1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 Written by Vladimir Makarov <vmakarov@redhat.com>
6 This file is part of GNU CC.
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
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
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
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.
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.
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
38 The current implementation is different from the 2nd article in the
41 1. New operator `|' (alternative) is permitted in functional unit
42 reservation which can be treated deterministicly and
45 2. Possibility of usage of nondeterministic automata too.
47 3. Possibility to query functional unit reservations for given
50 4. Several constructions to describe impossible reservations
51 (`exclusion_set', `presence_set', and `absence_set').
53 5. No reverse automata are generated. Trace instruction scheduling
54 requires this. It can be easily added in the future if we
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.
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
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
76 The translator major function `expand_automata' processes the
77 description internal representation into finite state automaton.
80 o checking correctness of the automaton pipeline description
81 (major function is `check_all_description').
83 o generating automaton (automata) from the description (major
84 function is `make_automaton').
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).
91 o optional minimization of the finite state automata by merging
92 equivalent automaton states (major function is `minimize_DFA').
94 o forming tables (some as comb vectors) and attributes
95 representing the automata (functions output_..._table).
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
122 #include "genattrtab.h"
124 #define obstack_chunk_alloc xmalloc
125 #define obstack_chunk_free free
127 /* Positions in machine description file. Now they are not used. But
128 they could be used in the future for better diagnostic messages. */
131 /* The following is element of vector of current (and planned in the
132 future) functional unit reservations. */
133 typedef unsigned HOST_WIDE_INT set_el_t;
135 /* Reservations of function units are represented by value of the following
137 typedef set_el_t *reserv_sets_t;
139 /* The following structure represents variable length array (vla) of
140 pointers and HOST WIDE INTs. We could be use only varray. But we
141 add new lay because we add elements very frequently and this could
142 stress OS allocator when varray is used only. */
144 size_t length; /* current size of vla. */
145 varray_type varray; /* container for vla. */
148 typedef vla_ptr_t vla_hwint_t;
150 /* The following structure describes a ticker. */
153 /* The following member value is time of the ticker creation with
154 taking into account time when the ticker is off. Active time of
155 the ticker is current time minus the value. */
156 int modified_creation_time;
157 /* The following member value is time (incremented by one) when the
158 ticker was off. Zero value means that now the ticker is on. */
159 int incremented_off_time;
162 /* The ticker is represented by the following type. */
163 typedef struct ticker ticker_t;
165 /* The following type describes elements of output vectors. */
166 typedef HOST_WIDE_INT vect_el_t;
168 /* Forward declaration of structures of internal representation of
169 pipeline description based on NDFA. */
174 struct automaton_decl;
175 struct unit_rel_decl;
177 struct insn_reserv_decl;
180 struct result_regexp;
181 struct reserv_regexp;
182 struct nothing_regexp;
183 struct sequence_regexp;
184 struct repeat_regexp;
195 struct state_ainsn_table;
197 /* The following typedefs are for brevity. */
198 typedef struct unit_decl *unit_decl_t;
199 typedef struct decl *decl_t;
200 typedef struct regexp *regexp_t;
201 typedef struct unit_set_el *unit_set_el_t;
202 typedef struct alt_state *alt_state_t;
203 typedef struct state *state_t;
204 typedef struct arc *arc_t;
205 typedef struct ainsn *ainsn_t;
206 typedef struct automaton *automaton_t;
207 typedef struct automata_list_el *automata_list_el_t;
208 typedef struct state_ainsn_table *state_ainsn_table_t;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
213 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
214 initiate_automaton_gen, expand_automata, write_automata are
215 described on the file top because the functions are called from
218 static void *create_node PARAMS ((size_t));
219 static void *copy_node PARAMS ((void *, size_t));
220 static char *check_name PARAMS ((char *, pos_t));
221 static char *next_sep_el PARAMS ((char **, int, int));
222 static int n_sep_els PARAMS ((char *, int, int));
223 static char **get_str_vect PARAMS ((char *, int *, int, int));
224 static regexp_t gen_regexp_el PARAMS ((char *));
225 static regexp_t gen_regexp_repeat PARAMS ((char *));
226 static regexp_t gen_regexp_allof PARAMS ((char *));
227 static regexp_t gen_regexp_oneof PARAMS ((char *));
228 static regexp_t gen_regexp_sequence PARAMS ((char *));
229 static regexp_t gen_regexp PARAMS ((char *));
231 static unsigned string_hash PARAMS ((const char *));
232 static unsigned automaton_decl_hash PARAMS ((const void *));
233 static int automaton_decl_eq_p PARAMS ((const void *,
235 static decl_t insert_automaton_decl PARAMS ((decl_t));
236 static decl_t find_automaton_decl PARAMS ((char *));
237 static void initiate_automaton_decl_table PARAMS ((void));
238 static void finish_automaton_decl_table PARAMS ((void));
240 static unsigned insn_decl_hash PARAMS ((const void *));
241 static int insn_decl_eq_p PARAMS ((const void *,
243 static decl_t insert_insn_decl PARAMS ((decl_t));
244 static decl_t find_insn_decl PARAMS ((char *));
245 static void initiate_insn_decl_table PARAMS ((void));
246 static void finish_insn_decl_table PARAMS ((void));
248 static unsigned decl_hash PARAMS ((const void *));
249 static int decl_eq_p PARAMS ((const void *,
251 static decl_t insert_decl PARAMS ((decl_t));
252 static decl_t find_decl PARAMS ((char *));
253 static void initiate_decl_table PARAMS ((void));
254 static void finish_decl_table PARAMS ((void));
256 static unit_set_el_t process_excls PARAMS ((char **, int, pos_t));
257 static void add_excls PARAMS ((unit_set_el_t, unit_set_el_t,
259 static unit_set_el_t process_presence_absence
260 PARAMS ((char **, int, pos_t, int));
261 static void add_presence_absence PARAMS ((unit_set_el_t, unit_set_el_t,
263 static void process_decls PARAMS ((void));
264 static struct bypass_decl *find_bypass PARAMS ((struct bypass_decl *,
265 struct insn_reserv_decl *));
266 static void check_automaton_usage PARAMS ((void));
267 static regexp_t process_regexp PARAMS ((regexp_t));
268 static void process_regexp_decls PARAMS ((void));
269 static void check_usage PARAMS ((void));
270 static int loop_in_regexp PARAMS ((regexp_t, decl_t));
271 static void check_loops_in_regexps PARAMS ((void));
272 static int process_regexp_cycles PARAMS ((regexp_t, int));
273 static void evaluate_max_reserv_cycles PARAMS ((void));
274 static void check_all_description PARAMS ((void));
276 static ticker_t create_ticker PARAMS ((void));
277 static void ticker_off PARAMS ((ticker_t *));
278 static void ticker_on PARAMS ((ticker_t *));
279 static int active_time PARAMS ((ticker_t));
280 static void print_active_time PARAMS ((FILE *, ticker_t));
282 static void add_advance_cycle_insn_decl PARAMS ((void));
284 static alt_state_t get_free_alt_state PARAMS ((void));
285 static void free_alt_state PARAMS ((alt_state_t));
286 static void free_alt_states PARAMS ((alt_state_t));
287 static int alt_state_cmp PARAMS ((const void *alt_state_ptr_1,
288 const void *alt_state_ptr_2));
289 static alt_state_t uniq_sort_alt_states PARAMS ((alt_state_t));
290 static int alt_states_eq PARAMS ((alt_state_t, alt_state_t));
291 static void initiate_alt_states PARAMS ((void));
292 static void finish_alt_states PARAMS ((void));
294 static reserv_sets_t alloc_empty_reserv_sets PARAMS ((void));
295 static unsigned reserv_sets_hash_value PARAMS ((reserv_sets_t));
296 static int reserv_sets_cmp PARAMS ((reserv_sets_t, reserv_sets_t));
297 static int reserv_sets_eq PARAMS ((reserv_sets_t, reserv_sets_t));
298 static void set_unit_reserv PARAMS ((reserv_sets_t, int, int));
299 static int test_unit_reserv PARAMS ((reserv_sets_t, int, int));
300 static int it_is_empty_reserv_sets PARAMS ((reserv_sets_t))
302 static int reserv_sets_are_intersected PARAMS ((reserv_sets_t, reserv_sets_t));
303 static void reserv_sets_shift PARAMS ((reserv_sets_t, reserv_sets_t));
304 static void reserv_sets_or PARAMS ((reserv_sets_t, reserv_sets_t,
306 static void reserv_sets_and PARAMS ((reserv_sets_t, reserv_sets_t,
309 static void output_cycle_reservs PARAMS ((FILE *, reserv_sets_t,
311 static void output_reserv_sets PARAMS ((FILE *, reserv_sets_t));
312 static state_t get_free_state PARAMS ((int, automaton_t));
313 static void free_state PARAMS ((state_t));
314 static unsigned state_hash PARAMS ((const void *));
315 static int state_eq_p PARAMS ((const void *, const void *));
316 static state_t insert_state PARAMS ((state_t));
317 static void set_state_reserv PARAMS ((state_t, int, int));
318 static int intersected_state_reservs_p PARAMS ((state_t, state_t));
319 static state_t states_union PARAMS ((state_t, state_t));
320 static state_t state_shift PARAMS ((state_t));
321 static void initiate_states PARAMS ((void));
322 static void finish_states PARAMS ((void));
324 static void free_arc PARAMS ((arc_t));
325 static void remove_arc PARAMS ((state_t, arc_t));
326 static arc_t find_arc PARAMS ((state_t, state_t, ainsn_t));
327 static arc_t add_arc PARAMS ((state_t, state_t, ainsn_t, int));
328 static arc_t first_out_arc PARAMS ((state_t));
329 static arc_t next_out_arc PARAMS ((arc_t));
330 static void initiate_arcs PARAMS ((void));
331 static void finish_arcs PARAMS ((void));
333 static automata_list_el_t get_free_automata_list_el PARAMS ((void));
334 static void free_automata_list_el PARAMS ((automata_list_el_t));
335 static void free_automata_list PARAMS ((automata_list_el_t));
336 static unsigned automata_list_hash PARAMS ((const void *));
337 static int automata_list_eq_p PARAMS ((const void *, const void *));
338 static void initiate_automata_lists PARAMS ((void));
339 static void automata_list_start PARAMS ((void));
340 static void automata_list_add PARAMS ((automaton_t));
341 static automata_list_el_t automata_list_finish PARAMS ((void));
342 static void finish_automata_lists PARAMS ((void));
344 static void initiate_excl_sets PARAMS ((void));
345 static reserv_sets_t get_excl_set PARAMS ((reserv_sets_t));
347 static void initiate_presence_absence_sets PARAMS ((void));
348 static reserv_sets_t get_presence_absence_set PARAMS ((reserv_sets_t, int));
350 static regexp_t copy_insn_regexp PARAMS ((regexp_t));
351 static regexp_t transform_1 PARAMS ((regexp_t));
352 static regexp_t transform_2 PARAMS ((regexp_t));
353 static regexp_t transform_3 PARAMS ((regexp_t));
354 static regexp_t regexp_transform_func
355 PARAMS ((regexp_t, regexp_t (*) (regexp_t)));
356 static regexp_t transform_regexp PARAMS ((regexp_t));
357 static void transform_insn_regexps PARAMS ((void));
359 static void process_unit_to_form_the_same_automaton_unit_lists
360 PARAMS ((regexp_t, regexp_t, int));
361 static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t));
362 static void form_the_same_automaton_unit_lists PARAMS ((void));
363 static void check_unit_distributions_to_automata PARAMS ((void));
365 static int process_seq_for_forming_states PARAMS ((regexp_t, automaton_t,
367 static void finish_forming_alt_state PARAMS ((alt_state_t,
369 static void process_alts_for_forming_states PARAMS ((regexp_t,
371 static void create_alt_states PARAMS ((automaton_t));
373 static void form_ainsn_with_same_reservs PARAMS ((automaton_t));
375 static void make_automaton PARAMS ((automaton_t));
376 static void form_arcs_marked_by_insn PARAMS ((state_t));
377 static void create_composed_state PARAMS ((state_t, arc_t, vla_ptr_t *));
378 static void NDFA_to_DFA PARAMS ((automaton_t));
379 static void pass_state_graph PARAMS ((state_t, void (*) (state_t)));
380 static void pass_states PARAMS ((automaton_t,
381 void (*) (state_t)));
382 static void initiate_pass_states PARAMS ((void));
383 static void add_achieved_state PARAMS ((state_t));
384 static int set_out_arc_insns_equiv_num PARAMS ((state_t, int));
385 static void clear_arc_insns_equiv_num PARAMS ((state_t));
386 static void copy_equiv_class PARAMS ((vla_ptr_t *to,
387 const vla_ptr_t *from));
388 static int state_is_differed PARAMS ((state_t, int, int));
389 static state_t init_equiv_class PARAMS ((state_t *states, int));
390 static int partition_equiv_class PARAMS ((state_t *, int,
391 vla_ptr_t *, int *));
392 static void evaluate_equiv_classes PARAMS ((automaton_t, vla_ptr_t *));
393 static void merge_states PARAMS ((automaton_t, vla_ptr_t *));
394 static void set_new_cycle_flags PARAMS ((state_t));
395 static void minimize_DFA PARAMS ((automaton_t));
396 static void incr_states_and_arcs_nums PARAMS ((state_t));
397 static void count_states_and_arcs PARAMS ((automaton_t, int *, int *));
398 static void build_automaton PARAMS ((automaton_t));
400 static void set_order_state_num PARAMS ((state_t));
401 static void enumerate_states PARAMS ((automaton_t));
403 static ainsn_t insert_ainsn_into_equiv_class PARAMS ((ainsn_t, ainsn_t));
404 static void delete_ainsn_from_equiv_class PARAMS ((ainsn_t));
405 static void process_insn_equiv_class PARAMS ((ainsn_t, arc_t *));
406 static void process_state_for_insn_equiv_partition PARAMS ((state_t));
407 static void set_insn_equiv_classes PARAMS ((automaton_t));
409 static double estimate_one_automaton_bound PARAMS ((void));
410 static int compare_max_occ_cycle_nums PARAMS ((const void *,
412 static void units_to_automata_heuristic_distr PARAMS ((void));
413 static ainsn_t create_ainsns PARAMS ((void));
414 static void units_to_automata_distr PARAMS ((void));
415 static void create_automata PARAMS ((void));
417 static void form_regexp PARAMS ((regexp_t));
418 static const char *regexp_representation PARAMS ((regexp_t));
419 static void finish_regexp_representation PARAMS ((void));
421 static void output_range_type PARAMS ((FILE *, long int, long int));
422 static int longest_path_length PARAMS ((state_t));
423 static void process_state_longest_path_length PARAMS ((state_t));
424 static void output_dfa_max_issue_rate PARAMS ((void));
425 static void output_vect PARAMS ((vect_el_t *, int));
426 static void output_chip_member_name PARAMS ((FILE *, automaton_t));
427 static void output_temp_chip_member_name PARAMS ((FILE *, automaton_t));
428 static void output_translate_vect_name PARAMS ((FILE *, automaton_t));
429 static void output_trans_full_vect_name PARAMS ((FILE *, automaton_t));
430 static void output_trans_comb_vect_name PARAMS ((FILE *, automaton_t));
431 static void output_trans_check_vect_name PARAMS ((FILE *, automaton_t));
432 static void output_trans_base_vect_name PARAMS ((FILE *, automaton_t));
433 static void output_state_alts_full_vect_name PARAMS ((FILE *, automaton_t));
434 static void output_state_alts_comb_vect_name PARAMS ((FILE *, automaton_t));
435 static void output_state_alts_check_vect_name PARAMS ((FILE *, automaton_t));
436 static void output_state_alts_base_vect_name PARAMS ((FILE *, automaton_t));
437 static void output_min_issue_delay_vect_name PARAMS ((FILE *, automaton_t));
438 static void output_dead_lock_vect_name PARAMS ((FILE *, automaton_t));
439 static void output_reserved_units_table_name PARAMS ((FILE *, automaton_t));
440 static void output_state_member_type PARAMS ((FILE *, automaton_t));
441 static void output_chip_definitions PARAMS ((void));
442 static void output_translate_vect PARAMS ((automaton_t));
443 static int comb_vect_p PARAMS ((state_ainsn_table_t));
444 static state_ainsn_table_t create_state_ainsn_table PARAMS ((automaton_t));
445 static void output_state_ainsn_table
446 PARAMS ((state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
447 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
448 void (*) (FILE *, automaton_t)));
449 static void add_vect PARAMS ((state_ainsn_table_t,
450 int, vect_el_t *, int));
451 static int out_state_arcs_num PARAMS ((state_t));
452 static int compare_transition_els_num PARAMS ((const void *, const void *));
453 static void add_vect_el PARAMS ((vla_hwint_t *,
455 static void add_states_vect_el PARAMS ((state_t));
456 static void output_trans_table PARAMS ((automaton_t));
457 static void output_state_alts_table PARAMS ((automaton_t));
458 static int min_issue_delay_pass_states PARAMS ((state_t, ainsn_t));
459 static int min_issue_delay PARAMS ((state_t, ainsn_t));
460 static void initiate_min_issue_delay_pass_states PARAMS ((void));
461 static void output_min_issue_delay_table PARAMS ((automaton_t));
462 static void output_dead_lock_vect PARAMS ((automaton_t));
463 static void output_reserved_units_table PARAMS ((automaton_t));
464 static void output_tables PARAMS ((void));
465 static void output_max_insn_queue_index_def PARAMS ((void));
466 static void output_insn_code_cases PARAMS ((void (*) (automata_list_el_t)));
467 static void output_automata_list_min_issue_delay_code PARAMS ((automata_list_el_t));
468 static void output_internal_min_issue_delay_func PARAMS ((void));
469 static void output_automata_list_transition_code PARAMS ((automata_list_el_t));
470 static void output_internal_trans_func PARAMS ((void));
471 static void output_internal_insn_code_evaluation PARAMS ((const char *,
473 static void output_dfa_insn_code_func PARAMS ((void));
474 static void output_trans_func PARAMS ((void));
475 static void output_automata_list_state_alts_code PARAMS ((automata_list_el_t));
476 static void output_internal_state_alts_func PARAMS ((void));
477 static void output_state_alts_func PARAMS ((void));
478 static void output_min_issue_delay_func PARAMS ((void));
479 static void output_internal_dead_lock_func PARAMS ((void));
480 static void output_dead_lock_func PARAMS ((void));
481 static void output_internal_reset_func PARAMS ((void));
482 static void output_size_func PARAMS ((void));
483 static void output_reset_func PARAMS ((void));
484 static void output_min_insn_conflict_delay_func PARAMS ((void));
485 static void output_internal_insn_latency_func PARAMS ((void));
486 static void output_insn_latency_func PARAMS ((void));
487 static void output_print_reservation_func PARAMS ((void));
488 static int units_cmp PARAMS ((const void *,
490 static void output_get_cpu_unit_code_func PARAMS ((void));
491 static void output_cpu_unit_reservation_p PARAMS ((void));
492 static void output_dfa_start_func PARAMS ((void));
493 static void output_dfa_finish_func PARAMS ((void));
495 static void output_regexp PARAMS ((regexp_t ));
496 static void output_unit_set_el_list PARAMS ((unit_set_el_t));
497 static void output_description PARAMS ((void));
498 static void output_automaton_name PARAMS ((FILE *, automaton_t));
499 static void output_automaton_units PARAMS ((automaton_t));
500 static void add_state_reservs PARAMS ((state_t));
501 static void output_state_arcs PARAMS ((state_t));
502 static int state_reservs_cmp PARAMS ((const void *,
504 static void remove_state_duplicate_reservs PARAMS ((void));
505 static void output_state PARAMS ((state_t));
506 static void output_automaton_descriptions PARAMS ((void));
507 static void output_statistics PARAMS ((FILE *));
508 static void output_time_statistics PARAMS ((FILE *));
509 static void generate PARAMS ((void));
511 static void make_insn_alts_attr PARAMS ((void));
512 static void make_internal_dfa_insn_code_attr PARAMS ((void));
513 static void make_default_insn_latency_attr PARAMS ((void));
514 static void make_bypass_attr PARAMS ((void));
515 static const char *file_name_suffix PARAMS ((const char *));
516 static const char *base_file_name PARAMS ((const char *));
517 static void check_automata_insn_issues PARAMS ((void));
518 static void add_automaton_state PARAMS ((state_t));
519 static void form_important_insn_automata_lists PARAMS ((void));
521 /* Undefined position. */
522 static pos_t no_pos = 0;
524 /* All IR is stored in the following obstack. */
525 static struct obstack irp;
529 /* This page contains code for work with variable length array (vla)
530 of pointers. We could be use only varray. But we add new lay
531 because we add elements very frequently and this could stress OS
532 allocator when varray is used only. */
534 /* Start work with vla. */
535 #define VLA_PTR_CREATE(vla, allocated_length, name) \
538 vla_ptr_t *vla_ptr = &(vla); \
540 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
541 vla_ptr->length = 0; \
545 /* Finish work with the vla. */
546 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
548 /* Return start address of the vla. */
549 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
551 /* Address of the last element of the vla. Do not use side effects in
552 the macro argument. */
553 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
555 /* Nullify the vla. */
556 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
558 /* Shorten the vla on given number bytes. */
559 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
561 /* Expand the vla on N elements. The values of new elements are
563 #define VLA_PTR_EXPAND(vla, n) \
565 vla_ptr_t *expand_vla_ptr = &(vla); \
566 size_t new_length = (n) + expand_vla_ptr->length; \
568 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
569 VARRAY_GROW (expand_vla_ptr->varray, \
570 (new_length - expand_vla_ptr->length < 128 \
571 ? expand_vla_ptr->length + 128 : new_length)); \
572 expand_vla_ptr->length = new_length; \
575 /* Add element to the end of the vla. */
576 #define VLA_PTR_ADD(vla, ptr) \
578 vla_ptr_t *vla_ptr = &(vla); \
580 VLA_PTR_EXPAND (*vla_ptr, 1); \
581 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
584 /* Length of the vla in elements. */
585 #define VLA_PTR_LENGTH(vla) ((vla).length)
587 /* N-th element of the vla. */
588 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
591 /* The following macros are analogous to the previous ones but for
592 VLAs of HOST WIDE INTs. */
594 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
596 vla_hwint_t *vla_ptr = &(vla); \
598 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
599 vla_ptr->length = 0; \
602 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
604 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
606 /* Do not use side effects in the macro argument. */
607 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
610 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
612 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
614 #define VLA_HWINT_EXPAND(vla, n) \
616 vla_hwint_t *expand_vla_ptr = &(vla); \
617 size_t new_length = (n) + expand_vla_ptr->length; \
619 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
620 VARRAY_GROW (expand_vla_ptr->varray, \
621 (new_length - expand_vla_ptr->length < 128 \
622 ? expand_vla_ptr->length + 128 : new_length)); \
623 expand_vla_ptr->length = new_length; \
626 #define VLA_HWINT_ADD(vla, ptr) \
628 vla_hwint_t *vla_ptr = &(vla); \
630 VLA_HWINT_EXPAND (*vla_ptr, 1); \
631 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
634 #define VLA_HWINT_LENGTH(vla) ((vla).length)
636 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
640 /* Options with the following names can be set up in automata_option
641 construction. Because the strings occur more one time we use the
644 #define NO_MINIMIZATION_OPTION "-no-minimization"
646 #define W_OPTION "-w"
648 #define NDFA_OPTION "-ndfa"
650 /* The following flags are set up by function `initiate_automaton_gen'. */
652 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
653 static int ndfa_flag;
655 /* Do not make minimization of DFA (`-no-minimization'). */
656 static int no_minimization_flag;
658 /* Value of this variable is number of automata being generated. The
659 actual number of automata may be less this value if there is not
660 sufficient number of units. This value is defined by argument of
661 option `-split' or by constructions automaton if the value is zero
662 (it is default value of the argument). */
663 static int split_argument;
665 /* Flag of output time statistics (`-time'). */
666 static int time_flag;
668 /* Flag of creation of description file which contains description of
669 result automaton and statistics information (`-v'). */
672 /* Flag of generating warning instead of error for non-critical errors
677 /* Output file for pipeline hazard recognizer (PHR) being generated.
678 The value is NULL if the file is not defined. */
679 static FILE *output_file;
681 /* Description file of PHR. The value is NULL if the file is not
683 static FILE *output_description_file;
685 /* PHR description file name. */
686 static char *output_description_file_name;
688 /* Value of the following variable is node representing description
689 being processed. This is start point of IR. */
690 static struct description *description;
694 /* This page contains description of IR structure (nodes). */
708 /* This describes define_cpu_unit and define_query_cpu_unit (see file
713 /* NULL if the automaton name is absent. */
714 char *automaton_name;
715 /* If the following value is not zero, the cpu unit reservation is
716 described in define_query_cpu_unit. */
719 /* The following fields are defined by checker. */
721 /* The following field value is nonzero if the unit is used in an
725 /* The following field value is used to form cyclic lists of units
726 which should be in the same automaton because the unit is
727 reserved not on all alternatives of a regexp on a cycle. */
728 unit_decl_t the_same_automaton_unit;
729 /* The following field is TRUE if we already reported that the unit
730 is not in the same automaton. */
731 int the_same_automaton_message_reported_p;
733 /* The following field value is order number (0, 1, ...) of given
736 /* The following field value is corresponding declaration of
737 automaton which was given in description. If the field value is
738 NULL then automaton in the unit declaration was absent. */
739 struct automaton_decl *automaton_decl;
740 /* The following field value is maximal cycle number (1, ...) on
741 which given unit occurs in insns. Zero value means that given
742 unit is not used in insns. */
743 int max_occ_cycle_num;
744 /* The following list contains units which conflict with given
746 unit_set_el_t excl_list;
747 /* The following list contains units which are required to
748 reservation of given unit. */
749 unit_set_el_t presence_list;
750 /* The following list contains units which should be not present in
751 reservation for given unit. */
752 unit_set_el_t absence_list;
753 /* The following is used only when `query_p' has nonzero value.
754 This is query number for the unit. */
757 /* The following fields are defined by automaton generator. */
759 /* The following field value is number of the automaton to which
760 given unit belongs. */
761 int corresponding_automaton_num;
764 /* This describes define_bypass (see file rtl.def). */
770 char *bypass_guard_name;
772 /* The following fields are defined by checker. */
774 /* output and input insns of given bypass. */
775 struct insn_reserv_decl *out_insn_reserv;
776 struct insn_reserv_decl *in_insn_reserv;
777 /* The next bypass for given output insn. */
778 struct bypass_decl *next;
781 /* This describes define_automaton (see file rtl.def). */
782 struct automaton_decl
786 /* The following fields are defined by automaton generator. */
788 /* The following field value is nonzero if the automaton is used in
789 an regexp definition. */
790 char automaton_is_used;
792 /* The following fields are defined by checker. */
794 /* The following field value is the corresponding automaton. This
795 field is not NULL only if the automaton is present in unit
796 declarations and the automatic partition on automata is not
798 automaton_t corresponding_automaton;
801 /* This describes unit relations: exclusion_set, presence_set, or
802 absence_set (see file rtl.def). */
806 int first_list_length;
810 /* This describes define_reservation (see file rtl.def). */
816 /* The following fields are defined by checker. */
818 /* The following field value is nonzero if the unit is used in an
821 /* The following field is used to check up cycle in expression
826 /* This describes define_insn_reservartion (see file rtl.def). */
827 struct insn_reserv_decl
834 /* The following fields are defined by checker. */
836 /* The following field value is order number (0, 1, ...) of given
839 /* The following field value is list of bypasses in which given insn
841 struct bypass_decl *bypass_list;
843 /* The following fields are defined by automaton generator. */
845 /* The following field is the insn regexp transformed that
846 the regexp has not optional regexp, repetition regexp, and an
847 reservation name (i.e. reservation identifiers are changed by the
848 corresponding regexp) and all alternations are the topest level
849 of the regexp. The value can be NULL only if it is special
850 insn `cycle advancing'. */
851 regexp_t transformed_regexp;
852 /* The following field value is list of arcs marked given
853 insn. The field is used in transfromation NDFA -> DFA. */
854 arc_t arcs_marked_by_insn;
855 /* The two following fields are used during minimization of a finite state
857 /* The field value is number of equivalence class of state into
858 which arc marked by given insn enters from a state (fixed during
859 an automaton minimization). */
861 /* The field value is state_alts of arc leaving a state (fixed
862 during an automaton minimization) and marked by given insn
865 /* The following member value is the list to automata which can be
866 changed by the insn issue. */
867 automata_list_el_t important_automata_list;
868 /* The following member is used to process insn once for output. */
872 /* This contains a declaration mentioned above. */
875 /* What node in the union? */
880 struct unit_decl unit;
881 struct bypass_decl bypass;
882 struct automaton_decl automaton;
883 struct unit_rel_decl excl;
884 struct unit_rel_decl presence;
885 struct unit_rel_decl absence;
886 struct reserv_decl reserv;
887 struct insn_reserv_decl insn_reserv;
891 /* The following structures represent parsed reservation strings. */
903 /* Cpu unit in reservation. */
907 unit_decl_t unit_decl;
910 /* Define_reservation in a reservation. */
914 struct reserv_decl *reserv_decl;
917 /* Absence of reservation (represented by string `nothing'). */
918 struct nothing_regexp
920 /* This used to be empty but ISO C doesn't allow that. */
924 /* Representation of reservations separated by ',' (see file
926 struct sequence_regexp
929 regexp_t regexps [1];
932 /* Representation of construction `repeat' (see file rtl.def). */
939 /* Representation of reservations separated by '+' (see file
944 regexp_t regexps [1];
947 /* Representation of reservations separated by '|' (see file
952 regexp_t regexps [1];
955 /* Representation of a reservation string. */
958 /* What node in the union? */
959 enum regexp_mode mode;
963 struct unit_regexp unit;
964 struct reserv_regexp reserv;
965 struct nothing_regexp nothing;
966 struct sequence_regexp sequence;
967 struct repeat_regexp repeat;
968 struct allof_regexp allof;
969 struct oneof_regexp oneof;
973 /* Reperesents description of pipeline hazard description based on
979 /* The following fields are defined by checker. */
981 /* The following fields values are correspondingly number of all
982 units, query units, and insns in the description. */
986 /* The following field value is max length (in cycles) of
987 reservations of insns. The field value is defined only for
989 int max_insn_reserv_cycles;
991 /* The following fields are defined by automaton generator. */
993 /* The following field value is the first automaton. */
994 automaton_t first_automaton;
996 /* The following field is created by pipeline hazard parser and
997 contains all declarations. We allocate additional entry for
998 special insn "cycle advancing" which is added by the automaton
1005 /* The following nodes are created in automaton checker. */
1007 /* The following nodes represent exclusion, presence, absence set for
1008 cpu units. Each element are accessed through only one excl_list,
1009 presence_list, absence_list. */
1012 unit_decl_t unit_decl;
1013 unit_set_el_t next_unit_set_el;
1018 /* The following nodes are created in automaton generator. */
1020 /* The following node type describes state automaton. The state may
1021 be deterministic or non-deterministic. Non-deterministic state has
1022 several component states which represent alternative cpu units
1023 reservations. The state also is used for describing a
1024 deterministic reservation of automaton insn. */
1027 /* The following member value is nonzero if there is a transition by
1030 /* The following field is list of processor unit reservations on
1032 reserv_sets_t reservs;
1033 /* The following field is unique number of given state between other
1036 /* The following field value is automaton to which given state
1038 automaton_t automaton;
1039 /* The following field value is the first arc output from given
1041 arc_t first_out_arc;
1042 /* The following field is used to form NDFA. */
1043 char it_was_placed_in_stack_for_NDFA_forming;
1044 /* The following field is used to form DFA. */
1045 char it_was_placed_in_stack_for_DFA_forming;
1046 /* The following field is used to transform NDFA to DFA. The field
1047 value is not NULL if the state is a compound state. In this case
1048 the value of field `unit_sets_list' is NULL. All states in the
1049 list are in the hash table. The list is formed through field
1050 `next_sorted_alt_state'. */
1051 alt_state_t component_states;
1052 /* The following field is used for passing graph of states. */
1054 /* The list of states belonging to one equivalence class is formed
1055 with the aid of the following field. */
1056 state_t next_equiv_class_state;
1057 /* The two following fields are used during minimization of a finite
1059 int equiv_class_num_1, equiv_class_num_2;
1060 /* The following field is used during minimization of a finite state
1061 automaton. The field value is state corresponding to equivalence
1062 class to which given state belongs. */
1063 state_t equiv_class_state;
1064 /* The following field value is the order number of given state.
1065 The states in final DFA is enumerated with the aid of the
1067 int order_state_num;
1068 /* This member is used for passing states for searching minimal
1071 /* The following member is used to evaluate min issue delay of insn
1073 int min_insn_issue_delay;
1074 /* The following member is used to evaluate max issue rate of the
1075 processor. The value of the member is maximal length of the path
1076 from given state no containing arcs marked by special insn `cycle
1078 int longest_path_length;
1081 /* The following macro is an initial value of member
1082 `longest_path_length' of a state. */
1083 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1085 /* Automaton arc. */
1088 /* The following field refers for the state into which given arc
1091 /* The following field describes that the insn issue (with cycle
1092 advancing for special insn `cycle advancing' and without cycle
1093 advancing for others) makes transition from given state to
1094 another given state. */
1096 /* The following field value is the next arc output from the same
1099 /* List of arcs marked given insn is formed with the following
1100 field. The field is used in transfromation NDFA -> DFA. */
1101 arc_t next_arc_marked_by_insn;
1102 /* The following field is defined if NDFA_FLAG is zero. The member
1103 value is number of alternative reservations which can be used for
1104 transition for given state by given insn. */
1108 /* The following node type describes a deterministic alternative in
1109 non-deterministic state which characterizes cpu unit reservations
1110 of automaton insn or which is part of NDFA. */
1113 /* The following field is a determinist state which characterizes
1114 unit reservations of the instruction. */
1116 /* The following field refers to the next state which characterizes
1117 unit reservations of the instruction. */
1118 alt_state_t next_alt_state;
1119 /* The following field refers to the next state in sorted list. */
1120 alt_state_t next_sorted_alt_state;
1123 /* The following node type describes insn of automaton. They are
1124 labels of FA arcs. */
1127 /* The following field value is the corresponding insn declaration
1129 struct insn_reserv_decl *insn_reserv_decl;
1130 /* The following field value is the next insn declaration for an
1133 /* The following field is states which characterize automaton unit
1134 reservations of the instruction. The value can be NULL only if it
1135 is special insn `cycle advancing'. */
1136 alt_state_t alt_states;
1137 /* The following field is sorted list of states which characterize
1138 automaton unit reservations of the instruction. The value can be
1139 NULL only if it is special insn `cycle advancing'. */
1140 alt_state_t sorted_alt_states;
1141 /* The following field refers the next automaton insn with
1142 the same reservations. */
1143 ainsn_t next_same_reservs_insn;
1144 /* The following field is flag of the first automaton insn with the
1145 same reservations in the declaration list. Only arcs marked such
1146 insn is present in the automaton. This significantly decreases
1147 memory requirements especially when several automata are
1149 char first_insn_with_same_reservs;
1150 /* The following member has nonzero value if there is arc from state of
1151 the automaton marked by the ainsn. */
1153 /* Cyclic list of insns of an equivalence class is formed with the
1154 aid of the following field. */
1155 ainsn_t next_equiv_class_insn;
1156 /* The following field value is nonzero if the insn declaration is
1157 the first insn declaration with given equivalence number. */
1158 char first_ainsn_with_given_equialence_num;
1159 /* The following field is number of class of equivalence of insns.
1160 It is necessary because many insns may be equivalent with the
1161 point of view of pipeline hazards. */
1162 int insn_equiv_class_num;
1163 /* The following member value is TRUE if there is an arc in the
1164 automaton marked by the insn into another state. In other
1165 words, the insn can change the state of the automaton. */
1169 /* The folowing describes an automaton for PHR. */
1172 /* The following field value is the list of insn declarations for
1175 /* The following field value is the corresponding automaton
1176 declaration. This field is not NULL only if the automatic
1177 partition on automata is not used. */
1178 struct automaton_decl *corresponding_automaton_decl;
1179 /* The following field value is the next automaton. */
1180 automaton_t next_automaton;
1181 /* The following field is start state of FA. There are not unit
1182 reservations in the state. */
1183 state_t start_state;
1184 /* The following field value is number of equivalence classes of
1185 insns (see field `insn_equiv_class_num' in
1186 `insn_reserv_decl'). */
1187 int insn_equiv_classes_num;
1188 /* The following field value is number of states of final DFA. */
1189 int achieved_states_num;
1190 /* The following field value is the order number (0, 1, ...) of
1192 int automaton_order_num;
1193 /* The following fields contain statistics information about
1194 building automaton. */
1195 int NDFA_states_num, DFA_states_num;
1196 /* The following field value is defined only if minimization of DFA
1198 int minimal_DFA_states_num;
1199 int NDFA_arcs_num, DFA_arcs_num;
1200 /* The following field value is defined only if minimization of DFA
1202 int minimal_DFA_arcs_num;
1203 /* The following two members refer for two table state x ainsn ->
1205 state_ainsn_table_t trans_table;
1206 state_ainsn_table_t state_alts_table;
1207 /* The following member value is maximal value of min issue delay
1208 for insns of the automaton. */
1210 /* Usually min issue delay is small and we can place several (2, 4,
1211 8) elements in one vector element. So the compression factor can
1212 be 1 (no compression), 2, 4, 8. */
1213 int min_issue_delay_table_compression_factor;
1216 /* The following is the element of the list of automata. */
1217 struct automata_list_el
1219 /* The automaton itself. */
1220 automaton_t automaton;
1221 /* The next automata set element. */
1222 automata_list_el_t next_automata_list_el;
1225 /* The following structure describes a table state X ainsn -> int(>= 0). */
1226 struct state_ainsn_table
1228 /* Automaton to which given table belongs. */
1229 automaton_t automaton;
1230 /* The following tree vectors for comb vector implementation of the
1232 vla_hwint_t comb_vect;
1233 vla_hwint_t check_vect;
1234 vla_hwint_t base_vect;
1235 /* This is simple implementation of the table. */
1236 vla_hwint_t full_vect;
1237 /* Minimal and maximal values of the previous vectors. */
1238 int min_comb_vect_el_value, max_comb_vect_el_value;
1239 int min_base_vect_el_value, max_base_vect_el_value;
1242 /* Create IR structure (node). */
1249 obstack_blank (&irp, size);
1250 result = obstack_base (&irp);
1251 obstack_finish (&irp);
1252 /* Default values of members are NULL and zero. */
1253 memset (result, 0, size);
1257 /* Copy IR structure (node). */
1259 copy_node (from, size)
1264 result = create_node (size);
1265 memcpy (result, from, size);
1269 /* The function checks that NAME does not contain quotes (`"'). */
1271 check_name (name, pos)
1273 pos_t pos ATTRIBUTE_UNUSED;
1277 for (str = name; *str != '\0'; str++)
1279 error ("Name `%s' contains quotes", name);
1283 /* Pointers top all declartions during IR generation are stored in the
1285 static vla_ptr_t decls;
1287 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1288 string containing the next separated element, taking parentheses
1289 into account if PAR_FLAG has nonzero value. Advance the pointer to
1290 after the string scanned, or the end-of-string. Return NULL if at
1293 next_sep_el (pstr, sep, par_flag)
1303 /* Remove leading whitespaces. */
1304 while (isspace ((int) **pstr))
1311 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1313 if (par_flag && *p == '(')
1315 else if (par_flag && *p == ')')
1317 else if (pars_num == 0 && *p == sep)
1319 if (pars_num == 0 && isspace ((int) *p))
1323 for (; n_spaces != 0; n_spaces--)
1324 obstack_1grow (&irp, p [-n_spaces]);
1325 obstack_1grow (&irp, *p);
1328 obstack_1grow (&irp, '\0');
1329 out_str = obstack_base (&irp);
1330 obstack_finish (&irp);
1339 /* Given a string and a separator, return the number of separated
1340 elements in it, taking parentheses into account if PAR_FLAG has
1341 nonzero value. Return 0 for the null string, -1 if parantheses is
1344 n_sep_els (s, sep, par_flag)
1355 for (pars_num = 0, n = 1; *s; s++)
1356 if (par_flag && *s == '(')
1358 else if (par_flag && *s == ')')
1360 else if (pars_num == 0 && *s == sep)
1363 return (pars_num != 0 ? -1 : n);
1366 /* Given a string and a separator, return vector of strings which are
1367 elements in the string and number of elements through els_num.
1368 Take parentheses into account if PAR_FLAG has nonzero value.
1369 Return 0 for the null string, -1 if parantheses are not balanced. */
1371 get_str_vect (str, els_num, sep, par_flag)
1381 *els_num = n_sep_els (str, sep, par_flag);
1384 obstack_blank (&irp, sizeof (char *) * (*els_num));
1385 vect = (char **) obstack_base (&irp);
1386 obstack_finish (&irp);
1388 for (i = 0; i < *els_num; i++)
1389 vect [i] = next_sep_el (pstr, sep, par_flag);
1390 if (next_sep_el (pstr, sep, par_flag) != NULL)
1395 /* Process a DEFINE_CPU_UNIT.
1397 This gives information about a unit contained in CPU. We fill a
1398 struct unit_decl with information used later by `expand_automata'. */
1404 char **str_cpu_units;
1408 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1409 if (str_cpu_units == NULL)
1410 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1411 for (i = 0; i < vect_length; i++)
1413 decl = create_node (sizeof (struct decl));
1414 decl->mode = dm_unit;
1416 decl->decl.unit.name = check_name (str_cpu_units [i], decl->pos);
1417 decl->decl.unit.automaton_name = (char *) XSTR (def, 1);
1418 decl->decl.unit.query_p = 0;
1419 VLA_PTR_ADD (decls, decl);
1424 /* Process a DEFINE_QUERY_CPU_UNIT.
1426 This gives information about a unit contained in CPU. We fill a
1427 struct unit_decl with information used later by `expand_automata'. */
1429 gen_query_cpu_unit (def)
1433 char **str_cpu_units;
1437 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1438 if (str_cpu_units == NULL)
1439 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1440 for (i = 0; i < vect_length; i++)
1442 decl = create_node (sizeof (struct decl));
1443 decl->mode = dm_unit;
1445 decl->decl.unit.name = check_name (str_cpu_units [i], decl->pos);
1446 decl->decl.unit.automaton_name = (char *) XSTR (def, 1);
1447 decl->decl.unit.query_p = 1;
1448 VLA_PTR_ADD (decls, decl);
1453 /* Process a DEFINE_BYPASS.
1455 This gives information about a unit contained in the CPU. We fill
1456 in a struct bypass_decl with information used later by
1457 `expand_automata'. */
1469 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', 0);
1470 if (out_insns == NULL)
1471 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1472 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', 0);
1473 if (in_insns == NULL)
1474 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1475 for (i = 0; i < out_length; i++)
1476 for (j = 0; j < in_length; j++)
1478 decl = create_node (sizeof (struct decl));
1479 decl->mode = dm_bypass;
1481 decl->decl.bypass.latency = XINT (def, 0);
1482 decl->decl.bypass.out_insn_name = out_insns [i];
1483 decl->decl.bypass.in_insn_name = in_insns [j];
1484 decl->decl.bypass.bypass_guard_name = (char *) XSTR (def, 3);
1485 VLA_PTR_ADD (decls, decl);
1490 /* Process an EXCLUSION_SET.
1492 This gives information about a cpu unit conflicts. We fill a
1493 struct unit_rel_decl (excl) with information used later by
1494 `expand_automata'. */
1500 char **first_str_cpu_units;
1501 char **second_str_cpu_units;
1502 int first_vect_length;
1507 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1508 if (first_str_cpu_units == NULL)
1509 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1510 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1512 if (second_str_cpu_units == NULL)
1513 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1514 length += first_vect_length;
1515 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1516 decl->mode = dm_excl;
1518 decl->decl.excl.names_num = length;
1519 decl->decl.excl.first_list_length = first_vect_length;
1520 for (i = 0; i < length; i++)
1521 if (i < first_vect_length)
1522 decl->decl.excl.names [i] = first_str_cpu_units [i];
1524 decl->decl.excl.names [i] = second_str_cpu_units [i - first_vect_length];
1525 VLA_PTR_ADD (decls, decl);
1529 /* Process a PRESENCE_SET.
1531 This gives information about a cpu unit reservation requirements.
1532 We fill a struct unit_rel_decl (presence) with information used
1533 later by `expand_automata'. */
1535 gen_presence_set (def)
1539 char **first_str_cpu_units;
1540 char **second_str_cpu_units;
1541 int first_vect_length;
1546 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1547 if (first_str_cpu_units == NULL)
1548 fatal ("invalid first string `%s' in presence_set", XSTR (def, 0));
1549 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1551 if (second_str_cpu_units == NULL)
1552 fatal ("invalid second string `%s' in presence_set", XSTR (def, 1));
1553 length += first_vect_length;
1554 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1555 decl->mode = dm_presence;
1557 decl->decl.presence.names_num = length;
1558 decl->decl.presence.first_list_length = first_vect_length;
1559 for (i = 0; i < length; i++)
1560 if (i < first_vect_length)
1561 decl->decl.presence.names [i] = first_str_cpu_units [i];
1563 decl->decl.presence.names [i]
1564 = second_str_cpu_units [i - first_vect_length];
1565 VLA_PTR_ADD (decls, decl);
1569 /* Process an ABSENCE_SET.
1571 This gives information about a cpu unit reservation requirements.
1572 We fill a struct unit_rel_decl (absence) with information used
1573 later by `expand_automata'. */
1575 gen_absence_set (def)
1579 char **first_str_cpu_units;
1580 char **second_str_cpu_units;
1581 int first_vect_length;
1586 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1587 if (first_str_cpu_units == NULL)
1588 fatal ("invalid first string `%s' in absence_set", XSTR (def, 0));
1589 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1591 if (second_str_cpu_units == NULL)
1592 fatal ("invalid second string `%s' in absence_set", XSTR (def, 1));
1593 length += first_vect_length;
1594 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1595 decl->mode = dm_absence;
1597 decl->decl.absence.names_num = length;
1598 decl->decl.absence.first_list_length = first_vect_length;
1599 for (i = 0; i < length; i++)
1600 if (i < first_vect_length)
1601 decl->decl.absence.names [i] = first_str_cpu_units [i];
1603 decl->decl.absence.names [i]
1604 = second_str_cpu_units [i - first_vect_length];
1605 VLA_PTR_ADD (decls, decl);
1609 /* Process a DEFINE_AUTOMATON.
1611 This gives information about a finite state automaton used for
1612 recognizing pipeline hazards. We fill a struct automaton_decl
1613 with information used later by `expand_automata'. */
1619 char **str_automata;
1623 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1624 if (str_automata == NULL)
1625 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1626 for (i = 0; i < vect_length; i++)
1628 decl = create_node (sizeof (struct decl));
1629 decl->mode = dm_automaton;
1631 decl->decl.automaton.name = check_name (str_automata [i], decl->pos);
1632 VLA_PTR_ADD (decls, decl);
1637 /* Process an AUTOMATA_OPTION.
1639 This gives information how to generate finite state automaton used
1640 for recognizing pipeline hazards. */
1642 gen_automata_option (def)
1645 if (strcmp ((char *) XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1646 no_minimization_flag = 1;
1647 else if (strcmp ((char *) XSTR (def, 0), W_OPTION + 1) == 0)
1649 else if (strcmp ((char *) XSTR (def, 0), NDFA_OPTION + 1) == 0)
1652 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1655 /* Name in reservation to denote absence reservation. */
1656 #define NOTHING_NAME "nothing"
1658 /* The following string contains original reservation string being
1660 static char *reserv_str;
1662 /* Parse an element in STR. */
1673 if (str [len - 1] != ')')
1674 fatal ("garbage after ) in reservation `%s'", reserv_str);
1675 str [len - 1] = '\0';
1676 regexp = gen_regexp_sequence (str + 1);
1678 else if (strcmp (str, NOTHING_NAME) == 0)
1680 regexp = create_node (sizeof (struct decl));
1681 regexp->mode = rm_nothing;
1685 regexp = create_node (sizeof (struct decl));
1686 regexp->mode = rm_unit;
1687 regexp->regexp.unit.name = str;
1692 /* Parse construction `repeat' in STR. */
1694 gen_regexp_repeat (str)
1703 repeat_vect = get_str_vect (str, &els_num, '*', 1);
1704 if (repeat_vect == NULL)
1705 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1708 regexp = gen_regexp_el (repeat_vect [0]);
1709 for (i = 1; i < els_num; i++)
1711 repeat = create_node (sizeof (struct regexp));
1712 repeat->mode = rm_repeat;
1713 repeat->regexp.repeat.regexp = regexp;
1714 repeat->regexp.repeat.repeat_num = atoi (repeat_vect [i]);
1715 if (repeat->regexp.repeat.repeat_num <= 1)
1716 fatal ("repetition `%s' <= 1 in reservation `%s'",
1723 return gen_regexp_el (str);
1726 /* Parse reservation STR which possibly contains separator '+'. */
1728 gen_regexp_allof (str)
1736 allof_vect = get_str_vect (str, &els_num, '+', 1);
1737 if (allof_vect == NULL)
1738 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1741 allof = create_node (sizeof (struct regexp)
1742 + sizeof (regexp_t) * (els_num - 1));
1743 allof->mode = rm_allof;
1744 allof->regexp.allof.regexps_num = els_num;
1745 for (i = 0; i < els_num; i++)
1746 allof->regexp.allof.regexps [i] = gen_regexp_repeat (allof_vect [i]);
1750 return gen_regexp_repeat (str);
1753 /* Parse reservation STR which possibly contains separator '|'. */
1755 gen_regexp_oneof (str)
1763 oneof_vect = get_str_vect (str, &els_num, '|', 1);
1764 if (oneof_vect == NULL)
1765 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1768 oneof = create_node (sizeof (struct regexp)
1769 + sizeof (regexp_t) * (els_num - 1));
1770 oneof->mode = rm_oneof;
1771 oneof->regexp.oneof.regexps_num = els_num;
1772 for (i = 0; i < els_num; i++)
1773 oneof->regexp.oneof.regexps [i] = gen_regexp_allof (oneof_vect [i]);
1777 return gen_regexp_allof (str);
1780 /* Parse reservation STR which possibly contains separator ','. */
1782 gen_regexp_sequence (str)
1786 char **sequence_vect;
1790 sequence_vect = get_str_vect (str, &els_num, ',', 1);
1793 sequence = create_node (sizeof (struct regexp)
1794 + sizeof (regexp_t) * (els_num - 1));
1795 sequence->mode = rm_sequence;
1796 sequence->regexp.sequence.regexps_num = els_num;
1797 for (i = 0; i < els_num; i++)
1798 sequence->regexp.sequence.regexps [i]
1799 = gen_regexp_oneof (sequence_vect [i]);
1803 return gen_regexp_oneof (str);
1806 /* Parse construction reservation STR. */
1812 return gen_regexp_sequence (str);;
1815 /* Process a DEFINE_RESERVATION.
1817 This gives information about a reservation of cpu units. We fill
1818 in a struct reserv_decl with information used later by
1819 `expand_automata'. */
1826 decl = create_node (sizeof (struct decl));
1827 decl->mode = dm_reserv;
1829 decl->decl.reserv.name = check_name ((char *) XSTR (def, 0), decl->pos);
1830 decl->decl.reserv.regexp = gen_regexp ((char *) XSTR (def, 1));
1831 VLA_PTR_ADD (decls, decl);
1835 /* Process a DEFINE_INSN_RESERVATION.
1837 This gives information about the reservation of cpu units by an
1838 insn. We fill a struct insn_reserv_decl with information used
1839 later by `expand_automata'. */
1841 gen_insn_reserv (def)
1846 decl = create_node (sizeof (struct decl));
1847 decl->mode = dm_insn_reserv;
1849 decl->decl.insn_reserv.name = check_name ((char *) XSTR (def, 0), decl->pos);
1850 decl->decl.insn_reserv.default_latency = XINT (def, 1);
1851 decl->decl.insn_reserv.condexp = XEXP (def, 2);
1852 decl->decl.insn_reserv.regexp = gen_regexp ((char *) XSTR (def, 3));
1853 VLA_PTR_ADD (decls, decl);
1859 /* The function evaluates hash value (0..UINT_MAX) of string. */
1861 string_hash (string)
1866 for (result = i = 0;*string++ != '\0'; i++)
1867 result += ((unsigned char) *string << (i % CHAR_BIT));
1873 /* This page contains abstract data `table of automaton declarations'.
1874 Elements of the table is nodes representing automaton declarations.
1875 Key of the table elements is name of given automaton. Rememeber
1876 that automaton names have own space. */
1878 /* The function evaluates hash value of an automaton declaration. The
1879 function is used by abstract data `hashtab'. The function returns
1880 hash value (0..UINT_MAX) of given automaton declaration. */
1882 automaton_decl_hash (automaton_decl)
1883 const void *automaton_decl;
1885 const decl_t decl = (decl_t) automaton_decl;
1887 if (decl->mode == dm_automaton && decl->decl.automaton.name == NULL)
1889 return string_hash (decl->decl.automaton.name);
1892 /* The function tests automaton declarations on equality of their
1893 keys. The function is used by abstract data `hashtab'. The
1894 function returns 1 if the declarations have the same key, 0
1897 automaton_decl_eq_p (automaton_decl_1, automaton_decl_2)
1898 const void* automaton_decl_1;
1899 const void* automaton_decl_2;
1901 const decl_t decl1 = (decl_t) automaton_decl_1;
1902 const decl_t decl2 = (decl_t) automaton_decl_2;
1904 if (decl1->mode != dm_automaton || decl1->decl.automaton.name == NULL
1905 || decl2->mode != dm_automaton || decl2->decl.automaton.name == NULL)
1907 return strcmp (decl1->decl.automaton.name, decl2->decl.automaton.name) == 0;
1910 /* The automaton declaration table itself is represented by the
1911 following variable. */
1912 static htab_t automaton_decl_table;
1914 /* The function inserts automaton declaration into the table. The
1915 function does nothing if an automaton declaration with the same key
1916 exists already in the table. The function returns automaton
1917 declaration node in the table with the same key as given automaton
1918 declaration node. */
1920 insert_automaton_decl (automaton_decl)
1921 decl_t automaton_decl;
1925 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
1926 if (*entry_ptr == NULL)
1927 *entry_ptr = (void *) automaton_decl;
1928 return (decl_t) *entry_ptr;
1931 /* The following variable value is node representing automaton
1932 declaration. The node used for searching automaton declaration
1934 static struct decl work_automaton_decl;
1936 /* The function searches for automaton declaration in the table with
1937 the same key as node representing name of the automaton
1938 declaration. The function returns node found in the table, NULL if
1939 such node does not exist in the table. */
1941 find_automaton_decl (name)
1946 work_automaton_decl.decl.automaton.name = name;
1947 entry = htab_find (automaton_decl_table, &work_automaton_decl);
1948 return (decl_t) entry;
1951 /* The function creates empty automaton declaration table and node
1952 representing automaton declaration and used for searching automaton
1953 declaration with given name. The function must be called only once
1954 before any work with the automaton declaration table. */
1956 initiate_automaton_decl_table ()
1958 work_automaton_decl.mode = dm_automaton;
1959 automaton_decl_table = htab_create (10, automaton_decl_hash,
1960 automaton_decl_eq_p, (htab_del) 0);
1963 /* The function deletes the automaton declaration table. Only call of
1964 function `initiate_automaton_decl_table' is possible immediately
1965 after this function call. */
1967 finish_automaton_decl_table ()
1969 htab_delete (automaton_decl_table);
1974 /* This page contains abstract data `table of insn declarations'.
1975 Elements of the table is nodes representing insn declarations. Key
1976 of the table elements is name of given insn (in corresponding
1977 define_insn_reservation). Rememeber that insn names have own
1980 /* The function evaluates hash value of an insn declaration. The
1981 function is used by abstract data `hashtab'. The function returns
1982 hash value (0..UINT_MAX) of given insn declaration. */
1984 insn_decl_hash (insn_decl)
1985 const void *insn_decl;
1987 const decl_t decl = (decl_t) insn_decl;
1989 if (decl->mode != dm_insn_reserv || decl->decl.insn_reserv.name == NULL)
1991 return string_hash (decl->decl.insn_reserv.name);
1994 /* The function tests insn declarations on equality of their keys.
1995 The function is used by abstract data `hashtab'. The function
1996 returns 1 if declarations have the same key, 0 otherwise. */
1998 insn_decl_eq_p (insn_decl_1, insn_decl_2)
1999 const void *insn_decl_1;
2000 const void *insn_decl_2;
2002 const decl_t decl1 = (decl_t) insn_decl_1;
2003 const decl_t decl2 = (decl_t) insn_decl_2;
2005 if (decl1->mode != dm_insn_reserv || decl1->decl.insn_reserv.name == NULL
2006 || decl2->mode != dm_insn_reserv || decl2->decl.insn_reserv.name == NULL)
2008 return strcmp (decl1->decl.insn_reserv.name,
2009 decl2->decl.insn_reserv.name) == 0;
2012 /* The insn declaration table itself is represented by the following
2013 variable. The table does not contain insn reservation
2015 static htab_t insn_decl_table;
2017 /* The function inserts insn declaration into the table. The function
2018 does nothing if an insn declaration with the same key exists
2019 already in the table. The function returns insn declaration node
2020 in the table with the same key as given insn declaration node. */
2022 insert_insn_decl (insn_decl)
2027 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2028 if (*entry_ptr == NULL)
2029 *entry_ptr = (void *) insn_decl;
2030 return (decl_t) *entry_ptr;
2033 /* The following variable value is node representing insn reservation
2034 declaration. The node used for searching insn reservation
2035 declaration with given name. */
2036 static struct decl work_insn_decl;
2038 /* The function searches for insn reservation declaration in the table
2039 with the same key as node representing name of the insn reservation
2040 declaration. The function returns node found in the table, NULL if
2041 such node does not exist in the table. */
2043 find_insn_decl (name)
2048 work_insn_decl.decl.insn_reserv.name = name;
2049 entry = htab_find (insn_decl_table, &work_insn_decl);
2050 return (decl_t) entry;
2053 /* The function creates empty insn declaration table and node
2054 representing insn declaration and used for searching insn
2055 declaration with given name. The function must be called only once
2056 before any work with the insn declaration table. */
2058 initiate_insn_decl_table ()
2060 work_insn_decl.mode = dm_insn_reserv;
2061 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2065 /* The function deletes the insn declaration table. Only call of
2066 function `initiate_insn_decl_table' is possible immediately after
2067 this function call. */
2069 finish_insn_decl_table ()
2071 htab_delete (insn_decl_table);
2076 /* This page contains abstract data `table of declarations'. Elements
2077 of the table is nodes representing declarations (of units and
2078 reservations). Key of the table elements is names of given
2081 /* The function evaluates hash value of a declaration. The function
2082 is used by abstract data `hashtab'. The function returns hash
2083 value (0..UINT_MAX) of given declaration. */
2088 const decl_t d = (const decl_t) decl;
2090 if ((d->mode != dm_unit || d->decl.unit.name == NULL)
2091 && (d->mode != dm_reserv || d->decl.reserv.name == NULL))
2093 return string_hash (d->mode == dm_unit
2094 ? d->decl.unit.name : d->decl.reserv.name);
2097 /* The function tests declarations on equality of their keys. The
2098 function is used by abstract data `hashtab'. The function
2099 returns 1 if the declarations have the same key, 0 otherwise. */
2101 decl_eq_p (decl_1, decl_2)
2105 const decl_t d1 = (const decl_t) decl_1;
2106 const decl_t d2 = (const decl_t) decl_2;
2108 if (((d1->mode != dm_unit || d1->decl.unit.name == NULL)
2109 && (d1->mode != dm_reserv || d1->decl.reserv.name == NULL))
2110 || ((d2->mode != dm_unit || d2->decl.unit.name == NULL)
2111 && (d2->mode != dm_reserv || d2->decl.reserv.name == NULL)))
2113 return strcmp ((d1->mode == dm_unit
2114 ? d1->decl.unit.name : d1->decl.reserv.name),
2115 (d2->mode == dm_unit
2116 ? d2->decl.unit.name : d2->decl.reserv.name)) == 0;
2119 /* The declaration table itself is represented by the following
2121 static htab_t decl_table;
2123 /* The function inserts declaration into the table. The function does
2124 nothing if a declaration with the same key exists already in the
2125 table. The function returns declaration node in the table with the
2126 same key as given declaration node. */
2134 entry_ptr = htab_find_slot (decl_table, decl, 1);
2135 if (*entry_ptr == NULL)
2136 *entry_ptr = (void *) decl;
2137 return (decl_t) *entry_ptr;
2140 /* The following variable value is node representing declaration. The
2141 node used for searching declaration with given name. */
2142 static struct decl work_decl;
2144 /* The function searches for declaration in the table with the same
2145 key as node representing name of the declaration. The function
2146 returns node found in the table, NULL if such node does not exist
2154 work_decl.decl.unit.name = name;
2155 entry = htab_find (decl_table, &work_decl);
2156 return (decl_t) entry;
2159 /* The function creates empty declaration table and node representing
2160 declaration and used for searching declaration with given name.
2161 The function must be called only once before any work with the
2162 declaration table. */
2164 initiate_decl_table ()
2166 work_decl.mode = dm_unit;
2167 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2170 /* The function deletes the declaration table. Only call of function
2171 `initiate_declaration_table' is possible immediately after this
2174 finish_decl_table ()
2176 htab_delete (decl_table);
2181 /* This page contains checker of pipeline hazard description. */
2183 /* Checking NAMES in an exclusion clause vector and returning formed
2184 unit_set_el_list. */
2185 static unit_set_el_t
2186 process_excls (names, num, excl_pos)
2189 pos_t excl_pos ATTRIBUTE_UNUSED;
2191 unit_set_el_t el_list;
2192 unit_set_el_t last_el;
2193 unit_set_el_t new_el;
2194 decl_t decl_in_table;
2199 for (i = 0; i < num; i++)
2201 decl_in_table = find_decl (names [i]);
2202 if (decl_in_table == NULL)
2203 error ("unit `%s' in exclusion is not declared", names [i]);
2204 else if (decl_in_table->mode != dm_unit)
2205 error ("`%s' in exclusion is not unit", names [i]);
2208 new_el = create_node (sizeof (struct unit_set_el));
2209 new_el->unit_decl = &decl_in_table->decl.unit;
2210 new_el->next_unit_set_el = NULL;
2211 if (last_el == NULL)
2212 el_list = last_el = new_el;
2215 last_el->next_unit_set_el = new_el;
2216 last_el = last_el->next_unit_set_el;
2223 /* The function adds each element from SOURCE_LIST to the exclusion
2224 list of the each element from DEST_LIST. Checking situation "unit
2225 excludes itself". */
2227 add_excls (dest_list, source_list, excl_pos)
2228 unit_set_el_t dest_list;
2229 unit_set_el_t source_list;
2230 pos_t excl_pos ATTRIBUTE_UNUSED;
2234 unit_set_el_t curr_el;
2235 unit_set_el_t prev_el;
2238 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2239 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2241 if (dst->unit_decl == src->unit_decl)
2243 error ("unit `%s' excludes itself", src->unit_decl->name);
2246 if (dst->unit_decl->automaton_name != NULL
2247 && src->unit_decl->automaton_name != NULL
2248 && strcmp (dst->unit_decl->automaton_name,
2249 src->unit_decl->automaton_name) != 0)
2251 error ("units `%s' and `%s' in exclusion set belong to different automata",
2252 src->unit_decl->name, dst->unit_decl->name);
2255 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2257 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2258 if (curr_el->unit_decl == src->unit_decl)
2260 if (curr_el == NULL)
2262 /* Element not found - insert. */
2263 copy = copy_node (src, sizeof (*src));
2264 copy->next_unit_set_el = NULL;
2265 if (prev_el == NULL)
2266 dst->unit_decl->excl_list = copy;
2268 prev_el->next_unit_set_el = copy;
2273 /* Checking NAMES in an presence clause vector and returning formed
2274 unit_set_el_list. The function is called only after processing all
2276 static unit_set_el_t
2277 process_presence_absence (names, num, req_pos, presence_p)
2280 pos_t req_pos ATTRIBUTE_UNUSED;
2283 unit_set_el_t el_list;
2284 unit_set_el_t last_el;
2285 unit_set_el_t new_el;
2286 decl_t decl_in_table;
2291 for (i = 0; i < num; i++)
2293 decl_in_table = find_decl (names [i]);
2294 if (decl_in_table == NULL)
2296 ? "unit `%s' in presence set is not declared"
2297 : "unit `%s' in absence set is not declared"), names [i]);
2298 else if (decl_in_table->mode != dm_unit)
2300 ? "`%s' in presence set is not unit"
2301 : "`%s' in absence set is not unit"), names [i]);
2304 new_el = create_node (sizeof (struct unit_set_el));
2305 new_el->unit_decl = &decl_in_table->decl.unit;
2306 new_el->next_unit_set_el = NULL;
2307 if (last_el == NULL)
2308 el_list = last_el = new_el;
2311 last_el->next_unit_set_el = new_el;
2312 last_el = last_el->next_unit_set_el;
2319 /* The function adds each element from SOURCE_LIST to presence (if
2320 PRESENCE_P) or absence list of the each element from DEST_LIST.
2321 Checking situations "unit requires own presence", "unit requires
2322 own absence", and "unit excludes and requires presence of ...".
2323 Remember that we process absence sets only after all presence
2326 add_presence_absence (dest_list, source_list, req_pos, presence_p)
2327 unit_set_el_t dest_list;
2328 unit_set_el_t source_list;
2329 pos_t req_pos ATTRIBUTE_UNUSED;
2334 unit_set_el_t curr_el;
2335 unit_set_el_t prev_el;
2338 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2339 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2341 if (dst->unit_decl == src->unit_decl)
2344 ? "unit `%s' requires own presence"
2345 : "unit `%s' requires own absence"), src->unit_decl->name);
2348 if (dst->unit_decl->automaton_name != NULL
2349 && src->unit_decl->automaton_name != NULL
2350 && strcmp (dst->unit_decl->automaton_name,
2351 src->unit_decl->automaton_name) != 0)
2354 ? "units `%s' and `%s' in presence set belong to different automata"
2355 : "units `%s' and `%s' in absence set belong to different automata"),
2356 src->unit_decl->name, dst->unit_decl->name);
2359 for (curr_el = (presence_p
2360 ? dst->unit_decl->presence_list
2361 : dst->unit_decl->absence_list), prev_el = NULL;
2363 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2364 if (curr_el->unit_decl == src->unit_decl)
2366 if (curr_el == NULL)
2368 /* Element not found - insert if there is no error. */
2369 int no_error_flag = 1;
2372 for (curr_el = dst->unit_decl->excl_list;
2374 curr_el = curr_el->next_unit_set_el)
2376 if (src->unit_decl == curr_el->unit_decl)
2381 ("unit `%s' excludes and requires presence of `%s'",
2382 dst->unit_decl->name, src->unit_decl->name);
2387 ("unit `%s' excludes and requires presence of `%s'",
2388 dst->unit_decl->name, src->unit_decl->name);
2392 for (curr_el = dst->unit_decl->presence_list;
2394 curr_el = curr_el->next_unit_set_el)
2396 if (src->unit_decl == curr_el->unit_decl)
2401 ("unit `%s' requires absence and presence of `%s'",
2402 dst->unit_decl->name, src->unit_decl->name);
2407 ("unit `%s' requires absence and presence of `%s'",
2408 dst->unit_decl->name, src->unit_decl->name);
2413 copy = copy_node (src, sizeof (*src));
2414 copy->next_unit_set_el = NULL;
2415 if (prev_el == NULL)
2418 dst->unit_decl->presence_list = copy;
2420 dst->unit_decl->absence_list = copy;
2423 prev_el->next_unit_set_el = copy;
2429 /* The function searches for bypass with given IN_INSN_RESERV in given
2431 static struct bypass_decl *
2432 find_bypass (bypass_list, in_insn_reserv)
2433 struct bypass_decl *bypass_list;
2434 struct insn_reserv_decl *in_insn_reserv;
2436 struct bypass_decl *bypass;
2438 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2439 if (bypass->in_insn_reserv == in_insn_reserv)
2444 /* The function processes pipeline description declarations, checks
2445 their correctness, and forms exclusion/presence/absence sets. */
2450 decl_t automaton_decl;
2451 decl_t decl_in_table;
2452 decl_t out_insn_reserv;
2453 decl_t in_insn_reserv;
2454 struct bypass_decl *bypass;
2455 int automaton_presence;
2458 /* Checking repeated automata declarations. */
2459 automaton_presence = 0;
2460 for (i = 0; i < description->decls_num; i++)
2462 decl = description->decls [i];
2463 if (decl->mode == dm_automaton)
2465 automaton_presence = 1;
2466 decl_in_table = insert_automaton_decl (decl);
2467 if (decl_in_table != decl)
2470 error ("repeated declaration of automaton `%s'",
2471 decl->decl.automaton.name);
2473 warning ("repeated declaration of automaton `%s'",
2474 decl->decl.automaton.name);
2478 /* Checking undeclared automata, repeated declarations (except for
2479 automata) and correctness of their attributes (insn latency times
2481 for (i = 0; i < description->decls_num; i++)
2483 decl = description->decls [i];
2484 if (decl->mode == dm_insn_reserv)
2486 decl->decl.insn_reserv.condexp
2487 = check_attr_test (decl->decl.insn_reserv.condexp, 0, 0);
2488 if (decl->decl.insn_reserv.default_latency < 0)
2489 error ("define_insn_reservation `%s' has negative latency time",
2490 decl->decl.insn_reserv.name);
2491 decl->decl.insn_reserv.insn_num = description->insns_num;
2492 description->insns_num++;
2493 decl_in_table = insert_insn_decl (decl);
2494 if (decl_in_table != decl)
2495 error ("`%s' is already used as insn reservation name",
2496 decl->decl.insn_reserv.name);
2498 else if (decl->mode == dm_bypass)
2500 if (decl->decl.bypass.latency < 0)
2501 error ("define_bypass `%s - %s' has negative latency time",
2502 decl->decl.bypass.out_insn_name,
2503 decl->decl.bypass.in_insn_name);
2505 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2507 if (decl->mode == dm_unit)
2509 decl->decl.unit.automaton_decl = NULL;
2510 if (decl->decl.unit.automaton_name != NULL)
2513 = find_automaton_decl (decl->decl.unit.automaton_name);
2514 if (automaton_decl == NULL)
2515 error ("automaton `%s' is not declared",
2516 decl->decl.unit.automaton_name);
2519 automaton_decl->decl.automaton.automaton_is_used = 1;
2520 decl->decl.unit.automaton_decl
2521 = &automaton_decl->decl.automaton;
2524 else if (automaton_presence)
2525 error ("define_unit `%s' without automaton when one defined",
2526 decl->decl.unit.name);
2527 decl->decl.unit.unit_num = description->units_num;
2528 description->units_num++;
2529 if (strcmp (decl->decl.unit.name, NOTHING_NAME) == 0)
2531 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2534 decl_in_table = find_decl (decl->decl.unit.name);
2538 if (strcmp (decl->decl.reserv.name, NOTHING_NAME) == 0)
2540 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2543 decl_in_table = find_decl (decl->decl.reserv.name);
2545 if (decl_in_table == NULL)
2546 decl_in_table = insert_decl (decl);
2549 if (decl->mode == dm_unit)
2550 error ("repeated declaration of unit `%s'",
2551 decl->decl.unit.name);
2553 error ("repeated declaration of reservation `%s'",
2554 decl->decl.reserv.name);
2558 /* Check bypasses and form list of bypasses for each (output)
2560 for (i = 0; i < description->decls_num; i++)
2562 decl = description->decls [i];
2563 if (decl->mode == dm_bypass)
2565 out_insn_reserv = find_insn_decl (decl->decl.bypass.out_insn_name);
2566 in_insn_reserv = find_insn_decl (decl->decl.bypass.in_insn_name);
2567 if (out_insn_reserv == NULL)
2568 error ("there is no insn reservation `%s'",
2569 decl->decl.bypass.out_insn_name);
2570 else if (in_insn_reserv == NULL)
2571 error ("there is no insn reservation `%s'",
2572 decl->decl.bypass.in_insn_name);
2575 decl->decl.bypass.out_insn_reserv
2576 = &out_insn_reserv->decl.insn_reserv;
2577 decl->decl.bypass.in_insn_reserv
2578 = &in_insn_reserv->decl.insn_reserv;
2580 = find_bypass (out_insn_reserv->decl.insn_reserv.bypass_list,
2581 decl->decl.bypass.in_insn_reserv);
2584 if (decl->decl.bypass.latency == bypass->latency)
2588 ("the same bypass `%s - %s' is already defined",
2589 decl->decl.bypass.out_insn_name,
2590 decl->decl.bypass.in_insn_name);
2593 ("the same bypass `%s - %s' is already defined",
2594 decl->decl.bypass.out_insn_name,
2595 decl->decl.bypass.in_insn_name);
2598 error ("bypass `%s - %s' is already defined",
2599 decl->decl.bypass.out_insn_name,
2600 decl->decl.bypass.in_insn_name);
2604 decl->decl.bypass.next
2605 = out_insn_reserv->decl.insn_reserv.bypass_list;
2606 out_insn_reserv->decl.insn_reserv.bypass_list
2607 = &decl->decl.bypass;
2613 /* Check exclusion set declarations and form exclussion sets. */
2614 for (i = 0; i < description->decls_num; i++)
2616 decl = description->decls [i];
2617 if (decl->mode == dm_excl)
2619 unit_set_el_t unit_set_el_list;
2620 unit_set_el_t unit_set_el_list_2;
2623 = process_excls (decl->decl.excl.names,
2624 decl->decl.excl.first_list_length, decl->pos);
2626 = process_excls (&decl->decl.excl.names
2627 [decl->decl.excl.first_list_length],
2628 decl->decl.excl.names_num
2629 - decl->decl.excl.first_list_length,
2631 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2632 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2636 /* Check presence set declarations and form presence sets. */
2637 for (i = 0; i < description->decls_num; i++)
2639 decl = description->decls [i];
2640 if (decl->mode == dm_presence)
2642 unit_set_el_t unit_set_el_list;
2643 unit_set_el_t unit_set_el_list_2;
2646 = process_presence_absence
2647 (decl->decl.presence.names,
2648 decl->decl.presence.first_list_length, decl->pos, 1);
2650 = process_presence_absence
2651 (&decl->decl.presence.names
2652 [decl->decl.presence.first_list_length],
2653 decl->decl.presence.names_num
2654 - decl->decl.presence.first_list_length,
2656 add_presence_absence (unit_set_el_list, unit_set_el_list_2,
2661 /* Check absence set declarations and form absence sets. */
2662 for (i = 0; i < description->decls_num; i++)
2664 decl = description->decls [i];
2665 if (decl->mode == dm_absence)
2667 unit_set_el_t unit_set_el_list;
2668 unit_set_el_t unit_set_el_list_2;
2671 = process_presence_absence
2672 (decl->decl.presence.names,
2673 decl->decl.presence.first_list_length, decl->pos, 0);
2675 = process_presence_absence
2676 (&decl->decl.presence.names
2677 [decl->decl.presence.first_list_length],
2678 decl->decl.presence.names_num
2679 - decl->decl.presence.first_list_length,
2681 add_presence_absence (unit_set_el_list, unit_set_el_list_2,
2687 /* The following function checks that declared automaton is used. If
2688 the automaton is not used, the function fixes error/warning. The
2689 following function must be called only after `process_decls'. */
2691 check_automaton_usage ()
2696 for (i = 0; i < description->decls_num; i++)
2698 decl = description->decls [i];
2699 if (decl->mode == dm_automaton
2700 && !decl->decl.automaton.automaton_is_used)
2703 error ("automaton `%s' is not used", decl->decl.automaton.name);
2705 warning ("automaton `%s' is not used", decl->decl.automaton.name);
2710 /* The following recursive function processes all regexp in order to
2711 fix usage of units or reservations and to fix errors of undeclared
2712 name. The function may change unit_regexp onto reserv_regexp.
2713 Remember that reserv_regexp does not exist before the function
2716 process_regexp (regexp)
2719 decl_t decl_in_table;
2720 regexp_t new_regexp;
2723 if (regexp->mode == rm_unit)
2725 decl_in_table = find_decl (regexp->regexp.unit.name);
2726 if (decl_in_table == NULL)
2727 error ("undeclared unit or reservation `%s'",
2728 regexp->regexp.unit.name);
2729 else if (decl_in_table->mode == dm_unit)
2731 decl_in_table->decl.unit.unit_is_used = 1;
2732 regexp->regexp.unit.unit_decl = &decl_in_table->decl.unit;
2734 else if (decl_in_table->mode == dm_reserv)
2736 decl_in_table->decl.reserv.reserv_is_used = 1;
2737 new_regexp = create_node (sizeof (struct regexp));
2738 new_regexp->mode = rm_reserv;
2739 new_regexp->pos = regexp->pos;
2740 new_regexp->regexp.reserv.name = regexp->regexp.unit.name;
2741 new_regexp->regexp.reserv.reserv_decl = &decl_in_table->decl.reserv;
2742 regexp = new_regexp;
2747 else if (regexp->mode == rm_sequence)
2748 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2749 regexp->regexp.sequence.regexps [i]
2750 = process_regexp (regexp->regexp.sequence.regexps [i]);
2751 else if (regexp->mode == rm_allof)
2752 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2753 regexp->regexp.allof.regexps [i]
2754 = process_regexp (regexp->regexp.allof.regexps [i]);
2755 else if (regexp->mode == rm_oneof)
2756 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2757 regexp->regexp.oneof.regexps [i]
2758 = process_regexp (regexp->regexp.oneof.regexps [i]);
2759 else if (regexp->mode == rm_repeat)
2760 regexp->regexp.repeat.regexp
2761 = process_regexp (regexp->regexp.repeat.regexp);
2762 else if (regexp->mode != rm_nothing)
2767 /* The following function processes regexp of define_reservation and
2768 define_insn_reservation with the aid of function
2769 `process_regexp'. */
2771 process_regexp_decls ()
2776 for (i = 0; i < description->decls_num; i++)
2778 decl = description->decls [i];
2779 if (decl->mode == dm_reserv)
2780 decl->decl.reserv.regexp = process_regexp (decl->decl.reserv.regexp);
2781 else if (decl->mode == dm_insn_reserv)
2782 decl->decl.insn_reserv.regexp
2783 = process_regexp (decl->decl.insn_reserv.regexp);
2787 /* The following function checks that declared unit is used. If the
2788 unit is not used, the function fixes errors/warnings. The
2789 following function must be called only after `process_decls',
2790 `process_regexp_decls'. */
2797 for (i = 0; i < description->decls_num; i++)
2799 decl = description->decls [i];
2800 if (decl->mode == dm_unit && !decl->decl.unit.unit_is_used)
2803 error ("unit `%s' is not used", decl->decl.unit.name);
2805 warning ("unit `%s' is not used", decl->decl.unit.name);
2807 else if (decl->mode == dm_reserv && !decl->decl.reserv.reserv_is_used)
2810 error ("reservation `%s' is not used", decl->decl.reserv.name);
2812 warning ("reservation `%s' is not used", decl->decl.reserv.name);
2817 /* The following variable value is number of reservation being
2818 processed on loop recognition. */
2819 static int curr_loop_pass_num;
2821 /* The following recursive function returns nonzero value if REGEXP
2822 contains given decl or reservations in given regexp refers for
2825 loop_in_regexp (regexp, start_decl)
2833 if (regexp->mode == rm_unit)
2835 else if (regexp->mode == rm_reserv)
2837 if (start_decl->mode == dm_reserv
2838 && regexp->regexp.reserv.reserv_decl == &start_decl->decl.reserv)
2840 else if (regexp->regexp.reserv.reserv_decl->loop_pass_num
2841 == curr_loop_pass_num)
2842 /* declaration has been processed. */
2846 regexp->regexp.reserv.reserv_decl->loop_pass_num
2847 = curr_loop_pass_num;
2848 return loop_in_regexp (regexp->regexp.reserv.reserv_decl->regexp,
2852 else if (regexp->mode == rm_sequence)
2854 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2855 if (loop_in_regexp (regexp->regexp.sequence.regexps [i], start_decl))
2859 else if (regexp->mode == rm_allof)
2861 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2862 if (loop_in_regexp (regexp->regexp.allof.regexps [i], start_decl))
2866 else if (regexp->mode == rm_oneof)
2868 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2869 if (loop_in_regexp (regexp->regexp.oneof.regexps [i], start_decl))
2873 else if (regexp->mode == rm_repeat)
2874 return loop_in_regexp (regexp->regexp.repeat.regexp, start_decl);
2877 if (regexp->mode != rm_nothing)
2883 /* The following function fixes errors "cycle in definition ...". The
2884 function uses function `loop_in_regexp' for that. */
2886 check_loops_in_regexps ()
2891 for (i = 0; i < description->decls_num; i++)
2893 decl = description->decls [i];
2894 if (decl->mode == dm_reserv)
2895 decl->decl.reserv.loop_pass_num = 0;
2897 for (i = 0; i < description->decls_num; i++)
2899 decl = description->decls [i];
2900 curr_loop_pass_num = i;
2902 if (decl->mode == dm_reserv)
2904 decl->decl.reserv.loop_pass_num = curr_loop_pass_num;
2905 if (loop_in_regexp (decl->decl.reserv.regexp, decl))
2907 if (decl->decl.reserv.regexp == NULL)
2909 error ("cycle in definition of reservation `%s'",
2910 decl->decl.reserv.name);
2916 /* The function recursively processes IR of reservation and defines
2917 max and min cycle for reservation of unit and for result in the
2920 process_regexp_cycles (regexp, start_cycle)
2926 if (regexp->mode == rm_unit)
2928 if (regexp->regexp.unit.unit_decl->max_occ_cycle_num < start_cycle)
2929 regexp->regexp.unit.unit_decl->max_occ_cycle_num = start_cycle;
2932 else if (regexp->mode == rm_reserv)
2933 return process_regexp_cycles (regexp->regexp.reserv.reserv_decl->regexp,
2935 else if (regexp->mode == rm_repeat)
2937 for (i = 0; i < regexp->regexp.repeat.repeat_num; i++)
2938 start_cycle = process_regexp_cycles (regexp->regexp.repeat.regexp,
2942 else if (regexp->mode == rm_sequence)
2944 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2946 = process_regexp_cycles (regexp->regexp.sequence.regexps [i],
2950 else if (regexp->mode == rm_allof)
2952 int finish_cycle = 0;
2955 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2957 cycle = process_regexp_cycles (regexp->regexp.allof.regexps [i],
2959 if (finish_cycle < cycle)
2960 finish_cycle = cycle;
2962 return finish_cycle;
2964 else if (regexp->mode == rm_oneof)
2966 int finish_cycle = 0;
2969 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2971 cycle = process_regexp_cycles (regexp->regexp.oneof.regexps [i],
2973 if (finish_cycle < cycle)
2974 finish_cycle = cycle;
2976 return finish_cycle;
2980 if (regexp->mode != rm_nothing)
2986 /* The following function is called only for correct program. The
2987 function defines max reservation of insns in cycles. */
2989 evaluate_max_reserv_cycles ()
2991 int max_insn_cycles_num;
2995 description->max_insn_reserv_cycles = 0;
2996 for (i = 0; i < description->decls_num; i++)
2998 decl = description->decls [i];
2999 if (decl->mode == dm_insn_reserv)
3002 = process_regexp_cycles (decl->decl.insn_reserv.regexp, 0);
3003 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3004 description->max_insn_reserv_cycles = max_insn_cycles_num;
3007 description->max_insn_reserv_cycles++;
3010 /* The following function calls functions for checking all
3013 check_all_description ()
3016 check_automaton_usage ();
3017 process_regexp_decls ();
3019 check_loops_in_regexps ();
3021 evaluate_max_reserv_cycles ();
3026 /* The page contains abstract data `ticker'. This data is used to
3027 report time of different phases of building automata. It is
3028 possibly to write a description for which automata will be built
3029 during several minutes even on fast machine. */
3031 /* The following function creates ticker and makes it active. */
3037 ticker.modified_creation_time = get_run_time ();
3038 ticker.incremented_off_time = 0;
3042 /* The following function switches off given ticker. */
3047 if (ticker->incremented_off_time == 0)
3048 ticker->incremented_off_time = get_run_time () + 1;
3051 /* The following function switches on given ticker. */
3056 if (ticker->incremented_off_time != 0)
3058 ticker->modified_creation_time
3059 += get_run_time () - ticker->incremented_off_time + 1;
3060 ticker->incremented_off_time = 0;
3064 /* The following function returns current time in milliseconds since
3065 the moment when given ticker was created. */
3067 active_time (ticker)
3070 if (ticker.incremented_off_time != 0)
3071 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3073 return get_run_time () - ticker.modified_creation_time;
3076 /* The following function returns string representation of active time
3077 of given ticker. The result is string representation of seconds
3078 with accuracy of 1/100 second. Only result of the last call of the
3079 function exists. Therefore the following code is not correct
3081 printf ("parser time: %s\ngeneration time: %s\n",
3082 active_time_string (parser_ticker),
3083 active_time_string (generation_ticker));
3085 Correct code has to be the following
3087 printf ("parser time: %s\n", active_time_string (parser_ticker));
3088 printf ("generation time: %s\n",
3089 active_time_string (generation_ticker));
3093 print_active_time (f, ticker)
3099 msecs = active_time (ticker);
3100 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3105 /* The following variable value is number of automaton which are
3106 really being created. This value is defined on the base of
3107 argument of option `-split'. If the variable has zero value the
3108 number of automata is defined by the constructions `%automaton'.
3109 This case occures when option `-split' is absent or has zero
3110 argument. If constructions `define_automaton' is absent only one
3111 automaton is created. */
3112 static int automata_num;
3114 /* The following variable values are times of
3115 o transformation of regular expressions
3116 o building NDFA (DFA if !ndfa_flag)
3117 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3119 o building insn equivalence classes
3122 static ticker_t transform_time;
3123 static ticker_t NDFA_time;
3124 static ticker_t NDFA_to_DFA_time;
3125 static ticker_t minimize_time;
3126 static ticker_t equiv_time;
3127 static ticker_t automaton_generation_time;
3128 static ticker_t output_time;
3130 /* The following variable values are times of
3133 all pipeline hazard translator work */
3134 static ticker_t check_time;
3135 static ticker_t generation_time;
3136 static ticker_t all_time;
3140 /* Pseudo insn decl which denotes advancing cycle. */
3141 static decl_t advance_cycle_insn_decl;
3143 add_advance_cycle_insn_decl ()
3145 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3146 advance_cycle_insn_decl->mode = dm_insn_reserv;
3147 advance_cycle_insn_decl->pos = no_pos;
3148 advance_cycle_insn_decl->decl.insn_reserv.regexp = NULL;
3149 advance_cycle_insn_decl->decl.insn_reserv.name = (char *) "$advance_cycle";
3150 advance_cycle_insn_decl->decl.insn_reserv.insn_num = description->insns_num;
3151 description->decls [description->decls_num] = advance_cycle_insn_decl;
3152 description->decls_num++;
3153 description->insns_num++;
3158 /* Abstract data `alternative states' which reperesents
3159 nondeterministic nature of the description (see comments for
3160 structures alt_state and state). */
3162 /* List of free states. */
3163 static alt_state_t first_free_alt_state;
3166 /* The following variables is maximal number of allocated nodes
3168 static int allocated_alt_states_num = 0;
3171 /* The following function returns free node alt_state. It may be new
3172 allocated node or node freed eralier. */
3174 get_free_alt_state ()
3178 if (first_free_alt_state != NULL)
3180 result = first_free_alt_state;
3181 first_free_alt_state = first_free_alt_state->next_alt_state;
3186 allocated_alt_states_num++;
3188 result = create_node (sizeof (struct alt_state));
3190 result->state = NULL;
3191 result->next_alt_state = NULL;
3192 result->next_sorted_alt_state = NULL;
3196 /* The function frees node ALT_STATE. */
3198 free_alt_state (alt_state)
3199 alt_state_t alt_state;
3201 if (alt_state == NULL)
3203 alt_state->next_alt_state = first_free_alt_state;
3204 first_free_alt_state = alt_state;
3207 /* The function frees list started with node ALT_STATE_LIST. */
3209 free_alt_states (alt_states_list)
3210 alt_state_t alt_states_list;
3212 alt_state_t curr_alt_state;
3213 alt_state_t next_alt_state;
3215 for (curr_alt_state = alt_states_list;
3216 curr_alt_state != NULL;
3217 curr_alt_state = next_alt_state)
3219 next_alt_state = curr_alt_state->next_alt_state;
3220 free_alt_state (curr_alt_state);
3224 /* The function compares unique numbers of alt states. */
3226 alt_state_cmp (alt_state_ptr_1, alt_state_ptr_2)
3227 const void *alt_state_ptr_1;
3228 const void *alt_state_ptr_2;
3230 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3231 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3233 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3234 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3240 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3241 states from the list. The comparison key is alt state unique
3244 uniq_sort_alt_states (alt_states_list)
3245 alt_state_t alt_states_list;
3247 alt_state_t curr_alt_state;
3248 vla_ptr_t alt_states;
3250 size_t prev_unique_state_ind;
3252 alt_state_t *result_ptr;
3254 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3255 for (curr_alt_state = alt_states_list;
3256 curr_alt_state != NULL;
3257 curr_alt_state = curr_alt_state->next_alt_state)
3258 VLA_PTR_ADD (alt_states, curr_alt_state);
3259 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3260 sizeof (alt_state_t), alt_state_cmp);
3261 if (VLA_PTR_LENGTH (alt_states) == 0)
3265 result_ptr = VLA_PTR_BEGIN (alt_states);
3266 prev_unique_state_ind = 0;
3267 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3268 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3270 prev_unique_state_ind++;
3271 result_ptr [prev_unique_state_ind] = result_ptr [i];
3274 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3275 free_alt_state (result_ptr [i]);
3277 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3278 result_ptr = VLA_PTR_BEGIN (alt_states);
3279 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3280 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3281 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3282 result = *result_ptr;
3284 VLA_PTR_DELETE (alt_states);
3288 /* The function checks equality of alt state lists. Remember that the
3289 lists must be already sorted by the previous function. */
3291 alt_states_eq (alt_states_1, alt_states_2)
3292 alt_state_t alt_states_1;
3293 alt_state_t alt_states_2;
3295 while (alt_states_1 != NULL && alt_states_2 != NULL
3296 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3298 alt_states_1 = alt_states_1->next_sorted_alt_state;
3299 alt_states_2 = alt_states_2->next_sorted_alt_state;
3301 return alt_states_1 == alt_states_2;
3304 /* Initialization of the abstract data. */
3306 initiate_alt_states ()
3308 first_free_alt_state = NULL;
3311 /* Finishing work with the abstract data. */
3313 finish_alt_states ()
3319 /* The page contains macros for work with bits strings. We could use
3320 standard gcc bitmap or sbitmap but it would result in difficulties
3321 of building canadian cross. */
3323 /* Set bit number bitno in the bit string. The macro is not side
3325 #define SET_BIT(bitstring, bitno) \
3326 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3328 /* Test if bit number bitno in the bitstring is set. The macro is not
3329 side effect proof. */
3330 #define TEST_BIT(bitstring, bitno) \
3331 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3335 /* This page contains abstract data `state'. */
3337 /* Maximal length of reservations in cycles (>= 1). */
3338 static int max_cycles_num;
3340 /* Number of set elements (see type set_el_t) needed for
3341 representation of one cycle reservation. It is depended on units
3343 static int els_in_cycle_reserv;
3345 /* Number of set elements (see type set_el_t) needed for
3346 representation of maximal length reservation. Deterministic
3347 reservation is stored as set (bit string) of length equal to the
3348 variable value * number of bits in set_el_t. */
3349 static int els_in_reservs;
3351 /* VLA for representation of array of pointers to unit
3353 static vla_ptr_t units_container;
3355 /* The start address of the array. */
3356 static unit_decl_t *units_array;
3358 /* Empty reservation of maximal length. */
3359 static reserv_sets_t empty_reserv;
3361 /* The state table itself is represented by the following variable. */
3362 static htab_t state_table;
3364 /* VLA for representation of array of pointers to free nodes
3366 static vla_ptr_t free_states;
3368 static int curr_unique_state_num;
3371 /* The following variables is maximal number of allocated nodes
3373 static int allocated_states_num = 0;
3376 /* Allocate new reservation set. */
3377 static reserv_sets_t
3378 alloc_empty_reserv_sets ()
3380 reserv_sets_t result;
3382 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3383 result = (reserv_sets_t) obstack_base (&irp);
3384 obstack_finish (&irp);
3385 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3389 /* Hash value of reservation set. */
3391 reserv_sets_hash_value (reservs)
3392 reserv_sets_t reservs;
3394 unsigned int hash_value;
3396 set_el_t *reserv_ptr;
3399 reservs_num = els_in_reservs;
3400 reserv_ptr = reservs;
3401 while (reservs_num != 0)
3404 hash_value = ((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3405 | (hash_value << CHAR_BIT)) + *reserv_ptr;
3411 /* Comparison of given reservation sets. */
3413 reserv_sets_cmp (reservs_1, reservs_2)
3414 reserv_sets_t reservs_1;
3415 reserv_sets_t reservs_2;
3418 set_el_t *reserv_ptr_1;
3419 set_el_t *reserv_ptr_2;
3421 if (reservs_1 == NULL || reservs_2 == NULL)
3423 reservs_num = els_in_reservs;
3424 reserv_ptr_1 = reservs_1;
3425 reserv_ptr_2 = reservs_2;
3426 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3432 if (reservs_num == 0)
3434 else if (*reserv_ptr_1 < *reserv_ptr_2)
3440 /* The function checks equality of the reservation sets. */
3442 reserv_sets_eq (reservs_1, reservs_2)
3443 reserv_sets_t reservs_1;
3444 reserv_sets_t reservs_2;
3446 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3449 /* Set up in the reservation set that unit with UNIT_NUM is used on
3452 set_unit_reserv (reservs, cycle_num, unit_num)
3453 reserv_sets_t reservs;
3457 if (cycle_num >= max_cycles_num)
3459 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3460 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3463 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3464 used on CYCLE_NUM. */
3466 test_unit_reserv (reservs, cycle_num, unit_num)
3467 reserv_sets_t reservs;
3471 if (cycle_num >= max_cycles_num)
3473 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3474 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3477 /* The function checks that the reservation set represents no one unit
3480 it_is_empty_reserv_sets (operand)
3481 reserv_sets_t operand;
3483 set_el_t *reserv_ptr;
3486 if (operand == NULL)
3488 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3490 reserv_ptr++, reservs_num--)
3491 if (*reserv_ptr != 0)
3496 /* The function checks that the reservation sets are intersected,
3497 i.e. there is a unit reservation on a cycle in both reservation
3500 reserv_sets_are_intersected (operand_1, operand_2)
3501 reserv_sets_t operand_1;
3502 reserv_sets_t operand_2;
3506 set_el_t *cycle_ptr_1;
3507 set_el_t *cycle_ptr_2;
3510 if (operand_1 == NULL || operand_2 == NULL)
3512 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3513 el_ptr_1 < operand_1 + els_in_reservs;
3514 el_ptr_1++, el_ptr_2++)
3515 if (*el_ptr_1 & *el_ptr_2)
3517 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3518 cycle_ptr_1 < operand_1 + els_in_reservs;
3519 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3521 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3522 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3523 el_ptr_1++, el_ptr_2++)
3524 if (*el_ptr_1 & *el_ptr_2)
3527 for (el_ptr_1 = cycle_ptr_1,
3528 el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 1);
3529 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3530 el_ptr_1++, el_ptr_2++)
3531 if (*el_ptr_1 & *el_ptr_2)
3533 else if (*el_ptr_2 != 0)
3535 if (nonzero_p && el_ptr_1 >= cycle_ptr_1 + els_in_cycle_reserv)
3537 for (el_ptr_1 = cycle_ptr_1,
3538 el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 0);
3539 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3540 el_ptr_1++, el_ptr_2++)
3541 /* It looks like code for exclusion but exclusion set is
3542 made as symmetric relation preliminary. */
3543 if (*el_ptr_1 & *el_ptr_2)
3549 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3550 cpu cycle. The remaining bits of OPERAND (representing the last
3551 cycle unit reservations) are not chenged. */
3553 reserv_sets_shift (result, operand)
3554 reserv_sets_t result;
3555 reserv_sets_t operand;
3559 if (result == NULL || operand == NULL || result == operand)
3561 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3562 result [i - els_in_cycle_reserv] = operand [i];
3565 /* OR of the reservation sets. */
3567 reserv_sets_or (result, operand_1, operand_2)
3568 reserv_sets_t result;
3569 reserv_sets_t operand_1;
3570 reserv_sets_t operand_2;
3574 set_el_t *result_set_el_ptr;
3576 if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3578 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3579 el_ptr_1 < operand_1 + els_in_reservs;
3580 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3581 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3584 /* AND of the reservation sets. */
3586 reserv_sets_and (result, operand_1, operand_2)
3587 reserv_sets_t result;
3588 reserv_sets_t operand_1;
3589 reserv_sets_t operand_2;
3593 set_el_t *result_set_el_ptr;
3595 if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3597 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3598 el_ptr_1 < operand_1 + els_in_reservs;
3599 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3600 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3603 /* The function outputs string representation of units reservation on
3604 cycle START_CYCLE in the reservation set. The function uses repeat
3605 construction if REPETITION_NUM > 1. */
3607 output_cycle_reservs (f, reservs, start_cycle, repetition_num)
3609 reserv_sets_t reservs;
3614 int reserved_units_num;
3616 reserved_units_num = 0;
3617 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3618 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3619 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3620 reserved_units_num++;
3621 if (repetition_num <= 0)
3623 if (repetition_num != 1 && reserved_units_num > 1)
3625 reserved_units_num = 0;
3627 unit_num < description->units_num;
3629 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3630 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3632 if (reserved_units_num != 0)
3634 reserved_units_num++;
3635 fprintf (f, "%s", units_array [unit_num]->name);
3637 if (reserved_units_num == 0)
3638 fprintf (f, NOTHING_NAME);
3639 if (repetition_num <= 0)
3641 if (reserved_units_num != 0 && repetition_num != 1)
3643 if (reserved_units_num > 1)
3645 fprintf (f, "*%d", repetition_num);
3649 /* The function outputs string representation of units reservation in
3650 the reservation set. */
3652 output_reserv_sets (f, reservs)
3654 reserv_sets_t reservs;
3656 int start_cycle = 0;
3661 for (cycle = 0; cycle < max_cycles_num; cycle++)
3662 if (repetition_num == 0)
3665 start_cycle = cycle;
3668 ((char *) reservs + start_cycle * els_in_cycle_reserv
3669 * sizeof (set_el_t),
3670 (char *) reservs + cycle * els_in_cycle_reserv
3671 * sizeof (set_el_t),
3672 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3676 if (start_cycle != 0)
3678 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3680 start_cycle = cycle;
3682 if (start_cycle < max_cycles_num)
3684 if (start_cycle != 0)
3686 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3690 /* The following function returns free node state for AUTOMATON. It
3691 may be new allocated node or node freed eralier. The function also
3692 allocates reservation set if WITH_RESERVS has nonzero value. */
3694 get_free_state (with_reservs, automaton)
3696 automaton_t automaton;
3700 if (max_cycles_num <= 0 || automaton == NULL)
3702 if (VLA_PTR_LENGTH (free_states) != 0)
3704 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
3705 VLA_PTR_SHORTEN (free_states, 1);
3706 result->automaton = automaton;
3707 result->first_out_arc = NULL;
3708 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3709 result->it_was_placed_in_stack_for_DFA_forming = 0;
3710 result->component_states = NULL;
3711 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3716 allocated_states_num++;
3718 result = create_node (sizeof (struct state));
3719 result->automaton = automaton;
3720 result->first_out_arc = NULL;
3721 result->unique_num = curr_unique_state_num;
3722 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3723 curr_unique_state_num++;
3727 if (result->reservs == NULL)
3728 result->reservs = alloc_empty_reserv_sets ();
3730 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3735 /* The function frees node STATE. */
3740 free_alt_states (state->component_states);
3741 VLA_PTR_ADD (free_states, state);
3744 /* Hash value of STATE. If STATE represents deterministic state it is
3745 simply hash value of the corresponding reservation set. Otherwise
3746 it is formed from hash values of the component deterministic
3747 states. One more key is order number of state automaton. */
3752 unsigned int hash_value;
3753 alt_state_t alt_state;
3755 if (((state_t) state)->component_states == NULL)
3756 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
3760 for (alt_state = ((state_t) state)->component_states;
3762 alt_state = alt_state->next_sorted_alt_state)
3763 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3764 | (hash_value << CHAR_BIT))
3765 + alt_state->state->unique_num);
3767 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3768 | (hash_value << CHAR_BIT))
3769 + ((state_t) state)->automaton->automaton_order_num);
3773 /* Return nonzero value if the states are the same. */
3775 state_eq_p (state_1, state_2)
3776 const void *state_1;
3777 const void *state_2;
3779 alt_state_t alt_state_1;
3780 alt_state_t alt_state_2;
3782 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
3784 else if (((state_t) state_1)->component_states == NULL
3785 && ((state_t) state_2)->component_states == NULL)
3786 return reserv_sets_eq (((state_t) state_1)->reservs,
3787 ((state_t) state_2)->reservs);
3788 else if (((state_t) state_1)->component_states != NULL
3789 && ((state_t) state_2)->component_states != NULL)
3791 for (alt_state_1 = ((state_t) state_1)->component_states,
3792 alt_state_2 = ((state_t) state_2)->component_states;
3793 alt_state_1 != NULL && alt_state_2 != NULL;
3794 alt_state_1 = alt_state_1->next_sorted_alt_state,
3795 alt_state_2 = alt_state_2->next_sorted_alt_state)
3796 /* All state in the list must be already in the hash table.
3797 Also the lists must be sorted. */
3798 if (alt_state_1->state != alt_state_2->state)
3800 return alt_state_1 == alt_state_2;
3806 /* Insert STATE into the state table. */
3808 insert_state (state)
3813 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
3814 if (*entry_ptr == NULL)
3815 *entry_ptr = (void *) state;
3816 return (state_t) *entry_ptr;
3819 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3820 deterministic STATE. */
3822 set_state_reserv (state, cycle_num, unit_num)
3827 set_unit_reserv (state->reservs, cycle_num, unit_num);
3830 /* Return nonzero value if the deterministic states contains a
3831 reservation of the same cpu unit on the same cpu cycle. */
3833 intersected_state_reservs_p (state1, state2)
3837 if (state1->automaton != state2->automaton)
3839 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3842 /* Return deterministic state (inserted into the table) which
3843 representing the automaton state whic is union of reservations of
3844 deterministic states. */
3846 states_union (state1, state2)
3851 state_t state_in_table;
3853 if (state1->automaton != state2->automaton)
3855 result = get_free_state (1, state1->automaton);
3856 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
3857 state_in_table = insert_state (result);
3858 if (result != state_in_table)
3860 free_state (result);
3861 result = state_in_table;
3866 /* Return deterministic state (inserted into the table) which
3867 represent the automaton state is obtained from deterministic STATE
3868 by advancing cpu cycle. */
3874 state_t state_in_table;
3876 result = get_free_state (1, state->automaton);
3877 reserv_sets_shift (result->reservs, state->reservs);
3878 state_in_table = insert_state (result);
3879 if (result != state_in_table)
3881 free_state (result);
3882 result = state_in_table;
3887 /* Initialization of the abstract data. */
3894 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
3896 = (description->decls_num && description->units_num
3897 ? VLA_PTR_BEGIN (units_container) : NULL);
3898 for (i = 0; i < description->decls_num; i++)
3900 decl = description->decls [i];
3901 if (decl->mode == dm_unit)
3902 units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
3904 max_cycles_num = description->max_insn_reserv_cycles;
3906 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3907 / (sizeof (set_el_t) * CHAR_BIT));
3908 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3909 curr_unique_state_num = 0;
3910 initiate_alt_states ();
3911 VLA_PTR_CREATE (free_states, 1500, "free states");
3912 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3913 empty_reserv = alloc_empty_reserv_sets ();
3916 /* Finisging work with the abstract data. */
3920 VLA_PTR_DELETE (units_container);
3921 htab_delete (state_table);
3922 VLA_PTR_DELETE (free_states);
3923 finish_alt_states ();
3928 /* Abstract data `arcs'. */
3930 /* List of free arcs. */
3931 static arc_t first_free_arc;
3934 /* The following variables is maximal number of allocated nodes
3936 static int allocated_arcs_num = 0;
3939 /* The function frees node ARC. */
3944 arc->next_out_arc = first_free_arc;
3945 first_free_arc = arc;
3948 /* The function removes and frees ARC staring from FROM_STATE. */
3950 remove_arc (from_state, arc)
3959 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3961 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3962 if (curr_arc == arc)
3964 if (curr_arc == NULL)
3966 if (prev_arc == NULL)
3967 from_state->first_out_arc = arc->next_out_arc;
3969 prev_arc->next_out_arc = arc->next_out_arc;
3973 /* The functions returns arc with given characteristics (or NULL if
3974 the arc does not exist). */
3976 find_arc (from_state, to_state, insn)
3983 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3984 if (arc->to_state == to_state && arc->insn == insn)
3989 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
3990 and with given STATE_ALTS. The function returns added arc (or
3991 already existing arc). */
3993 add_arc (from_state, to_state, ainsn, state_alts)
4001 new_arc = find_arc (from_state, to_state, ainsn);
4002 if (new_arc != NULL)
4004 if (first_free_arc == NULL)
4007 allocated_arcs_num++;
4009 new_arc = create_node (sizeof (struct arc));
4010 new_arc->to_state = NULL;
4011 new_arc->insn = NULL;
4012 new_arc->next_out_arc = NULL;
4016 new_arc = first_free_arc;
4017 first_free_arc = first_free_arc->next_out_arc;
4019 new_arc->to_state = to_state;
4020 new_arc->insn = ainsn;
4021 ainsn->arc_exists_p = 1;
4022 new_arc->next_out_arc = from_state->first_out_arc;
4023 from_state->first_out_arc = new_arc;
4024 new_arc->next_arc_marked_by_insn = NULL;
4025 new_arc->state_alts = state_alts;
4029 /* The function returns the first arc starting from STATE. */
4031 first_out_arc (state)
4034 return state->first_out_arc;
4037 /* The function returns next out arc after ARC. */
4042 return arc->next_out_arc;
4045 /* Initialization of the abstract data. */
4049 first_free_arc = NULL;
4052 /* Finishing work with the abstract data. */
4060 /* Abstract data `automata lists'. */
4062 /* List of free states. */
4063 static automata_list_el_t first_free_automata_list_el;
4065 /* The list being formed. */
4066 static automata_list_el_t current_automata_list;
4068 /* Hash table of automata lists. */
4069 static htab_t automata_list_table;
4071 /* The following function returns free automata list el. It may be
4072 new allocated node or node freed earlier. */
4073 static automata_list_el_t
4074 get_free_automata_list_el ()
4076 automata_list_el_t result;
4078 if (first_free_automata_list_el != NULL)
4080 result = first_free_automata_list_el;
4081 first_free_automata_list_el
4082 = first_free_automata_list_el->next_automata_list_el;
4085 result = create_node (sizeof (struct automata_list_el));
4086 result->automaton = NULL;
4087 result->next_automata_list_el = NULL;
4091 /* The function frees node AUTOMATA_LIST_EL. */
4093 free_automata_list_el (automata_list_el)
4094 automata_list_el_t automata_list_el;
4096 if (automata_list_el == NULL)
4098 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4099 first_free_automata_list_el = automata_list_el;
4102 /* The function frees list AUTOMATA_LIST. */
4104 free_automata_list (automata_list)
4105 automata_list_el_t automata_list;
4107 automata_list_el_t curr_automata_list_el;
4108 automata_list_el_t next_automata_list_el;
4110 for (curr_automata_list_el = automata_list;
4111 curr_automata_list_el != NULL;
4112 curr_automata_list_el = next_automata_list_el)
4114 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4115 free_automata_list_el (curr_automata_list_el);
4119 /* Hash value of AUTOMATA_LIST. */
4121 automata_list_hash (automata_list)
4122 const void *automata_list;
4124 unsigned int hash_value;
4125 automata_list_el_t curr_automata_list_el;
4128 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4129 curr_automata_list_el != NULL;
4130 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4131 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4132 | (hash_value << CHAR_BIT))
4133 + curr_automata_list_el->automaton->automaton_order_num);
4137 /* Return nonzero value if the automata_lists are the same. */
4139 automata_list_eq_p (automata_list_1, automata_list_2)
4140 const void *automata_list_1;
4141 const void *automata_list_2;
4143 automata_list_el_t automata_list_el_1;
4144 automata_list_el_t automata_list_el_2;
4146 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4147 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4148 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4149 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4150 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4151 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4153 return automata_list_el_1 == automata_list_el_2;
4156 /* Initialization of the abstract data. */
4158 initiate_automata_lists ()
4160 first_free_automata_list_el = NULL;
4161 automata_list_table = htab_create (1500, automata_list_hash,
4162 automata_list_eq_p, (htab_del) 0);
4165 /* The following function starts new automata list and makes it the
4168 automata_list_start ()
4170 current_automata_list = NULL;
4173 /* The following function adds AUTOMATON to the current list. */
4175 automata_list_add (automaton)
4176 automaton_t automaton;
4178 automata_list_el_t el;
4180 el = get_free_automata_list_el ();
4181 el->automaton = automaton;
4182 el->next_automata_list_el = current_automata_list;
4183 current_automata_list = el;
4186 /* The following function finishes forming the current list, inserts
4187 it into the table and returns it. */
4188 static automata_list_el_t
4189 automata_list_finish ()
4193 if (current_automata_list == NULL)
4195 entry_ptr = htab_find_slot (automata_list_table,
4196 (void *) current_automata_list, 1);
4197 if (*entry_ptr == NULL)
4198 *entry_ptr = (void *) current_automata_list;
4200 free_automata_list (current_automata_list);
4201 current_automata_list = NULL;
4202 return (automata_list_el_t) *entry_ptr;
4205 /* Finishing work with the abstract data. */
4207 finish_automata_lists ()
4209 htab_delete (automata_list_table);
4214 /* The page contains abstract data for work with exclusion sets (see
4215 exclusion_set in file rtl.def). */
4217 /* The following variable refers to an exclusion set returned by
4218 get_excl_set. This is bit string of length equal to cpu units
4219 number. If exclusion set for given unit contains 1 for a unit,
4220 then simultaneous reservation of the units is prohibited. */
4221 static reserv_sets_t excl_set;
4223 /* The array contains exclusion sets for each unit. */
4224 static reserv_sets_t *unit_excl_set_table;
4226 /* The following function forms the array containing exclusion sets
4229 initiate_excl_sets ()
4232 reserv_sets_t unit_excl_set;
4236 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4237 excl_set = (reserv_sets_t) obstack_base (&irp);
4238 obstack_finish (&irp);
4239 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4240 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4241 obstack_finish (&irp);
4242 /* Evaluate unit exclusion sets. */
4243 for (i = 0; i < description->decls_num; i++)
4245 decl = description->decls [i];
4246 if (decl->mode == dm_unit)
4248 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4249 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4250 obstack_finish (&irp);
4251 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4252 for (el = decl->decl.unit.excl_list;
4254 el = el->next_unit_set_el)
4255 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4256 unit_excl_set_table [decl->decl.unit.unit_num] = unit_excl_set;
4261 /* The function sets up and return EXCL_SET which is union of
4262 exclusion sets for each unit in IN_SET. */
4263 static reserv_sets_t
4264 get_excl_set (in_set)
4265 reserv_sets_t in_set;
4273 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4274 memset (excl_set, 0, chars_num);
4275 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4276 if (((unsigned char *) in_set) [excl_char_num])
4277 for (i = CHAR_BIT - 1; i >= 0; i--)
4278 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4280 start_unit_num = excl_char_num * CHAR_BIT + i;
4281 if (start_unit_num >= description->units_num)
4283 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4286 |= unit_excl_set_table [start_unit_num] [unit_num];
4294 /* The page contains abstract data for work with presence/absence sets
4295 (see presence_set/absence_set in file rtl.def). */
4297 /* The following variables refer to correspondingly an presence and an
4298 absence set returned by get_presence_absence_set. This is bit
4299 string of length equal to cpu units number. */
4300 static reserv_sets_t presence_set, absence_set;
4302 /* The following arrays contain correspondingly presence and absence
4303 sets for each unit. */
4304 static reserv_sets_t *unit_presence_set_table, *unit_absence_set_table;
4306 /* The following function forms the array containing presence and
4307 absence sets for each unit */
4309 initiate_presence_absence_sets ()
4312 reserv_sets_t unit_set;
4316 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4317 presence_set = (reserv_sets_t) obstack_base (&irp);
4318 obstack_finish (&irp);
4319 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4320 unit_presence_set_table = (reserv_sets_t *) obstack_base (&irp);
4321 obstack_finish (&irp);
4322 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4323 absence_set = (reserv_sets_t) obstack_base (&irp);
4324 obstack_finish (&irp);
4325 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4326 unit_absence_set_table = (reserv_sets_t *) obstack_base (&irp);
4327 obstack_finish (&irp);
4328 /* Evaluate unit presence/absence sets. */
4329 for (i = 0; i < description->decls_num; i++)
4331 decl = description->decls [i];
4332 if (decl->mode == dm_unit)
4334 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4335 unit_set = (reserv_sets_t) obstack_base (&irp);
4336 obstack_finish (&irp);
4337 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4338 for (el = decl->decl.unit.presence_list;
4340 el = el->next_unit_set_el)
4341 SET_BIT (unit_set, el->unit_decl->unit_num);
4342 unit_presence_set_table [decl->decl.unit.unit_num] = unit_set;
4344 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4345 unit_set = (reserv_sets_t) obstack_base (&irp);
4346 obstack_finish (&irp);
4347 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4348 for (el = decl->decl.unit.absence_list;
4350 el = el->next_unit_set_el)
4351 SET_BIT (unit_set, el->unit_decl->unit_num);
4352 unit_absence_set_table [decl->decl.unit.unit_num] = unit_set;
4357 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4358 ABSENCE_SET which is union of corresponding sets for each unit in
4360 static reserv_sets_t
4361 get_presence_absence_set (in_set, presence_p)
4362 reserv_sets_t in_set;
4371 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4373 memset (presence_set, 0, chars_num);
4375 memset (absence_set, 0, chars_num);
4376 for (char_num = 0; char_num < chars_num; char_num++)
4377 if (((unsigned char *) in_set) [char_num])
4378 for (i = CHAR_BIT - 1; i >= 0; i--)
4379 if ((((unsigned char *) in_set) [char_num] >> i) & 1)
4381 start_unit_num = char_num * CHAR_BIT + i;
4382 if (start_unit_num >= description->units_num)
4383 return (presence_p ? presence_set : absence_set);
4384 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4386 presence_set [unit_num]
4387 |= unit_presence_set_table [start_unit_num] [unit_num];
4389 absence_set [unit_num]
4390 |= unit_absence_set_table [start_unit_num] [unit_num];
4392 return (presence_p ? presence_set : absence_set);
4397 /* This page contains code for transformation of original reservations
4398 described in .md file. The main goal of transformations is
4399 simplifying reservation and lifting up all `|' on the top of IR
4400 reservation representation. */
4403 /* The following function makes copy of IR representation of
4404 reservation. The function also substitutes all reservations
4405 defined by define_reservation by corresponding value during making
4408 copy_insn_regexp (regexp)
4414 if (regexp->mode == rm_reserv)
4415 result = copy_insn_regexp (regexp->regexp.reserv.reserv_decl->regexp);
4416 else if (regexp->mode == rm_unit)
4417 result = copy_node (regexp, sizeof (struct regexp));
4418 else if (regexp->mode == rm_repeat)
4420 result = copy_node (regexp, sizeof (struct regexp));
4421 result->regexp.repeat.regexp
4422 = copy_insn_regexp (regexp->regexp.repeat.regexp);
4424 else if (regexp->mode == rm_sequence)
4426 result = copy_node (regexp,
4427 sizeof (struct regexp) + sizeof (regexp_t)
4428 * (regexp->regexp.sequence.regexps_num - 1));
4429 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4430 result->regexp.sequence.regexps [i]
4431 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4433 else if (regexp->mode == rm_allof)
4435 result = copy_node (regexp,
4436 sizeof (struct regexp) + sizeof (regexp_t)
4437 * (regexp->regexp.allof.regexps_num - 1));
4438 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4439 result->regexp.allof.regexps [i]
4440 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4442 else if (regexp->mode == rm_oneof)
4444 result = copy_node (regexp,
4445 sizeof (struct regexp) + sizeof (regexp_t)
4446 * (regexp->regexp.oneof.regexps_num - 1));
4447 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4448 result->regexp.oneof.regexps [i]
4449 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4453 if (regexp->mode != rm_nothing)
4455 result = copy_node (regexp, sizeof (struct regexp));
4460 /* The following variable is set up 1 if a transformation has been
4462 static int regexp_transformed_p;
4464 /* The function makes transformation
4467 transform_1 (regexp)
4475 if (regexp->mode == rm_repeat)
4477 repeat_num = regexp->regexp.repeat.repeat_num;
4478 if (repeat_num <= 1)
4480 operand = regexp->regexp.repeat.regexp;
4482 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4483 * (repeat_num - 1));
4484 regexp->mode = rm_sequence;
4486 regexp->regexp.sequence.regexps_num = repeat_num;
4487 for (i = 0; i < repeat_num; i++)
4488 regexp->regexp.sequence.regexps [i] = copy_insn_regexp (operand);
4489 regexp_transformed_p = 1;
4494 /* The function makes transformations
4495 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4496 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4497 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4499 transform_2 (regexp)
4502 if (regexp->mode == rm_sequence)
4509 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4510 if (regexp->regexp.sequence.regexps [i]->mode == rm_sequence)
4513 sequence = regexp->regexp.sequence.regexps [i];
4516 if (i < regexp->regexp.sequence.regexps_num)
4518 if (sequence->regexp.sequence.regexps_num <= 1
4519 || regexp->regexp.sequence.regexps_num <= 1)
4521 result = create_node (sizeof (struct regexp)
4523 * (regexp->regexp.sequence.regexps_num
4524 + sequence->regexp.sequence.regexps_num
4526 result->mode = rm_sequence;
4527 result->pos = regexp->pos;
4528 result->regexp.sequence.regexps_num
4529 = (regexp->regexp.sequence.regexps_num
4530 + sequence->regexp.sequence.regexps_num - 1);
4531 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4532 if (i < sequence_index)
4533 result->regexp.sequence.regexps [i]
4534 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4535 else if (i > sequence_index)
4536 result->regexp.sequence.regexps
4537 [i + sequence->regexp.sequence.regexps_num - 1]
4538 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4540 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4541 result->regexp.sequence.regexps [i + j]
4542 = copy_insn_regexp (sequence->regexp.sequence.regexps [j]);
4543 regexp_transformed_p = 1;
4547 else if (regexp->mode == rm_allof)
4554 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4555 if (regexp->regexp.allof.regexps [i]->mode == rm_allof)
4558 allof = regexp->regexp.allof.regexps [i];
4561 if (i < regexp->regexp.allof.regexps_num)
4563 if (allof->regexp.allof.regexps_num <= 1
4564 || regexp->regexp.allof.regexps_num <= 1)
4566 result = create_node (sizeof (struct regexp)
4568 * (regexp->regexp.allof.regexps_num
4569 + allof->regexp.allof.regexps_num - 2));
4570 result->mode = rm_allof;
4571 result->pos = regexp->pos;
4572 result->regexp.allof.regexps_num
4573 = (regexp->regexp.allof.regexps_num
4574 + allof->regexp.allof.regexps_num - 1);
4575 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4576 if (i < allof_index)
4577 result->regexp.allof.regexps [i]
4578 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4579 else if (i > allof_index)
4580 result->regexp.allof.regexps
4581 [i + allof->regexp.allof.regexps_num - 1]
4582 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4584 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4585 result->regexp.allof.regexps [i + j]
4586 = copy_insn_regexp (allof->regexp.allof.regexps [j]);
4587 regexp_transformed_p = 1;
4591 else if (regexp->mode == rm_oneof)
4598 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4599 if (regexp->regexp.oneof.regexps [i]->mode == rm_oneof)
4602 oneof = regexp->regexp.oneof.regexps [i];
4605 if (i < regexp->regexp.oneof.regexps_num)
4607 if (oneof->regexp.oneof.regexps_num <= 1
4608 || regexp->regexp.oneof.regexps_num <= 1)
4610 result = create_node (sizeof (struct regexp)
4612 * (regexp->regexp.oneof.regexps_num
4613 + oneof->regexp.oneof.regexps_num - 2));
4614 result->mode = rm_oneof;
4615 result->pos = regexp->pos;
4616 result->regexp.oneof.regexps_num
4617 = (regexp->regexp.oneof.regexps_num
4618 + oneof->regexp.oneof.regexps_num - 1);
4619 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4620 if (i < oneof_index)
4621 result->regexp.oneof.regexps [i]
4622 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4623 else if (i > oneof_index)
4624 result->regexp.oneof.regexps
4625 [i + oneof->regexp.oneof.regexps_num - 1]
4626 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4628 for (j = 0; j < oneof->regexp.oneof.regexps_num; j++)
4629 result->regexp.oneof.regexps [i + j]
4630 = copy_insn_regexp (oneof->regexp.oneof.regexps [j]);
4631 regexp_transformed_p = 1;
4638 /* The function makes transformations
4639 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4640 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4641 ...+(A,B,...)+C+... -> (...+A+C+...),B,... */
4643 transform_3 (regexp)
4646 if (regexp->mode == rm_sequence)
4654 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4655 if (regexp->regexp.sequence.regexps [i]->mode == rm_oneof)
4658 oneof = regexp->regexp.sequence.regexps [i];
4661 if (i < regexp->regexp.sequence.regexps_num)
4663 if (oneof->regexp.oneof.regexps_num <= 1
4664 || regexp->regexp.sequence.regexps_num <= 1)
4666 result = create_node (sizeof (struct regexp)
4668 * (oneof->regexp.oneof.regexps_num - 1));
4669 result->mode = rm_oneof;
4670 result->pos = regexp->pos;
4671 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4672 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4675 = create_node (sizeof (struct regexp)
4677 * (regexp->regexp.sequence.regexps_num - 1));
4678 sequence->mode = rm_sequence;
4679 sequence->pos = regexp->pos;
4680 sequence->regexp.sequence.regexps_num
4681 = regexp->regexp.sequence.regexps_num;
4682 result->regexp.oneof.regexps [i] = sequence;
4683 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4684 if (j != oneof_index)
4685 sequence->regexp.sequence.regexps [j]
4686 = copy_insn_regexp (regexp->regexp.sequence.regexps [j]);
4688 sequence->regexp.sequence.regexps [j]
4689 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4691 regexp_transformed_p = 1;
4695 else if (regexp->mode == rm_allof)
4697 regexp_t oneof, seq;
4698 int oneof_index, seq_index;
4703 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4704 if (regexp->regexp.allof.regexps [i]->mode == rm_oneof)
4707 oneof = regexp->regexp.allof.regexps [i];
4710 if (i < regexp->regexp.allof.regexps_num)
4712 if (oneof->regexp.oneof.regexps_num <= 1
4713 || regexp->regexp.allof.regexps_num <= 1)
4715 result = create_node (sizeof (struct regexp)
4717 * (oneof->regexp.oneof.regexps_num - 1));
4718 result->mode = rm_oneof;
4719 result->pos = regexp->pos;
4720 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4721 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4724 = create_node (sizeof (struct regexp)
4726 * (regexp->regexp.allof.regexps_num - 1));
4727 allof->mode = rm_allof;
4728 allof->pos = regexp->pos;
4729 allof->regexp.allof.regexps_num
4730 = regexp->regexp.allof.regexps_num;
4731 result->regexp.oneof.regexps [i] = allof;
4732 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4733 if (j != oneof_index)
4734 allof->regexp.allof.regexps [j]
4735 = copy_insn_regexp (regexp->regexp.allof.regexps [j]);
4737 allof->regexp.allof.regexps [j]
4738 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4740 regexp_transformed_p = 1;
4743 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4744 if (regexp->regexp.allof.regexps [i]->mode == rm_sequence)
4747 seq = regexp->regexp.allof.regexps [i];
4750 if (i < regexp->regexp.allof.regexps_num)
4752 if (seq->regexp.sequence.regexps_num <= 1
4753 || regexp->regexp.allof.regexps_num <= 1)
4755 result = create_node (sizeof (struct regexp)
4757 * (seq->regexp.sequence.regexps_num - 1));
4758 result->mode = rm_sequence;
4759 result->pos = regexp->pos;
4760 result->regexp.sequence.regexps_num
4761 = seq->regexp.sequence.regexps_num;
4762 allof = create_node (sizeof (struct regexp)
4764 * (regexp->regexp.allof.regexps_num - 1));
4765 allof->mode = rm_allof;
4766 allof->pos = regexp->pos;
4767 allof->regexp.allof.regexps_num = regexp->regexp.allof.regexps_num;
4768 result->regexp.sequence.regexps [0] = allof;
4769 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4771 allof->regexp.allof.regexps [j]
4772 = copy_insn_regexp (regexp->regexp.allof.regexps [j]);
4774 allof->regexp.allof.regexps [j]
4775 = copy_insn_regexp (seq->regexp.sequence.regexps [0]);
4776 for (i = 1; i < result->regexp.sequence.regexps_num; i++)
4777 result->regexp.sequence.regexps [i]
4778 = copy_insn_regexp (seq->regexp.sequence.regexps [i]);
4779 regexp_transformed_p = 1;
4786 /* The function traverses IR of reservation and applies transformations
4787 implemented by FUNC. */
4789 regexp_transform_func (regexp, func)
4791 regexp_t (*func) PARAMS ((regexp_t regexp));
4795 if (regexp->mode == rm_sequence)
4796 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4797 regexp->regexp.sequence.regexps [i]
4798 = regexp_transform_func (regexp->regexp.sequence.regexps [i], func);
4799 else if (regexp->mode == rm_allof)
4800 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4801 regexp->regexp.allof.regexps [i]
4802 = regexp_transform_func (regexp->regexp.allof.regexps [i], func);
4803 else if (regexp->mode == rm_oneof)
4804 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4805 regexp->regexp.oneof.regexps [i]
4806 = regexp_transform_func (regexp->regexp.oneof.regexps [i], func);
4807 else if (regexp->mode == rm_repeat)
4808 regexp->regexp.repeat.regexp
4809 = regexp_transform_func (regexp->regexp.repeat.regexp, func);
4810 else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
4812 return (*func) (regexp);
4815 /* The function applies all transformations for IR representation of
4816 reservation REGEXP. */
4818 transform_regexp (regexp)
4821 regexp = regexp_transform_func (regexp, transform_1);
4824 regexp_transformed_p = 0;
4825 regexp = regexp_transform_func (regexp, transform_2);
4826 regexp = regexp_transform_func (regexp, transform_3);
4828 while (regexp_transformed_p);
4832 /* The function applys all transformations for reservations of all
4833 insn declarations. */
4835 transform_insn_regexps ()
4840 transform_time = create_ticker ();
4841 add_advance_cycle_insn_decl ();
4842 fprintf (stderr, "Reservation transformation...");
4844 for (i = 0; i < description->decls_num; i++)
4846 decl = description->decls [i];
4847 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4848 decl->decl.insn_reserv.transformed_regexp
4849 = transform_regexp (copy_insn_regexp
4850 (decl->decl.insn_reserv.regexp));
4852 fprintf (stderr, "done\n");
4853 ticker_off (&transform_time);
4859 /* The following variable is an array indexed by cycle. Each element
4860 contains cyclic list of units which should be in the same cycle. */
4861 static unit_decl_t *the_same_automaton_lists;
4863 /* The function processes all alternative reservations on CYCLE in
4864 given REGEXP to check the UNIT is not reserved on the all
4865 alternatives. If it is true, the unit should be in the same
4866 automaton with other analogous units reserved on CYCLE in given
4869 process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
4875 regexp_t seq, allof;
4876 unit_decl_t unit_decl, last;
4878 if (regexp == NULL || regexp->mode != rm_oneof)
4880 unit_decl = unit->regexp.unit.unit_decl;
4881 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4883 seq = regexp->regexp.oneof.regexps [i];
4884 if (seq->mode == rm_sequence)
4886 if (cycle >= seq->regexp.sequence.regexps_num)
4888 allof = seq->regexp.sequence.regexps [cycle];
4889 if (allof->mode == rm_allof)
4891 for (k = 0; k < allof->regexp.allof.regexps_num; k++)
4892 if (allof->regexp.allof.regexps [k]->mode == rm_unit
4893 && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
4896 if (k >= allof->regexp.allof.regexps_num)
4899 else if (allof->mode == rm_unit
4900 && allof->regexp.unit.unit_decl != unit_decl)
4903 else if (cycle != 0)
4905 else if (seq->mode == rm_allof)
4907 for (k = 0; k < seq->regexp.allof.regexps_num; k++)
4908 if (seq->regexp.allof.regexps [k]->mode == rm_unit
4909 && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
4912 if (k >= seq->regexp.allof.regexps_num)
4915 else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
4920 if (the_same_automaton_lists [cycle] == NULL)
4921 the_same_automaton_lists [cycle] = unit_decl;
4924 for (last = the_same_automaton_lists [cycle];;)
4926 if (last == unit_decl)
4928 if (last->the_same_automaton_unit
4929 == the_same_automaton_lists [cycle])
4931 last = last->the_same_automaton_unit;
4933 last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
4934 unit_decl->the_same_automaton_unit
4935 = the_same_automaton_lists [cycle];
4940 /* The function processes given REGEXP to find units which should be
4941 in the same automaton. */
4943 form_the_same_automaton_unit_lists_from_regexp (regexp)
4947 regexp_t seq, allof, unit;
4949 if (regexp == NULL || regexp->mode != rm_oneof)
4951 for (i = 0; i < description->max_insn_reserv_cycles; i++)
4952 the_same_automaton_lists [i] = NULL;
4953 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4955 seq = regexp->regexp.oneof.regexps [i];
4956 if (seq->mode == rm_sequence)
4957 for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
4959 allof = seq->regexp.sequence.regexps [j];
4960 if (allof->mode == rm_allof)
4961 for (k = 0; k < allof->regexp.allof.regexps_num; k++)
4963 unit = allof->regexp.allof.regexps [k];
4964 if (unit->mode == rm_unit)
4965 process_unit_to_form_the_same_automaton_unit_lists
4967 else if (unit->mode != rm_nothing)
4970 else if (allof->mode == rm_unit)
4971 process_unit_to_form_the_same_automaton_unit_lists
4973 else if (allof->mode != rm_nothing)
4976 else if (seq->mode == rm_allof)
4977 for (k = 0; k < seq->regexp.allof.regexps_num; k++)
4979 unit = seq->regexp.allof.regexps [k];
4980 if (unit->mode == rm_unit)
4981 process_unit_to_form_the_same_automaton_unit_lists
4983 else if (unit->mode != rm_nothing)
4986 else if (seq->mode == rm_unit)
4987 process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
4988 else if (seq->mode != rm_nothing)
4993 /* The function initializes data to search for units which should be
4994 in the same automaton and call function
4995 `form_the_same_automaton_unit_lists_from_regexp' for each insn
4996 reservation regexp. */
4998 form_the_same_automaton_unit_lists ()
5003 the_same_automaton_lists
5004 = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
5005 * sizeof (unit_decl_t));
5006 for (i = 0; i < description->decls_num; i++)
5008 decl = description->decls [i];
5009 if (decl->mode == dm_unit)
5011 decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
5012 decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
5015 for (i = 0; i < description->decls_num; i++)
5017 decl = description->decls [i];
5018 if (decl->mode == dm_insn_reserv)
5019 form_the_same_automaton_unit_lists_from_regexp
5020 (decl->decl.insn_reserv.transformed_regexp);
5022 free (the_same_automaton_lists);
5025 /* The function finds units which should be in the same automaton and,
5026 if they are not, reports about it. */
5028 check_unit_distributions_to_automata ()
5031 unit_decl_t start_unit_decl, unit_decl;
5034 form_the_same_automaton_unit_lists ();
5035 for (i = 0; i < description->decls_num; i++)
5037 decl = description->decls [i];
5038 if (decl->mode == dm_unit)
5040 start_unit_decl = &decl->decl.unit;
5041 if (!start_unit_decl->the_same_automaton_message_reported_p)
5042 for (unit_decl = start_unit_decl->the_same_automaton_unit;
5043 unit_decl != start_unit_decl;
5044 unit_decl = unit_decl->the_same_automaton_unit)
5045 if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
5047 error ("Units `%s' and `%s' should be in the same automaton",
5048 start_unit_decl->name, unit_decl->name);
5049 unit_decl->the_same_automaton_message_reported_p = TRUE;
5057 /* The page contains code for building alt_states (see comments for
5058 IR) describing all possible insns reservations of an automaton. */
5060 /* Current state being formed for which the current alt_state
5062 static state_t state_being_formed;
5064 /* Current alt_state being formed. */
5065 static alt_state_t alt_state_being_formed;
5067 /* This recursive function processes `,' and units in reservation
5068 REGEXP for forming alt_states of AUTOMATON. It is believed that
5069 CURR_CYCLE is start cycle of all reservation REGEXP. */
5071 process_seq_for_forming_states (regexp, automaton, curr_cycle)
5073 automaton_t automaton;
5080 else if (regexp->mode == rm_unit)
5082 if (regexp->regexp.unit.unit_decl->corresponding_automaton_num
5083 == automaton->automaton_order_num)
5084 set_state_reserv (state_being_formed, curr_cycle,
5085 regexp->regexp.unit.unit_decl->unit_num);
5088 else if (regexp->mode == rm_sequence)
5090 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
5092 = process_seq_for_forming_states
5093 (regexp->regexp.sequence.regexps [i], automaton, curr_cycle) + 1;
5096 else if (regexp->mode == rm_allof)
5098 int finish_cycle = 0;
5101 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
5104 = process_seq_for_forming_states (regexp->regexp.allof.regexps [i],
5105 automaton, curr_cycle);
5106 if (finish_cycle < cycle)
5107 finish_cycle = cycle;
5109 return finish_cycle;
5113 if (regexp->mode != rm_nothing)
5119 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5120 inserts alt_state into the table. */
5122 finish_forming_alt_state (alt_state, automaton)
5123 alt_state_t alt_state;
5124 automaton_t automaton ATTRIBUTE_UNUSED;
5126 state_t state_in_table;
5127 state_t corresponding_state;
5129 corresponding_state = alt_state->state;
5130 state_in_table = insert_state (corresponding_state);
5131 if (state_in_table != corresponding_state)
5133 free_state (corresponding_state);
5134 alt_state->state = state_in_table;
5138 /* The following variable value is current automaton insn for whose
5139 reservation the alt states are created. */
5140 static ainsn_t curr_ainsn;
5142 /* This recursive function processes `|' in reservation REGEXP for
5143 forming alt_states of AUTOMATON. List of the alt states should
5144 have the same order as in the description. */
5146 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
5148 automaton_t automaton;
5153 if (regexp->mode != rm_oneof)
5155 alt_state_being_formed = get_free_alt_state ();
5156 state_being_formed = get_free_state (1, automaton);
5157 alt_state_being_formed->state = state_being_formed;
5158 /* We inserts in reverse order but we process alternatives also
5159 in reverse order. So we have the same order of alternative
5160 as in the description. */
5161 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5162 curr_ainsn->alt_states = alt_state_being_formed;
5163 (void) process_seq_for_forming_states (regexp, automaton, 0);
5164 finish_forming_alt_state (alt_state_being_formed, automaton);
5170 /* We processes it in reverse order to get list with the same
5171 order as in the description. See also the previous
5173 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
5174 process_alts_for_forming_states (regexp->regexp.oneof.regexps [i],
5179 /* Create nodes alt_state for all AUTOMATON insns. */
5181 create_alt_states (automaton)
5182 automaton_t automaton;
5184 struct insn_reserv_decl *reserv_decl;
5186 for (curr_ainsn = automaton->ainsn_list;
5188 curr_ainsn = curr_ainsn->next_ainsn)
5190 reserv_decl = curr_ainsn->insn_reserv_decl;
5191 if (reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5193 curr_ainsn->alt_states = NULL;
5194 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5196 curr_ainsn->sorted_alt_states
5197 = uniq_sort_alt_states (curr_ainsn->alt_states);
5204 /* The page contains major code for building DFA(s) for fast pipeline
5205 hazards recognition. */
5207 /* The function forms list of ainsns of AUTOMATON with the same
5210 form_ainsn_with_same_reservs (automaton)
5211 automaton_t automaton;
5215 vla_ptr_t first_insns;
5216 vla_ptr_t last_insns;
5218 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5219 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5220 for (curr_ainsn = automaton->ainsn_list;
5222 curr_ainsn = curr_ainsn->next_ainsn)
5223 if (curr_ainsn->insn_reserv_decl
5224 == &advance_cycle_insn_decl->decl.insn_reserv)
5226 curr_ainsn->next_same_reservs_insn = NULL;
5227 curr_ainsn->first_insn_with_same_reservs = 1;
5231 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5233 (curr_ainsn->sorted_alt_states,
5234 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5236 curr_ainsn->next_same_reservs_insn = NULL;
5237 if (i < VLA_PTR_LENGTH (first_insns))
5239 curr_ainsn->first_insn_with_same_reservs = 0;
5240 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5242 VLA_PTR (last_insns, i) = curr_ainsn;
5246 VLA_PTR_ADD (first_insns, curr_ainsn);
5247 VLA_PTR_ADD (last_insns, curr_ainsn);
5248 curr_ainsn->first_insn_with_same_reservs = 1;
5251 VLA_PTR_DELETE (first_insns);
5252 VLA_PTR_DELETE (last_insns);
5255 /* The following function creates all states of nondeterministic (if
5256 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5258 make_automaton (automaton)
5259 automaton_t automaton;
5262 struct insn_reserv_decl *insn_reserv_decl;
5263 alt_state_t alt_state;
5265 state_t start_state;
5267 ainsn_t advance_cycle_ainsn;
5269 vla_ptr_t state_stack;
5271 VLA_PTR_CREATE (state_stack, 150, "state stack");
5272 /* Create the start state (empty state). */
5273 start_state = insert_state (get_free_state (1, automaton));
5274 automaton->start_state = start_state;
5275 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5276 VLA_PTR_ADD (state_stack, start_state);
5277 while (VLA_PTR_LENGTH (state_stack) != 0)
5279 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5280 VLA_PTR_SHORTEN (state_stack, 1);
5281 advance_cycle_ainsn = NULL;
5282 for (ainsn = automaton->ainsn_list;
5284 ainsn = ainsn->next_ainsn)
5285 if (ainsn->first_insn_with_same_reservs)
5287 insn_reserv_decl = ainsn->insn_reserv_decl;
5288 if (insn_reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5290 /* We process alt_states in the same order as they are
5291 present in the description. */
5293 for (alt_state = ainsn->alt_states;
5295 alt_state = alt_state->next_alt_state)
5297 state2 = alt_state->state;
5298 if (!intersected_state_reservs_p (state, state2))
5300 state2 = states_union (state, state2);
5301 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5303 state2->it_was_placed_in_stack_for_NDFA_forming
5305 VLA_PTR_ADD (state_stack, state2);
5307 added_arc = add_arc (state, state2, ainsn, 1);
5312 if (!ndfa_flag && added_arc != NULL)
5314 added_arc->state_alts = 0;
5315 for (alt_state = ainsn->alt_states;
5317 alt_state = alt_state->next_alt_state)
5319 state2 = alt_state->state;
5320 if (!intersected_state_reservs_p (state, state2))
5321 added_arc->state_alts++;
5326 advance_cycle_ainsn = ainsn;
5328 /* Add transition to advance cycle. */
5329 state2 = state_shift (state);
5330 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5332 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5333 VLA_PTR_ADD (state_stack, state2);
5335 if (advance_cycle_ainsn == NULL)
5337 add_arc (state, state2, advance_cycle_ainsn, 1);
5339 VLA_PTR_DELETE (state_stack);
5342 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5344 form_arcs_marked_by_insn (state)
5351 for (i = 0; i < description->decls_num; i++)
5353 decl = description->decls [i];
5354 if (decl->mode == dm_insn_reserv)
5355 decl->decl.insn_reserv.arcs_marked_by_insn = NULL;
5357 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5359 if (arc->insn == NULL)
5361 arc->next_arc_marked_by_insn
5362 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5363 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5367 /* The function creates composed state (see comments for IR) from
5368 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5369 same insn. If the composed state is not in STATE_STACK yet, it is
5370 popped to STATE_STACK. */
5372 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5373 state_t original_state;
5374 arc_t arcs_marked_by_insn;
5375 vla_ptr_t *state_stack;
5378 alt_state_t curr_alt_state;
5379 alt_state_t new_alt_state;
5382 state_t state_in_table;
5384 alt_state_t canonical_alt_states_list;
5387 if (arcs_marked_by_insn == NULL)
5389 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5390 state = arcs_marked_by_insn->to_state;
5395 /* Create composed state. */
5396 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5397 curr_alt_state = NULL;
5398 for (curr_arc = arcs_marked_by_insn;
5400 curr_arc = curr_arc->next_arc_marked_by_insn)
5402 new_alt_state = get_free_alt_state ();
5403 new_alt_state->next_alt_state = curr_alt_state;
5404 new_alt_state->state = curr_arc->to_state;
5405 if (curr_arc->to_state->component_states != NULL)
5407 curr_alt_state = new_alt_state;
5409 /* There are not identical sets in the alt state list. */
5410 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5411 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5414 state = canonical_alt_states_list->state;
5415 free_state (temp_state);
5419 state->component_states = canonical_alt_states_list;
5420 state_in_table = insert_state (state);
5421 if (state_in_table != state)
5423 if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5426 state = state_in_table;
5430 if (state->it_was_placed_in_stack_for_DFA_forming)
5432 for (curr_alt_state = state->component_states;
5433 curr_alt_state != NULL;
5434 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5435 for (curr_arc = first_out_arc (curr_alt_state->state);
5437 curr_arc = next_out_arc (curr_arc))
5438 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5440 arcs_marked_by_insn->to_state = state;
5441 for (alts_number = 0,
5442 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5444 curr_arc = next_arc)
5446 next_arc = curr_arc->next_arc_marked_by_insn;
5447 remove_arc (original_state, curr_arc);
5450 arcs_marked_by_insn->state_alts = alts_number;
5453 if (!state->it_was_placed_in_stack_for_DFA_forming)
5455 state->it_was_placed_in_stack_for_DFA_forming = 1;
5456 VLA_PTR_ADD (*state_stack, state);
5460 /* The function transformes nondeterminstic AUTOMATON into
5463 NDFA_to_DFA (automaton)
5464 automaton_t automaton;
5466 state_t start_state;
5469 vla_ptr_t state_stack;
5472 VLA_PTR_CREATE (state_stack, 150, "state stack");
5473 /* Create the start state (empty state). */
5474 start_state = automaton->start_state;
5475 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5476 VLA_PTR_ADD (state_stack, start_state);
5477 while (VLA_PTR_LENGTH (state_stack) != 0)
5479 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5480 VLA_PTR_SHORTEN (state_stack, 1);
5481 form_arcs_marked_by_insn (state);
5482 for (i = 0; i < description->decls_num; i++)
5484 decl = description->decls [i];
5485 if (decl->mode == dm_insn_reserv)
5486 create_composed_state
5487 (state, decl->decl.insn_reserv.arcs_marked_by_insn,
5491 VLA_PTR_DELETE (state_stack);
5494 /* The following variable value is current number (1, 2, ...) of passing
5496 static int curr_state_graph_pass_num;
5498 /* This recursive function passes all states achieved from START_STATE
5499 and applies APPLIED_FUNC to them. */
5501 pass_state_graph (start_state, applied_func)
5502 state_t start_state;
5503 void (*applied_func) PARAMS ((state_t state));
5507 if (start_state->pass_num == curr_state_graph_pass_num)
5509 start_state->pass_num = curr_state_graph_pass_num;
5510 (*applied_func) (start_state);
5511 for (arc = first_out_arc (start_state);
5513 arc = next_out_arc (arc))
5514 pass_state_graph (arc->to_state, applied_func);
5517 /* This recursive function passes all states of AUTOMATON and applies
5518 APPLIED_FUNC to them. */
5520 pass_states (automaton, applied_func)
5521 automaton_t automaton;
5522 void (*applied_func) PARAMS ((state_t state));
5524 curr_state_graph_pass_num++;
5525 pass_state_graph (automaton->start_state, applied_func);
5528 /* The function initializes code for passing of all states. */
5530 initiate_pass_states ()
5532 curr_state_graph_pass_num = 0;
5535 /* The following vla is used for storing pointers to all achieved
5537 static vla_ptr_t all_achieved_states;
5539 /* This function is called by function pass_states to add an achieved
5542 add_achieved_state (state)
5545 VLA_PTR_ADD (all_achieved_states, state);
5548 /* The function sets up equivalence numbers of insns which mark all
5549 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5550 nonzero value) or by equiv_class_num_2 of the destination state.
5551 The function returns number of out arcs of STATE. */
5553 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
5555 int odd_iteration_flag;
5557 int state_out_arcs_num;
5560 state_out_arcs_num = 0;
5561 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5563 if (arc->insn->insn_reserv_decl->equiv_class_num != 0
5564 || arc->insn->insn_reserv_decl->state_alts != 0)
5566 state_out_arcs_num++;
5567 arc->insn->insn_reserv_decl->equiv_class_num
5568 = (odd_iteration_flag
5569 ? arc->to_state->equiv_class_num_1
5570 : arc->to_state->equiv_class_num_2);
5571 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5572 if (arc->insn->insn_reserv_decl->equiv_class_num == 0
5573 || arc->insn->insn_reserv_decl->state_alts <= 0)
5576 return state_out_arcs_num;
5579 /* The function clears equivalence numbers and alt_states in all insns
5580 which mark all out arcs of STATE. */
5582 clear_arc_insns_equiv_num (state)
5587 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5589 arc->insn->insn_reserv_decl->equiv_class_num = 0;
5590 arc->insn->insn_reserv_decl->state_alts = 0;
5594 /* The function copies pointers to equivalent states from vla FROM
5597 copy_equiv_class (to, from)
5599 const vla_ptr_t *from;
5603 VLA_PTR_NULLIFY (*to);
5604 for (class_ptr = VLA_PTR_BEGIN (*from);
5605 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
5607 VLA_PTR_ADD (*to, *class_ptr);
5610 /* The function returns nonzero value if STATE is not equivalent to
5611 another state from the same current partition on equivalence
5612 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5613 output arcs. Iteration of making equivalence partition is defined
5614 by ODD_ITERATION_FLAG. */
5616 state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
5618 int original_state_out_arcs_num;
5619 int odd_iteration_flag;
5622 int state_out_arcs_num;
5624 state_out_arcs_num = 0;
5625 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5627 state_out_arcs_num++;
5628 if ((odd_iteration_flag
5629 ? arc->to_state->equiv_class_num_1
5630 : arc->to_state->equiv_class_num_2)
5631 != arc->insn->insn_reserv_decl->equiv_class_num
5632 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
5635 return state_out_arcs_num != original_state_out_arcs_num;
5638 /* The function makes initial partition of STATES on equivalent
5641 init_equiv_class (states, states_num)
5646 state_t result_equiv_class;
5648 result_equiv_class = NULL;
5649 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
5651 (*state_ptr)->equiv_class_num_1 = 1;
5652 (*state_ptr)->next_equiv_class_state = result_equiv_class;
5653 result_equiv_class = *state_ptr;
5655 return result_equiv_class;
5658 /* The function processes equivalence class given by its pointer
5659 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5660 are not equvalent states, the function partitions the class
5661 removing nonequivalent states and placing them in
5662 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5663 assigns it to the state equivalence number. If the class has been
5664 partitioned, the function returns nonzero value. */
5666 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5667 next_iteration_classes, new_equiv_class_num_ptr)
5668 state_t *equiv_class_ptr;
5669 int odd_iteration_flag;
5670 vla_ptr_t *next_iteration_classes;
5671 int *new_equiv_class_num_ptr;
5673 state_t new_equiv_class;
5675 state_t first_state;
5682 if (*equiv_class_ptr == NULL)
5684 for (first_state = *equiv_class_ptr;
5685 first_state != NULL;
5686 first_state = new_equiv_class)
5688 new_equiv_class = NULL;
5689 if (first_state->next_equiv_class_state != NULL)
5691 /* There are more one states in the class equivalence. */
5692 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
5693 odd_iteration_flag);
5694 for (prev_state = first_state,
5695 curr_state = first_state->next_equiv_class_state;
5697 curr_state = next_state)
5699 next_state = curr_state->next_equiv_class_state;
5700 if (state_is_differed (curr_state, out_arcs_num,
5701 odd_iteration_flag))
5703 /* Remove curr state from the class equivalence. */
5704 prev_state->next_equiv_class_state = next_state;
5705 /* Add curr state to the new class equivalence. */
5706 curr_state->next_equiv_class_state = new_equiv_class;
5707 if (new_equiv_class == NULL)
5708 (*new_equiv_class_num_ptr)++;
5709 if (odd_iteration_flag)
5710 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5712 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5713 new_equiv_class = curr_state;
5717 prev_state = curr_state;
5719 clear_arc_insns_equiv_num (first_state);
5721 if (new_equiv_class != NULL)
5722 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
5727 /* The function finds equivalent states of AUTOMATON. */
5729 evaluate_equiv_classes (automaton, equiv_classes)
5730 automaton_t automaton;
5731 vla_ptr_t *equiv_classes;
5733 state_t new_equiv_class;
5734 int new_equiv_class_num;
5735 int odd_iteration_flag;
5737 vla_ptr_t next_iteration_classes;
5738 state_t *equiv_class_ptr;
5741 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
5742 pass_states (automaton, add_achieved_state);
5743 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
5744 VLA_PTR_LENGTH (all_achieved_states));
5745 odd_iteration_flag = 0;
5746 new_equiv_class_num = 1;
5747 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
5748 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
5751 odd_iteration_flag = !odd_iteration_flag;
5753 copy_equiv_class (equiv_classes, &next_iteration_classes);
5754 /* Transfer equiv numbers for the next iteration. */
5755 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
5756 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
5758 if (odd_iteration_flag)
5759 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
5761 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
5762 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5763 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5765 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5766 &next_iteration_classes,
5767 &new_equiv_class_num))
5770 while (!finish_flag);
5771 VLA_PTR_DELETE (next_iteration_classes);
5772 VLA_PTR_DELETE (all_achieved_states);
5775 /* The function merges equivalent states of AUTOMATON. */
5777 merge_states (automaton, equiv_classes)
5778 automaton_t automaton;
5779 vla_ptr_t *equiv_classes;
5781 state_t *equiv_class_ptr;
5784 state_t first_class_state;
5785 alt_state_t alt_states;
5786 alt_state_t new_alt_state;
5790 /* Create states corresponding to equivalence classes containing two
5792 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5793 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5795 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5797 /* There are more one states in the class equivalence. */
5798 /* Create new compound state. */
5799 new_state = get_free_state (0, automaton);
5801 first_class_state = *equiv_class_ptr;
5802 for (curr_state = first_class_state;
5804 curr_state = curr_state->next_equiv_class_state)
5806 curr_state->equiv_class_state = new_state;
5807 new_alt_state = get_free_alt_state ();
5808 new_alt_state->state = curr_state;
5809 new_alt_state->next_sorted_alt_state = alt_states;
5810 alt_states = new_alt_state;
5812 new_state->component_states = alt_states;
5815 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
5816 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5817 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5819 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5821 first_class_state = *equiv_class_ptr;
5822 /* Create new arcs output from the state corresponding to
5824 for (curr_arc = first_out_arc (first_class_state);
5826 curr_arc = next_out_arc (curr_arc))
5827 add_arc (first_class_state->equiv_class_state,
5828 curr_arc->to_state->equiv_class_state,
5829 curr_arc->insn, curr_arc->state_alts);
5830 /* Delete output arcs from states of given class equivalence. */
5831 for (curr_state = first_class_state;
5833 curr_state = curr_state->next_equiv_class_state)
5835 if (automaton->start_state == curr_state)
5836 automaton->start_state = curr_state->equiv_class_state;
5837 /* Delete the state and its output arcs. */
5838 for (curr_arc = first_out_arc (curr_state);
5840 curr_arc = next_arc)
5842 next_arc = next_out_arc (curr_arc);
5843 free_arc (curr_arc);
5849 /* Change `to_state' of arcs output from the state of given
5850 equivalence class. */
5851 for (curr_arc = first_out_arc (*equiv_class_ptr);
5853 curr_arc = next_out_arc (curr_arc))
5854 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
5858 /* The function sets up new_cycle_p for states if there is arc to the
5859 state marked by advance_cycle_insn_decl. */
5861 set_new_cycle_flags (state)
5866 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5867 if (arc->insn->insn_reserv_decl
5868 == &advance_cycle_insn_decl->decl.insn_reserv)
5869 arc->to_state->new_cycle_p = 1;
5872 /* The top level function for minimization of deterministic
5875 minimize_DFA (automaton)
5876 automaton_t automaton;
5878 vla_ptr_t equiv_classes;
5880 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
5881 evaluate_equiv_classes (automaton, &equiv_classes);
5882 merge_states (automaton, &equiv_classes);
5883 pass_states (automaton, set_new_cycle_flags);
5884 VLA_PTR_DELETE (equiv_classes);
5887 /* Values of two variables are counted number of states and arcs in an
5889 static int curr_counted_states_num;
5890 static int curr_counted_arcs_num;
5892 /* The function is called by function `pass_states' to count states
5893 and arcs of an automaton. */
5895 incr_states_and_arcs_nums (state)
5900 curr_counted_states_num++;
5901 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5902 curr_counted_arcs_num++;
5905 /* The function counts states and arcs of AUTOMATON. */
5907 count_states_and_arcs (automaton, states_num, arcs_num)
5908 automaton_t automaton;
5912 curr_counted_states_num = 0;
5913 curr_counted_arcs_num = 0;
5914 pass_states (automaton, incr_states_and_arcs_nums);
5915 *states_num = curr_counted_states_num;
5916 *arcs_num = curr_counted_arcs_num;
5919 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5920 recognition after checking and simplifying IR of the
5923 build_automaton (automaton)
5924 automaton_t automaton;
5929 ticker_on (&NDFA_time);
5930 make_automaton (automaton);
5931 ticker_off (&NDFA_time);
5932 count_states_and_arcs (automaton, &states_num, &arcs_num);
5933 automaton->NDFA_states_num = states_num;
5934 automaton->NDFA_arcs_num = arcs_num;
5935 ticker_on (&NDFA_to_DFA_time);
5936 NDFA_to_DFA (automaton);
5937 ticker_off (&NDFA_to_DFA_time);
5938 count_states_and_arcs (automaton, &states_num, &arcs_num);
5939 automaton->DFA_states_num = states_num;
5940 automaton->DFA_arcs_num = arcs_num;
5941 if (!no_minimization_flag)
5943 ticker_on (&minimize_time);
5944 minimize_DFA (automaton);
5945 ticker_off (&minimize_time);
5946 count_states_and_arcs (automaton, &states_num, &arcs_num);
5947 automaton->minimal_DFA_states_num = states_num;
5948 automaton->minimal_DFA_arcs_num = arcs_num;
5954 /* The page contains code for enumeration of all states of an automaton. */
5956 /* Variable used for enumeration of all states of an automaton. Its
5957 value is current number of automaton states. */
5958 static int curr_state_order_num;
5960 /* The function is called by function `pass_states' for enumerating
5963 set_order_state_num (state)
5966 state->order_state_num = curr_state_order_num;
5967 curr_state_order_num++;
5970 /* The function enumerates all states of AUTOMATON. */
5972 enumerate_states (automaton)
5973 automaton_t automaton;
5975 curr_state_order_num = 0;
5976 pass_states (automaton, set_order_state_num);
5977 automaton->achieved_states_num = curr_state_order_num;
5982 /* The page contains code for finding equivalent automaton insns
5985 /* The function inserts AINSN into cyclic list
5986 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
5988 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
5990 ainsn_t cyclic_equiv_class_insn_list;
5992 if (cyclic_equiv_class_insn_list == NULL)
5993 ainsn->next_equiv_class_insn = ainsn;
5996 ainsn->next_equiv_class_insn
5997 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
5998 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6003 /* The function deletes equiv_class_insn into cyclic list of
6004 equivalent ainsns. */
6006 delete_ainsn_from_equiv_class (equiv_class_insn)
6007 ainsn_t equiv_class_insn;
6009 ainsn_t curr_equiv_class_insn;
6010 ainsn_t prev_equiv_class_insn;
6012 prev_equiv_class_insn = equiv_class_insn;
6013 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6014 curr_equiv_class_insn != equiv_class_insn;
6015 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6016 prev_equiv_class_insn = curr_equiv_class_insn;
6017 if (prev_equiv_class_insn != equiv_class_insn)
6018 prev_equiv_class_insn->next_equiv_class_insn
6019 = equiv_class_insn->next_equiv_class_insn;
6022 /* The function processes AINSN of a state in order to find equivalent
6023 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6026 process_insn_equiv_class (ainsn, insn_arcs_array)
6028 arc_t *insn_arcs_array;
6032 ainsn_t cyclic_insn_list;
6035 if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
6038 /* New class of ainsns which are not equivalent to given ainsn. */
6039 cyclic_insn_list = NULL;
6042 next_insn = curr_insn->next_equiv_class_insn;
6043 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6045 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6048 delete_ainsn_from_equiv_class (curr_insn);
6049 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6052 curr_insn = next_insn;
6054 while (curr_insn != ainsn);
6057 /* The function processes STATE in order to find equivalent ainsns. */
6059 process_state_for_insn_equiv_partition (state)
6063 arc_t *insn_arcs_array;
6065 vla_ptr_t insn_arcs_vect;
6067 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6068 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6069 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6070 /* Process insns of the arcs. */
6071 for (i = 0; i < description->insns_num; i++)
6072 insn_arcs_array [i] = NULL;
6073 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6074 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6075 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6076 process_insn_equiv_class (arc->insn, insn_arcs_array);
6077 VLA_PTR_DELETE (insn_arcs_vect);
6080 /* The function searches for equivalent ainsns of AUTOMATON. */
6082 set_insn_equiv_classes (automaton)
6083 automaton_t automaton;
6088 ainsn_t cyclic_insn_list;
6089 ainsn_t insn_with_same_reservs;
6090 int equiv_classes_num;
6092 /* All insns are included in one equivalence class. */
6093 cyclic_insn_list = NULL;
6094 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6095 if (ainsn->first_insn_with_same_reservs)
6096 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6098 /* Process insns in order to make equivalence partition. */
6099 pass_states (automaton, process_state_for_insn_equiv_partition);
6100 /* Enumerate equiv classes. */
6101 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6102 /* Set undefined value. */
6103 ainsn->insn_equiv_class_num = -1;
6104 equiv_classes_num = 0;
6105 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6106 if (ainsn->insn_equiv_class_num < 0)
6109 if (!first_insn->first_insn_with_same_reservs)
6111 first_insn->first_ainsn_with_given_equialence_num = 1;
6112 curr_insn = first_insn;
6115 for (insn_with_same_reservs = curr_insn;
6116 insn_with_same_reservs != NULL;
6117 insn_with_same_reservs
6118 = insn_with_same_reservs->next_same_reservs_insn)
6119 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6120 curr_insn = curr_insn->next_equiv_class_insn;
6122 while (curr_insn != first_insn);
6123 equiv_classes_num++;
6125 automaton->insn_equiv_classes_num = equiv_classes_num;
6130 /* This page contains code for creating DFA(s) and calls functions
6134 /* The following value is used to prevent floating point overflow for
6135 estimating an automaton bound. The value should be less DBL_MAX on
6136 the host machine. We use here approximate minimum of maximal
6137 double floating point value required by ANSI C standard. It
6138 will work for non ANSI sun compiler too. */
6140 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6142 /* The function estimate size of the single DFA used by PHR (pipeline
6143 hazards recognizer). */
6145 estimate_one_automaton_bound ()
6148 double one_automaton_estimation_bound;
6152 one_automaton_estimation_bound = 1.0;
6153 for (i = 0; i < description->decls_num; i++)
6155 decl = description->decls [i];
6156 if (decl->mode == dm_unit)
6158 root_value = exp (log (decl->decl.unit.max_occ_cycle_num + 1.0)
6160 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6161 > one_automaton_estimation_bound)
6162 one_automaton_estimation_bound *= root_value;
6165 return one_automaton_estimation_bound;
6168 /* The function compares unit declarations acoording to their maximal
6169 cycle in reservations. */
6171 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
6172 const void *unit_decl_1;
6173 const void *unit_decl_2;
6175 if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6176 < ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6178 else if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6179 == ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6185 /* The function makes heuristic assigning automata to units. Actually
6186 efficacy of the algorithm has been checked yet??? */
6188 units_to_automata_heuristic_distr ()
6190 double estimation_bound;
6192 decl_t *unit_decl_ptr;
6196 vla_ptr_t unit_decls;
6199 if (description->units_num == 0)
6201 estimation_bound = estimate_one_automaton_bound ();
6202 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6203 for (i = 0; i < description->decls_num; i++)
6205 decl = description->decls [i];
6206 if (decl->mode == dm_unit)
6207 VLA_PTR_ADD (unit_decls, decl);
6209 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6210 sizeof (decl_t), compare_max_occ_cycle_nums);
6212 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6213 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6214 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6215 for (unit_decl_ptr++;
6216 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6220 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6221 if (automata_num - automaton_num - 1 > rest_units_num)
6223 if (automaton_num < automata_num - 1
6224 && ((automata_num - automaton_num - 1 == rest_units_num)
6227 / ((*unit_decl_ptr)->decl.unit.max_occ_cycle_num)))))
6229 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6233 bound_value *= (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6234 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6236 if (automaton_num != automata_num - 1)
6238 VLA_PTR_DELETE (unit_decls);
6241 /* The functions creates automaton insns for each automata. Automaton
6242 insn is simply insn for given automaton which makes reservation
6243 only of units of the automaton. */
6248 ainsn_t first_ainsn;
6255 for (i = 0; i < description->decls_num; i++)
6257 decl = description->decls [i];
6258 if (decl->mode == dm_insn_reserv)
6260 curr_ainsn = create_node (sizeof (struct ainsn));
6261 curr_ainsn->insn_reserv_decl = &decl->decl.insn_reserv;
6262 curr_ainsn->important_p = FALSE;
6263 curr_ainsn->next_ainsn = NULL;
6264 if (prev_ainsn == NULL)
6265 first_ainsn = curr_ainsn;
6267 prev_ainsn->next_ainsn = curr_ainsn;
6268 prev_ainsn = curr_ainsn;
6274 /* The function assigns automata to units according to constructions
6275 `define_automaton' in the description. */
6277 units_to_automata_distr ()
6282 for (i = 0; i < description->decls_num; i++)
6284 decl = description->decls [i];
6285 if (decl->mode == dm_unit)
6287 if (decl->decl.unit.automaton_decl == NULL
6288 || (decl->decl.unit.automaton_decl->corresponding_automaton
6290 /* Distribute to the first automaton. */
6291 decl->decl.unit.corresponding_automaton_num = 0;
6293 decl->decl.unit.corresponding_automaton_num
6294 = (decl->decl.unit.automaton_decl
6295 ->corresponding_automaton->automaton_order_num);
6300 /* The function creates DFA(s) for fast pipeline hazards recognition
6301 after checking and simplifying IR of the description. */
6305 automaton_t curr_automaton;
6306 automaton_t prev_automaton;
6308 int curr_automaton_num;
6311 if (automata_num != 0)
6313 units_to_automata_heuristic_distr ();
6314 for (prev_automaton = NULL, curr_automaton_num = 0;
6315 curr_automaton_num < automata_num;
6316 curr_automaton_num++, prev_automaton = curr_automaton)
6318 curr_automaton = create_node (sizeof (struct automaton));
6319 curr_automaton->ainsn_list = create_ainsns ();
6320 curr_automaton->corresponding_automaton_decl = NULL;
6321 curr_automaton->next_automaton = NULL;
6322 curr_automaton->automaton_order_num = curr_automaton_num;
6323 if (prev_automaton == NULL)
6324 description->first_automaton = curr_automaton;
6326 prev_automaton->next_automaton = curr_automaton;
6331 curr_automaton_num = 0;
6332 prev_automaton = NULL;
6333 for (i = 0; i < description->decls_num; i++)
6335 decl = description->decls [i];
6336 if (decl->mode == dm_automaton
6337 && decl->decl.automaton.automaton_is_used)
6339 curr_automaton = create_node (sizeof (struct automaton));
6340 curr_automaton->ainsn_list = create_ainsns ();
6341 curr_automaton->corresponding_automaton_decl
6342 = &decl->decl.automaton;
6343 curr_automaton->next_automaton = NULL;
6344 decl->decl.automaton.corresponding_automaton = curr_automaton;
6345 curr_automaton->automaton_order_num = curr_automaton_num;
6346 if (prev_automaton == NULL)
6347 description->first_automaton = curr_automaton;
6349 prev_automaton->next_automaton = curr_automaton;
6350 curr_automaton_num++;
6351 prev_automaton = curr_automaton;
6354 if (curr_automaton_num == 0)
6356 curr_automaton = create_node (sizeof (struct automaton));
6357 curr_automaton->ainsn_list = create_ainsns ();
6358 curr_automaton->corresponding_automaton_decl = NULL;
6359 curr_automaton->next_automaton = NULL;
6360 description->first_automaton = curr_automaton;
6362 units_to_automata_distr ();
6364 NDFA_time = create_ticker ();
6365 ticker_off (&NDFA_time);
6366 NDFA_to_DFA_time = create_ticker ();
6367 ticker_off (&NDFA_to_DFA_time);
6368 minimize_time = create_ticker ();
6369 ticker_off (&minimize_time);
6370 equiv_time = create_ticker ();
6371 ticker_off (&equiv_time);
6372 for (curr_automaton = description->first_automaton;
6373 curr_automaton != NULL;
6374 curr_automaton = curr_automaton->next_automaton)
6376 if (curr_automaton->corresponding_automaton_decl == NULL)
6377 fprintf (stderr, "Create anonymous automaton ...");
6379 fprintf (stderr, "Create automaton `%s'...",
6380 curr_automaton->corresponding_automaton_decl->name);
6381 create_alt_states (curr_automaton);
6382 form_ainsn_with_same_reservs (curr_automaton);
6383 build_automaton (curr_automaton);
6384 enumerate_states (curr_automaton);
6385 ticker_on (&equiv_time);
6386 set_insn_equiv_classes (curr_automaton);
6387 ticker_off (&equiv_time);
6388 fprintf (stderr, "done\n");
6394 /* This page contains code for forming string representation of
6395 regexp. The representation is formed on IR obstack. So you should
6396 not work with IR obstack between regexp_representation and
6397 finish_regexp_representation calls. */
6399 /* This recursive function forms string representation of regexp
6400 (without tailing '\0'). */
6402 form_regexp (regexp)
6407 if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6409 const char *name = (regexp->mode == rm_unit
6410 ? regexp->regexp.unit.name
6411 : regexp->regexp.reserv.name);
6413 obstack_grow (&irp, name, strlen (name));
6415 else if (regexp->mode == rm_sequence)
6416 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
6419 obstack_1grow (&irp, ',');
6420 form_regexp (regexp->regexp.sequence.regexps [i]);
6422 else if (regexp->mode == rm_allof)
6424 obstack_1grow (&irp, '(');
6425 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
6428 obstack_1grow (&irp, '+');
6429 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6430 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6431 obstack_1grow (&irp, '(');
6432 form_regexp (regexp->regexp.allof.regexps [i]);
6433 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6434 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6435 obstack_1grow (&irp, ')');
6437 obstack_1grow (&irp, ')');
6439 else if (regexp->mode == rm_oneof)
6440 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
6443 obstack_1grow (&irp, '|');
6444 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6445 obstack_1grow (&irp, '(');
6446 form_regexp (regexp->regexp.oneof.regexps [i]);
6447 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6448 obstack_1grow (&irp, ')');
6450 else if (regexp->mode == rm_repeat)
6454 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6455 || regexp->regexp.repeat.regexp->mode == rm_allof
6456 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6457 obstack_1grow (&irp, '(');
6458 form_regexp (regexp->regexp.repeat.regexp);
6459 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6460 || regexp->regexp.repeat.regexp->mode == rm_allof
6461 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6462 obstack_1grow (&irp, ')');
6463 sprintf (digits, "*%d", regexp->regexp.repeat.repeat_num);
6464 obstack_grow (&irp, digits, strlen (digits));
6466 else if (regexp->mode == rm_nothing)
6467 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6472 /* The function returns string representation of REGEXP on IR
6475 regexp_representation (regexp)
6478 form_regexp (regexp);
6479 obstack_1grow (&irp, '\0');
6480 return obstack_base (&irp);
6483 /* The function frees memory allocated for last formed string
6484 representation of regexp. */
6486 finish_regexp_representation ()
6488 int length = obstack_object_size (&irp);
6490 obstack_blank_fast (&irp, -length);
6495 /* This page contains code for output PHR (pipeline hazards recognizer). */
6497 /* The function outputs minimal C type which is sufficient for
6498 representation numbers in range min_range_value and
6499 max_range_value. Because host machine and build machine may be
6500 different, we use here minimal values required by ANSI C standard
6501 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6505 output_range_type (f, min_range_value, max_range_value)
6507 long int min_range_value;
6508 long int max_range_value;
6510 if (min_range_value >= 0 && max_range_value <= 255)
6511 fprintf (f, "unsigned char");
6512 else if (min_range_value >= -127 && max_range_value <= 127)
6513 fprintf (f, "signed char");
6514 else if (min_range_value >= 0 && max_range_value <= 65535)
6515 fprintf (f, "unsigned short");
6516 else if (min_range_value >= -32767 && max_range_value <= 32767)
6517 fprintf (f, "short");
6522 /* The following macro value is used as value of member
6523 `longest_path_length' of state when we are processing path and the
6524 state on the path. */
6526 #define ON_THE_PATH -2
6528 /* The following recursive function searches for the length of the
6529 longest path starting from STATE which does not contain cycles and
6530 `cycle advance' arcs. */
6533 longest_path_length (state)
6539 if (state->longest_path_length == ON_THE_PATH)
6540 /* We don't expect the path cycle here. Our graph may contain
6541 only cycles with one state on the path not containing `cycle
6542 advance' arcs -- see comment below. */
6544 else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6545 /* We alreday visited the state. */
6546 return state->longest_path_length;
6549 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6550 /* Ignore cycles containing one state and `cycle advance' arcs. */
6551 if (arc->to_state != state
6552 && (arc->insn->insn_reserv_decl
6553 != &advance_cycle_insn_decl->decl.insn_reserv))
6555 length = longest_path_length (arc->to_state);
6556 if (length > result)
6559 state->longest_path_length = result + 1;
6563 /* The following variable value is value of the corresponding global
6564 variable in the automaton based pipeline interface. */
6566 static int max_dfa_issue_rate;
6568 /* The following function processes the longest path length staring
6569 from STATE to find MAX_DFA_ISSUE_RATE. */
6572 process_state_longest_path_length (state)
6577 value = longest_path_length (state);
6578 if (value > max_dfa_issue_rate)
6579 max_dfa_issue_rate = value;
6582 /* The following nacro value is name of the corresponding global
6583 variable in the automaton based pipeline interface. */
6585 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6587 /* The following function calculates value of the the corresponding
6588 global variable and outputs its declaration. */
6591 output_dfa_max_issue_rate ()
6593 automaton_t automaton;
6595 if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
6597 max_dfa_issue_rate = 0;
6598 for (automaton = description->first_automaton;
6600 automaton = automaton->next_automaton)
6601 pass_states (automaton, process_state_longest_path_length);
6602 fprintf (output_file, "\nint %s = %d;\n",
6603 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
6606 /* The function outputs all initialization values of VECT with length
6609 output_vect (vect, vect_length)
6616 if (vect_length == 0)
6617 fprintf (output_file,
6618 "0 /* This is dummy el because the vect is empty */");
6623 fprintf (output_file, "%5ld", (long) *vect);
6625 if (els_on_line == 10)
6628 fprintf (output_file, ",\n");
6630 else if (vect_length != 0)
6631 fprintf (output_file, ", ");
6635 while (vect_length != 0);
6639 /* The following is name of the structure which represents DFA(s) for
6641 #define CHIP_NAME "DFA_chip"
6643 /* The following is name of member which represents state of a DFA for
6646 output_chip_member_name (f, automaton)
6648 automaton_t automaton;
6650 if (automaton->corresponding_automaton_decl == NULL)
6651 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6653 fprintf (f, "%s_automaton_state",
6654 automaton->corresponding_automaton_decl->name);
6657 /* The following is name of temporary variable which stores state of a
6660 output_temp_chip_member_name (f, automaton)
6662 automaton_t automaton;
6665 output_chip_member_name (f, automaton);
6668 /* This is name of macro value which is code of pseudo_insn
6669 representing advancing cpu cycle. Its value is used as internal
6670 code unknown insn. */
6671 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6673 /* Output name of translate vector for given automaton. */
6675 output_translate_vect_name (f, automaton)
6677 automaton_t automaton;
6679 if (automaton->corresponding_automaton_decl == NULL)
6680 fprintf (f, "translate_%d", automaton->automaton_order_num);
6682 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6685 /* Output name for simple transition table representation. */
6687 output_trans_full_vect_name (f, automaton)
6689 automaton_t automaton;
6691 if (automaton->corresponding_automaton_decl == NULL)
6692 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6694 fprintf (f, "%s_transitions",
6695 automaton->corresponding_automaton_decl->name);
6698 /* Output name of comb vector of the transition table for given
6701 output_trans_comb_vect_name (f, automaton)
6703 automaton_t automaton;
6705 if (automaton->corresponding_automaton_decl == NULL)
6706 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6708 fprintf (f, "%s_transitions",
6709 automaton->corresponding_automaton_decl->name);
6712 /* Output name of check vector of the transition table for given
6715 output_trans_check_vect_name (f, automaton)
6717 automaton_t automaton;
6719 if (automaton->corresponding_automaton_decl == NULL)
6720 fprintf (f, "check_%d", automaton->automaton_order_num);
6722 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6725 /* Output name of base vector of the transition table for given
6728 output_trans_base_vect_name (f, automaton)
6730 automaton_t automaton;
6732 if (automaton->corresponding_automaton_decl == NULL)
6733 fprintf (f, "base_%d", automaton->automaton_order_num);
6735 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6738 /* Output name for simple alternatives number representation. */
6740 output_state_alts_full_vect_name (f, automaton)
6742 automaton_t automaton;
6744 if (automaton->corresponding_automaton_decl == NULL)
6745 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6747 fprintf (f, "%s_state_alts",
6748 automaton->corresponding_automaton_decl->name);
6751 /* Output name of comb vector of the alternatives number table for given
6754 output_state_alts_comb_vect_name (f, automaton)
6756 automaton_t automaton;
6758 if (automaton->corresponding_automaton_decl == NULL)
6759 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6761 fprintf (f, "%s_state_alts",
6762 automaton->corresponding_automaton_decl->name);
6765 /* Output name of check vector of the alternatives number table for given
6768 output_state_alts_check_vect_name (f, automaton)
6770 automaton_t automaton;
6772 if (automaton->corresponding_automaton_decl == NULL)
6773 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
6775 fprintf (f, "%s_check_state_alts",
6776 automaton->corresponding_automaton_decl->name);
6779 /* Output name of base vector of the alternatives number table for given
6782 output_state_alts_base_vect_name (f, automaton)
6784 automaton_t automaton;
6786 if (automaton->corresponding_automaton_decl == NULL)
6787 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
6789 fprintf (f, "%s_base_state_alts",
6790 automaton->corresponding_automaton_decl->name);
6793 /* Output name of simple min issue delay table representation. */
6795 output_min_issue_delay_vect_name (f, automaton)
6797 automaton_t automaton;
6799 if (automaton->corresponding_automaton_decl == NULL)
6800 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6802 fprintf (f, "%s_min_issue_delay",
6803 automaton->corresponding_automaton_decl->name);
6806 /* Output name of deadlock vector for given automaton. */
6808 output_dead_lock_vect_name (f, automaton)
6810 automaton_t automaton;
6812 if (automaton->corresponding_automaton_decl == NULL)
6813 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6815 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6818 /* Output name of reserved units table for AUTOMATON into file F. */
6820 output_reserved_units_table_name (f, automaton)
6822 automaton_t automaton;
6824 if (automaton->corresponding_automaton_decl == NULL)
6825 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6827 fprintf (f, "%s_reserved_units",
6828 automaton->corresponding_automaton_decl->name);
6831 /* Name of the PHR interface macro. */
6832 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6834 /* Name of the PHR interface macro. */
6835 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6837 /* Names of an internal functions: */
6838 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6840 /* This is external type of DFA(s) state. */
6841 #define STATE_TYPE_NAME "state_t"
6843 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6845 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6847 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6849 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6851 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6853 /* Name of cache of insn dfa codes. */
6854 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6856 /* Name of length of cache of insn dfa codes. */
6857 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6859 /* Names of the PHR interface functions: */
6860 #define SIZE_FUNC_NAME "state_size"
6862 #define TRANSITION_FUNC_NAME "state_transition"
6864 #define STATE_ALTS_FUNC_NAME "state_alts"
6866 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6868 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6870 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6872 #define RESET_FUNC_NAME "state_reset"
6874 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6876 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6878 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6880 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6882 #define DFA_START_FUNC_NAME "dfa_start"
6884 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6886 /* Names of parameters of the PHR interface functions. */
6887 #define STATE_NAME "state"
6889 #define INSN_PARAMETER_NAME "insn"
6891 #define INSN2_PARAMETER_NAME "insn2"
6893 #define CHIP_PARAMETER_NAME "chip"
6895 #define FILE_PARAMETER_NAME "f"
6897 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6899 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6901 /* Names of the variables whose values are internal insn code of rtx
6903 #define INTERNAL_INSN_CODE_NAME "insn_code"
6905 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6907 /* Names of temporary variables in some functions. */
6908 #define TEMPORARY_VARIABLE_NAME "temp"
6910 #define I_VARIABLE_NAME "i"
6912 /* Name of result variable in some functions. */
6913 #define RESULT_VARIABLE_NAME "res"
6915 /* Name of function (attribute) to translate insn into number of insn
6916 alternatives reservation. */
6917 #define INSN_ALTS_FUNC_NAME "insn_alts"
6919 /* Name of function (attribute) to translate insn into internal insn
6921 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6923 /* Name of function (attribute) to translate insn into internal insn
6924 code with caching. */
6925 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6927 /* Name of function (attribute) to translate insn into internal insn
6929 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6931 /* Name of function (attribute) to translate insn into internal insn
6933 #define BYPASS_P_FUNC_NAME "bypass_p"
6935 /* Output C type which is used for representation of codes of states
6938 output_state_member_type (f, automaton)
6940 automaton_t automaton;
6942 output_range_type (f, 0, automaton->achieved_states_num);
6945 /* Output definition of the structure representing current DFA(s)
6948 output_chip_definitions ()
6950 automaton_t automaton;
6952 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
6953 for (automaton = description->first_automaton;
6955 automaton = automaton->next_automaton)
6957 fprintf (output_file, " ");
6958 output_state_member_type (output_file, automaton);
6959 fprintf (output_file, " ");
6960 output_chip_member_name (output_file, automaton);
6961 fprintf (output_file, ";\n");
6963 fprintf (output_file, "};\n\n");
6965 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
6970 /* The function outputs translate vector of internal insn code into
6971 insn equivalence class number. The equivalence class number is
6972 used to access to table and vectors reprewsenting DFA(s). */
6974 output_translate_vect (automaton)
6975 automaton_t automaton;
6979 vla_hwint_t translate_vect;
6981 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
6982 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
6983 for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
6984 /* Undefined value */
6985 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
6986 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6987 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
6988 = ainsn->insn_equiv_class_num;
6989 fprintf (output_file,
6990 "/* Vector translating external insn codes to internal ones.*/\n");
6991 fprintf (output_file, "static const ");
6992 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
6993 fprintf (output_file, " ");
6994 output_translate_vect_name (output_file, automaton);
6995 fprintf (output_file, "[] = {\n");
6996 output_vect (VLA_HWINT_BEGIN (translate_vect),
6997 VLA_HWINT_LENGTH (translate_vect));
6998 fprintf (output_file, "};\n\n");
6999 VLA_HWINT_DELETE (translate_vect);
7002 /* The value in a table state x ainsn -> something which represents
7004 static int undefined_vect_el_value;
7006 /* The following function returns nonzero value if the best
7007 representation of the table is comb vector. */
7010 state_ainsn_table_t tab;
7012 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7013 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7016 /* The following function creates new table for AUTOMATON. */
7017 static state_ainsn_table_t
7018 create_state_ainsn_table (automaton)
7019 automaton_t automaton;
7021 state_ainsn_table_t tab;
7022 int full_vect_length;
7025 tab = create_node (sizeof (struct state_ainsn_table));
7026 tab->automaton = automaton;
7027 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7028 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7029 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7030 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7031 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7032 full_vect_length = (automaton->insn_equiv_classes_num
7033 * automaton->achieved_states_num);
7034 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7035 for (i = 0; i < full_vect_length; i++)
7036 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7037 tab->min_base_vect_el_value = 0;
7038 tab->max_base_vect_el_value = 0;
7039 tab->min_comb_vect_el_value = 0;
7040 tab->max_comb_vect_el_value = 0;
7044 /* The following function outputs the best C representation of the
7045 table TAB of given TABLE_NAME. */
7047 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
7048 output_comb_vect_name_func,
7049 output_check_vect_name_func,
7050 output_base_vect_name_func)
7051 state_ainsn_table_t tab;
7053 void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
7054 void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
7055 void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
7056 void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
7058 if (!comb_vect_p (tab))
7060 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7061 fprintf (output_file, "static const ");
7062 output_range_type (output_file, tab->min_comb_vect_el_value,
7063 tab->max_comb_vect_el_value);
7064 fprintf (output_file, " ");
7065 (*output_full_vect_name_func) (output_file, tab->automaton);
7066 fprintf (output_file, "[] = {\n");
7067 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7068 VLA_HWINT_LENGTH (tab->full_vect));
7069 fprintf (output_file, "};\n\n");
7073 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7074 fprintf (output_file, "static const ");
7075 output_range_type (output_file, tab->min_comb_vect_el_value,
7076 tab->max_comb_vect_el_value);
7077 fprintf (output_file, " ");
7078 (*output_comb_vect_name_func) (output_file, tab->automaton);
7079 fprintf (output_file, "[] = {\n");
7080 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7081 VLA_HWINT_LENGTH (tab->comb_vect));
7082 fprintf (output_file, "};\n\n");
7083 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7084 fprintf (output_file, "static const ");
7085 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7086 fprintf (output_file, " ");
7087 (*output_check_vect_name_func) (output_file, tab->automaton);
7088 fprintf (output_file, "[] = {\n");
7089 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7090 VLA_HWINT_LENGTH (tab->check_vect));
7091 fprintf (output_file, "};\n\n");
7092 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7093 fprintf (output_file, "static const ");
7094 output_range_type (output_file, tab->min_base_vect_el_value,
7095 tab->max_base_vect_el_value);
7096 fprintf (output_file, " ");
7097 (*output_base_vect_name_func) (output_file, tab->automaton);
7098 fprintf (output_file, "[] = {\n");
7099 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7100 VLA_HWINT_LENGTH (tab->base_vect));
7101 fprintf (output_file, "};\n\n");
7105 /* The following function adds vector with length VECT_LENGTH and
7106 elements pointed by VECT to table TAB as its line with number
7109 add_vect (tab, vect_num, vect, vect_length)
7110 state_ainsn_table_t tab;
7115 int real_vect_length;
7116 vect_el_t *comb_vect_start;
7117 vect_el_t *check_vect_start;
7118 int comb_vect_index;
7119 int comb_vect_els_num;
7121 int first_unempty_vect_index;
7122 int additional_els_num;
7127 if (vect_length == 0)
7129 real_vect_length = tab->automaton->insn_equiv_classes_num;
7130 if (vect [vect_length - 1] == undefined_vect_el_value)
7132 /* Form full vector in the table: */
7133 for (i = 0; i < vect_length; i++)
7134 VLA_HWINT (tab->full_vect,
7135 i + tab->automaton->insn_equiv_classes_num * vect_num)
7137 /* Form comb vector in the table: */
7138 if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7140 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7141 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7142 for (first_unempty_vect_index = 0;
7143 first_unempty_vect_index < vect_length;
7144 first_unempty_vect_index++)
7145 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7147 /* Search for the place in comb vect for the inserted vect. */
7148 for (comb_vect_index = 0;
7149 comb_vect_index < comb_vect_els_num;
7152 for (vect_index = first_unempty_vect_index;
7153 vect_index < vect_length
7154 && vect_index + comb_vect_index < comb_vect_els_num;
7156 if (vect [vect_index] != undefined_vect_el_value
7157 && (comb_vect_start [vect_index + comb_vect_index]
7158 != undefined_vect_el_value))
7160 if (vect_index >= vect_length
7161 || vect_index + comb_vect_index >= comb_vect_els_num)
7164 /* Slot was found. */
7165 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7166 if (additional_els_num < 0)
7167 additional_els_num = 0;
7168 /* Expand comb and check vectors. */
7169 vect_el = undefined_vect_el_value;
7170 no_state_value = tab->automaton->achieved_states_num;
7171 while (additional_els_num > 0)
7173 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7174 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7175 additional_els_num--;
7177 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7178 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7179 if (VLA_HWINT_LENGTH (tab->comb_vect)
7180 < (size_t) (comb_vect_index + real_vect_length))
7182 /* Fill comb and check vectors. */
7183 for (vect_index = 0; vect_index < vect_length; vect_index++)
7184 if (vect [vect_index] != undefined_vect_el_value)
7186 if (comb_vect_start [comb_vect_index + vect_index]
7187 != undefined_vect_el_value)
7189 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7190 if (vect [vect_index] < 0)
7192 if (tab->max_comb_vect_el_value < vect [vect_index])
7193 tab->max_comb_vect_el_value = vect [vect_index];
7194 if (tab->min_comb_vect_el_value > vect [vect_index])
7195 tab->min_comb_vect_el_value = vect [vect_index];
7196 check_vect_start [comb_vect_index + vect_index] = vect_num;
7198 if (tab->max_base_vect_el_value < comb_vect_index)
7199 tab->max_base_vect_el_value = comb_vect_index;
7200 if (tab->min_base_vect_el_value > comb_vect_index)
7201 tab->min_base_vect_el_value = comb_vect_index;
7202 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7205 /* Return number of out arcs of STATE. */
7207 out_state_arcs_num (state)
7214 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7216 if (arc->insn == NULL)
7218 if (arc->insn->first_ainsn_with_given_equialence_num)
7224 /* Compare number of possible transitions from the states. */
7226 compare_transition_els_num (state_ptr_1, state_ptr_2)
7227 const void *state_ptr_1;
7228 const void *state_ptr_2;
7230 int transition_els_num_1;
7231 int transition_els_num_2;
7233 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7234 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7235 if (transition_els_num_1 < transition_els_num_2)
7237 else if (transition_els_num_1 == transition_els_num_2)
7243 /* The function adds element EL_VALUE to vector VECT for a table state
7246 add_vect_el (vect, ainsn, el_value)
7251 int equiv_class_num;
7256 equiv_class_num = ainsn->insn_equiv_class_num;
7257 for (vect_index = VLA_HWINT_LENGTH (*vect);
7258 vect_index <= equiv_class_num;
7260 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7261 VLA_HWINT (*vect, equiv_class_num) = el_value;
7264 /* This is for forming vector of states of an automaton. */
7265 static vla_ptr_t output_states_vect;
7267 /* The function is called by function pass_states. The function adds
7268 STATE to `output_states_vect'. */
7270 add_states_vect_el (state)
7273 VLA_PTR_ADD (output_states_vect, state);
7276 /* Form and output vectors (comb, check, base or full vector)
7277 representing transition table of AUTOMATON. */
7279 output_trans_table (automaton)
7280 automaton_t automaton;
7284 vla_hwint_t transition_vect;
7286 undefined_vect_el_value = automaton->achieved_states_num;
7287 automaton->trans_table = create_state_ainsn_table (automaton);
7288 /* Create vect of pointers to states ordered by num of transitions
7289 from the state (state with the maximum num is the first). */
7290 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7291 pass_states (automaton, add_states_vect_el);
7292 qsort (VLA_PTR_BEGIN (output_states_vect),
7293 VLA_PTR_LENGTH (output_states_vect),
7294 sizeof (state_t), compare_transition_els_num);
7295 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7296 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7297 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7300 VLA_HWINT_NULLIFY (transition_vect);
7301 for (arc = first_out_arc (*state_ptr);
7303 arc = next_out_arc (arc))
7305 if (arc->insn == NULL)
7307 if (arc->insn->first_ainsn_with_given_equialence_num)
7308 add_vect_el (&transition_vect, arc->insn,
7309 arc->to_state->order_state_num);
7311 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7312 VLA_HWINT_BEGIN (transition_vect),
7313 VLA_HWINT_LENGTH (transition_vect));
7315 output_state_ainsn_table
7316 (automaton->trans_table, (char *) "state transitions",
7317 output_trans_full_vect_name, output_trans_comb_vect_name,
7318 output_trans_check_vect_name, output_trans_base_vect_name);
7319 VLA_PTR_DELETE (output_states_vect);
7320 VLA_HWINT_DELETE (transition_vect);
7323 /* Form and output vectors (comb, check, base or simple vect)
7324 representing alts number table of AUTOMATON. The table is state x
7325 ainsn -> number of possible alternative reservations by the
7328 output_state_alts_table (automaton)
7329 automaton_t automaton;
7333 vla_hwint_t state_alts_vect;
7335 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7336 automaton->state_alts_table = create_state_ainsn_table (automaton);
7337 /* Create vect of pointers to states ordered by num of transitions
7338 from the state (state with the maximum num is the first). */
7339 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7340 pass_states (automaton, add_states_vect_el);
7341 qsort (VLA_PTR_BEGIN (output_states_vect),
7342 VLA_PTR_LENGTH (output_states_vect),
7343 sizeof (state_t), compare_transition_els_num);
7344 /* Create base, comb, and check vectors. */
7345 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7346 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7347 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7350 VLA_HWINT_NULLIFY (state_alts_vect);
7351 for (arc = first_out_arc (*state_ptr);
7353 arc = next_out_arc (arc))
7355 if (arc->insn == NULL)
7357 if (arc->insn->first_ainsn_with_given_equialence_num)
7358 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7360 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7361 VLA_HWINT_BEGIN (state_alts_vect),
7362 VLA_HWINT_LENGTH (state_alts_vect));
7364 output_state_ainsn_table
7365 (automaton->state_alts_table, (char *) "state insn alternatives",
7366 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7367 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7368 VLA_PTR_DELETE (output_states_vect);
7369 VLA_HWINT_DELETE (state_alts_vect);
7372 /* The current number of passing states to find minimal issue delay
7373 value for an ainsn and state. */
7374 static int curr_state_pass_num;
7377 /* This recursive function passes states to find minimal issue delay
7378 value for AINSN. The state being visited is STATE. The function
7379 returns minimal issue delay value for AINSN in STATE or -1 if we
7380 enter into a loop. */
7382 min_issue_delay_pass_states (state, ainsn)
7387 int min_insn_issue_delay, insn_issue_delay;
7389 if (state->state_pass_num == curr_state_pass_num
7390 || state->min_insn_issue_delay != -1)
7391 /* We've entered into a loop or already have the correct value for
7392 given state and ainsn. */
7393 return state->min_insn_issue_delay;
7394 state->state_pass_num = curr_state_pass_num;
7395 min_insn_issue_delay = -1;
7396 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7397 if (arc->insn == ainsn)
7399 min_insn_issue_delay = 0;
7404 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7405 if (insn_issue_delay != -1)
7407 if (arc->insn->insn_reserv_decl
7408 == &advance_cycle_insn_decl->decl.insn_reserv)
7410 if (min_insn_issue_delay == -1
7411 || min_insn_issue_delay > insn_issue_delay)
7413 min_insn_issue_delay = insn_issue_delay;
7414 if (insn_issue_delay == 0)
7419 return min_insn_issue_delay;
7422 /* The function searches minimal issue delay value for AINSN in STATE.
7423 The function can return negative value if we can not issue AINSN. We
7424 will report about it later. */
7426 min_issue_delay (state, ainsn)
7430 curr_state_pass_num++;
7431 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7432 return state->min_insn_issue_delay;
7435 /* The function initiates code for finding minimal issue delay values.
7436 It should be called only once. */
7438 initiate_min_issue_delay_pass_states ()
7440 curr_state_pass_num = 0;
7443 /* Form and output vectors representing minimal issue delay table of
7444 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7447 output_min_issue_delay_table (automaton)
7448 automaton_t automaton;
7450 vla_hwint_t min_issue_delay_vect;
7451 vla_hwint_t compressed_min_issue_delay_vect;
7452 vect_el_t min_delay;
7457 /* Create vect of pointers to states ordered by num of transitions
7458 from the state (state with the maximum num is the first). */
7459 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7460 pass_states (automaton, add_states_vect_el);
7461 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7462 VLA_HWINT_EXPAND (min_issue_delay_vect,
7463 VLA_HWINT_LENGTH (output_states_vect)
7464 * automaton->insn_equiv_classes_num);
7466 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7467 * automaton->insn_equiv_classes_num);
7469 VLA_HWINT (min_issue_delay_vect, i) = 0;
7470 automaton->max_min_delay = 0;
7471 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7472 if (ainsn->first_ainsn_with_given_equialence_num)
7474 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7475 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7477 (*state_ptr)->min_insn_issue_delay = -1;
7478 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7479 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7482 min_delay = min_issue_delay (*state_ptr, ainsn);
7483 if (automaton->max_min_delay < min_delay)
7484 automaton->max_min_delay = min_delay;
7485 VLA_HWINT (min_issue_delay_vect,
7486 (*state_ptr)->order_state_num
7487 * automaton->insn_equiv_classes_num
7488 + ainsn->insn_equiv_class_num) = min_delay;
7491 fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
7492 fprintf (output_file, "static const ");
7493 output_range_type (output_file, 0, automaton->max_min_delay);
7494 fprintf (output_file, " ");
7495 output_min_issue_delay_vect_name (output_file, automaton);
7496 fprintf (output_file, "[] = {\n");
7497 /* Compress the vector */
7498 if (automaton->max_min_delay < 2)
7499 automaton->min_issue_delay_table_compression_factor = 8;
7500 else if (automaton->max_min_delay < 4)
7501 automaton->min_issue_delay_table_compression_factor = 4;
7502 else if (automaton->max_min_delay < 16)
7503 automaton->min_issue_delay_table_compression_factor = 2;
7505 automaton->min_issue_delay_table_compression_factor = 1;
7506 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7507 "compressed min issue delay vector");
7508 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7509 (VLA_HWINT_LENGTH (min_issue_delay_vect)
7510 + automaton->min_issue_delay_table_compression_factor
7512 / automaton->min_issue_delay_table_compression_factor);
7514 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7516 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7517 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7518 VLA_HWINT (compressed_min_issue_delay_vect,
7519 i / automaton->min_issue_delay_table_compression_factor)
7520 |= (VLA_HWINT (min_issue_delay_vect, i)
7521 << (8 - (i % automaton->min_issue_delay_table_compression_factor
7523 * (8 / automaton->min_issue_delay_table_compression_factor)));
7524 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7525 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7526 fprintf (output_file, "};\n\n");
7527 VLA_PTR_DELETE (output_states_vect);
7528 VLA_HWINT_DELETE (min_issue_delay_vect);
7529 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7533 /* Number of states which contains transition only by advancing cpu
7535 static int locked_states_num;
7538 /* Form and output vector representing the locked states of
7541 output_dead_lock_vect (automaton)
7542 automaton_t automaton;
7546 vla_hwint_t dead_lock_vect;
7548 /* Create vect of pointers to states ordered by num of
7549 transitions from the state (state with the maximum num is the
7551 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7552 pass_states (automaton, add_states_vect_el);
7553 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7554 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7555 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7556 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7559 arc = first_out_arc (*state_ptr);
7562 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
7563 = (next_out_arc (arc) == NULL
7564 && (arc->insn->insn_reserv_decl
7565 == &advance_cycle_insn_decl->decl.insn_reserv) ? 1 : 0);
7567 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
7568 locked_states_num++;
7571 fprintf (output_file, "/* Vector for locked state flags. */\n");
7572 fprintf (output_file, "static const ");
7573 output_range_type (output_file, 0, 1);
7574 fprintf (output_file, " ");
7575 output_dead_lock_vect_name (output_file, automaton);
7576 fprintf (output_file, "[] = {\n");
7577 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
7578 VLA_HWINT_LENGTH (dead_lock_vect));
7579 fprintf (output_file, "};\n\n");
7580 VLA_HWINT_DELETE (dead_lock_vect);
7581 VLA_PTR_DELETE (output_states_vect);
7584 /* Form and output vector representing reserved units of the states of
7587 output_reserved_units_table (automaton)
7588 automaton_t automaton;
7590 state_t *curr_state_ptr;
7591 vla_hwint_t reserved_units_table;
7592 size_t state_byte_size;
7595 /* Create vect of pointers to states. */
7596 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7597 pass_states (automaton, add_states_vect_el);
7598 /* Create vector. */
7599 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
7600 state_byte_size = (description->query_units_num + 7) / 8;
7601 VLA_HWINT_EXPAND (reserved_units_table,
7602 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7604 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7606 VLA_HWINT (reserved_units_table, i) = 0;
7607 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
7608 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7611 for (i = 0; i < description->units_num; i++)
7612 if (units_array [i]->query_p)
7614 if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
7615 VLA_HWINT (reserved_units_table,
7616 (*curr_state_ptr)->order_state_num * state_byte_size
7617 + units_array [i]->query_num / 8)
7618 += (1 << (units_array [i]->query_num % 8));
7621 fprintf (output_file, "/* Vector for reserved units of states. */\n");
7622 fprintf (output_file, "static const ");
7623 output_range_type (output_file, 0, 255);
7624 fprintf (output_file, " ");
7625 output_reserved_units_table_name (output_file, automaton);
7626 fprintf (output_file, "[] = {\n");
7627 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
7628 VLA_HWINT_LENGTH (reserved_units_table));
7629 fprintf (output_file, "};\n\n");
7630 VLA_HWINT_DELETE (reserved_units_table);
7631 VLA_PTR_DELETE (output_states_vect);
7634 /* The function outputs all tables representing DFA(s) used for fast
7635 pipeline hazards recognition. */
7639 automaton_t automaton;
7642 locked_states_num = 0;
7644 initiate_min_issue_delay_pass_states ();
7645 for (automaton = description->first_automaton;
7647 automaton = automaton->next_automaton)
7649 output_translate_vect (automaton);
7650 output_trans_table (automaton);
7651 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
7652 output_state_alts_table (automaton);
7653 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7654 AUTOMATON_STATE_ALTS_MACRO_NAME);
7655 output_min_issue_delay_table (automaton);
7656 output_dead_lock_vect (automaton);
7657 if (no_minimization_flag)
7659 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
7660 output_reserved_units_table (automaton);
7661 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7662 CPU_UNITS_QUERY_MACRO_NAME);
7665 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7666 advance_cycle_insn_decl->decl.insn_reserv.insn_num);
7669 /* The function outputs definition and value of PHR interface variable
7670 `max_insn_queue_index' */
7672 output_max_insn_queue_index_def ()
7676 for (i = 0; (1 << i) <= description->max_insn_reserv_cycles; i++)
7680 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
7684 /* The function outputs switch cases for insn reseravtions using
7685 function *output_automata_list_code. */
7687 output_insn_code_cases (output_automata_list_code)
7688 void (*output_automata_list_code) (automata_list_el_t);
7690 decl_t decl, decl_2;
7693 for (i = 0; i < description->decls_num; i++)
7695 decl = description->decls [i];
7696 if (decl->mode == dm_insn_reserv)
7697 decl->decl.insn_reserv.processed_p = FALSE;
7699 for (i = 0; i < description->decls_num; i++)
7701 decl = description->decls [i];
7702 if (decl->mode == dm_insn_reserv && !decl->decl.insn_reserv.processed_p)
7704 for (j = i; j < description->decls_num; j++)
7706 decl_2 = description->decls [j];
7707 if (decl_2->mode == dm_insn_reserv
7708 && (decl_2->decl.insn_reserv.important_automata_list
7709 == decl->decl.insn_reserv.important_automata_list))
7711 decl_2->decl.insn_reserv.processed_p = TRUE;
7712 fprintf (output_file, " case %d: /* %s */\n",
7713 decl_2->decl.insn_reserv.insn_num,
7714 decl_2->decl.insn_reserv.name);
7717 (*output_automata_list_code)
7718 (decl->decl.insn_reserv.important_automata_list);
7724 /* The function outputs a code for evaluation of a minimal delay of
7725 issue of insns which have reservations in given AUTOMATA_LIST. */
7727 output_automata_list_min_issue_delay_code (automata_list)
7728 automata_list_el_t automata_list;
7730 automata_list_el_t el;
7731 automaton_t automaton;
7733 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7735 automaton = el->automaton;
7736 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7737 output_min_issue_delay_vect_name (output_file, automaton);
7738 fprintf (output_file,
7739 (automaton->min_issue_delay_table_compression_factor != 1
7741 output_translate_vect_name (output_file, automaton);
7742 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7743 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7744 output_chip_member_name (output_file, automaton);
7745 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7746 if (automaton->min_issue_delay_table_compression_factor == 1)
7747 fprintf (output_file, "];\n");
7750 fprintf (output_file, ") / %d];\n",
7751 automaton->min_issue_delay_table_compression_factor);
7752 fprintf (output_file, " %s = (%s >> (8 - (",
7753 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7754 output_translate_vect_name (output_file, automaton);
7756 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
7757 INTERNAL_INSN_CODE_NAME,
7758 automaton->min_issue_delay_table_compression_factor,
7759 8 / automaton->min_issue_delay_table_compression_factor,
7760 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7763 if (el == automata_list)
7764 fprintf (output_file, " %s = %s;\n",
7765 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7768 fprintf (output_file, " if (%s > %s)\n",
7769 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7770 fprintf (output_file, " %s = %s;\n",
7771 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7774 fprintf (output_file, " break;\n\n");
7777 /* Output function `internal_min_issue_delay'. */
7779 output_internal_min_issue_delay_func ()
7781 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7782 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
7783 fprintf (output_file,
7784 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
7785 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7786 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
7787 CHIP_PARAMETER_NAME);
7788 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s;\n",
7789 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7790 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7791 output_insn_code_cases (output_automata_list_min_issue_delay_code);
7792 fprintf (output_file,
7793 "\n default:\n %s = -1;\n break;\n }\n",
7794 RESULT_VARIABLE_NAME);
7795 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
7796 fprintf (output_file, "}\n\n");
7799 /* The function outputs a code changing state after issue of insns
7800 which have reservations in given AUTOMATA_LIST. */
7802 output_automata_list_transition_code (automata_list)
7803 automata_list_el_t automata_list;
7805 automata_list_el_t el, next_el;
7807 fprintf (output_file, " {\n");
7808 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7809 for (el = automata_list;; el = next_el)
7811 next_el = el->next_automata_list_el;
7812 if (next_el == NULL)
7814 fprintf (output_file, " ");
7815 output_state_member_type (output_file, el->automaton);
7816 fprintf (output_file, " ");
7817 output_temp_chip_member_name (output_file, el->automaton);
7818 fprintf (output_file, ";\n");
7820 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7821 if (comb_vect_p (el->automaton->trans_table))
7823 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7824 output_trans_base_vect_name (output_file, el->automaton);
7825 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7826 output_chip_member_name (output_file, el->automaton);
7827 fprintf (output_file, "] + ");
7828 output_translate_vect_name (output_file, el->automaton);
7829 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7830 fprintf (output_file, " if (");
7831 output_trans_check_vect_name (output_file, el->automaton);
7832 fprintf (output_file, " [%s] != %s->",
7833 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7834 output_chip_member_name (output_file, el->automaton);
7835 fprintf (output_file, ")\n");
7836 fprintf (output_file, " return %s (%s, %s);\n",
7837 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7838 CHIP_PARAMETER_NAME);
7839 fprintf (output_file, " else\n");
7840 fprintf (output_file, " ");
7841 if (el->next_automata_list_el != NULL)
7842 output_temp_chip_member_name (output_file, el->automaton);
7845 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7846 output_chip_member_name (output_file, el->automaton);
7848 fprintf (output_file, " = ");
7849 output_trans_comb_vect_name (output_file, el->automaton);
7850 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7854 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7855 output_trans_full_vect_name (output_file, el->automaton);
7856 fprintf (output_file, " [");
7857 output_translate_vect_name (output_file, el->automaton);
7858 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7859 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7860 output_chip_member_name (output_file, el->automaton);
7861 fprintf (output_file, " * %d];\n",
7862 el->automaton->insn_equiv_classes_num);
7863 fprintf (output_file, " if (%s >= %d)\n",
7864 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7865 fprintf (output_file, " return %s (%s, %s);\n",
7866 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7867 CHIP_PARAMETER_NAME);
7868 fprintf (output_file, " else\n ");
7869 if (el->next_automata_list_el != NULL)
7870 output_temp_chip_member_name (output_file, el->automaton);
7873 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7874 output_chip_member_name (output_file, el->automaton);
7876 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7878 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7879 for (el = automata_list;; el = next_el)
7881 next_el = el->next_automata_list_el;
7882 if (next_el == NULL)
7884 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
7885 output_chip_member_name (output_file, el->automaton);
7886 fprintf (output_file, " = ");
7887 output_temp_chip_member_name (output_file, el->automaton);
7888 fprintf (output_file, ";\n");
7890 fprintf (output_file, " return -1;\n");
7891 fprintf (output_file, " }\n");
7894 /* Output function `internal_state_transition'. */
7896 output_internal_trans_func ()
7898 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7899 INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
7900 fprintf (output_file,
7901 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
7902 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7903 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
7904 CHIP_NAME, CHIP_PARAMETER_NAME);
7905 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
7906 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7907 output_insn_code_cases (output_automata_list_transition_code);
7908 fprintf (output_file, "\n default:\n return -1;\n }\n");
7909 fprintf (output_file, "}\n\n");
7916 insn_code = dfa_insn_code (insn);
7917 if (insn_code > DFA__ADVANCE_CYCLE)
7921 insn_code = DFA__ADVANCE_CYCLE;
7923 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7924 code denotes CODE. */
7926 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
7927 const char *insn_name;
7928 const char *insn_code_name;
7931 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
7932 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
7933 DFA_INSN_CODE_FUNC_NAME, insn_name);
7934 fprintf (output_file, " if (%s > %s)\n return %d;\n",
7935 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
7936 fprintf (output_file, " }\n else\n %s = %s;\n\n",
7937 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
7941 /* The function outputs function `dfa_insn_code'. */
7943 output_dfa_insn_code_func ()
7945 fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
7946 fprintf (output_file, "static int %s PARAMS ((rtx));\n",
7947 DFA_INSN_CODE_FUNC_NAME);
7948 fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
7949 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
7950 fprintf (output_file, "{\n int %s;\n int %s;\n\n",
7951 INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
7952 fprintf (output_file, " if (INSN_UID (%s) >= %s)\n {\n",
7953 INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7954 fprintf (output_file, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
7955 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7956 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
7957 fprintf (output_file, " %s = xrealloc (%s, %s * sizeof (int));\n",
7958 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7959 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7960 fprintf (output_file,
7961 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
7962 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7963 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7964 TEMPORARY_VARIABLE_NAME);
7965 fprintf (output_file, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
7966 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7967 INSN_PARAMETER_NAME);
7968 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
7969 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
7970 fprintf (output_file, " %s [INSN_UID (%s)] = %s;\n",
7971 DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
7972 INTERNAL_INSN_CODE_NAME);
7973 fprintf (output_file, " }\n return %s;\n}\n\n",
7974 INTERNAL_INSN_CODE_NAME);
7977 /* The function outputs PHR interface function `state_transition'. */
7979 output_trans_func ()
7981 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7982 TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
7983 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
7984 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7985 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7986 INTERNAL_INSN_CODE_NAME, -1);
7987 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
7988 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
7991 /* The function outputs a code for evaluation of alternative states
7992 number for insns which have reservations in given AUTOMATA_LIST. */
7994 output_automata_list_state_alts_code (automata_list)
7995 automata_list_el_t automata_list;
7997 automata_list_el_t el;
7998 automaton_t automaton;
8000 fprintf (output_file, " {\n");
8001 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8002 if (comb_vect_p (el->automaton->state_alts_table))
8004 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8007 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8009 automaton = el->automaton;
8010 if (comb_vect_p (automaton->state_alts_table))
8012 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8013 output_state_alts_base_vect_name (output_file, automaton);
8014 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8015 output_chip_member_name (output_file, automaton);
8016 fprintf (output_file, "] + ");
8017 output_translate_vect_name (output_file, automaton);
8018 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8019 fprintf (output_file, " if (");
8020 output_state_alts_check_vect_name (output_file, automaton);
8021 fprintf (output_file, " [%s] != %s->",
8022 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8023 output_chip_member_name (output_file, automaton);
8024 fprintf (output_file, ")\n");
8025 fprintf (output_file, " return 0;\n");
8026 fprintf (output_file, " else\n");
8027 fprintf (output_file,
8028 (el == automata_list
8029 ? " %s = " : " %s += "),
8030 RESULT_VARIABLE_NAME);
8031 output_state_alts_comb_vect_name (output_file, automaton);
8032 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8036 fprintf (output_file,
8037 (el == automata_list
8038 ? "\n %s = " : " %s += "),
8039 RESULT_VARIABLE_NAME);
8040 output_state_alts_full_vect_name (output_file, automaton);
8041 fprintf (output_file, " [");
8042 output_translate_vect_name (output_file, automaton);
8043 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8044 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8045 output_chip_member_name (output_file, automaton);
8046 fprintf (output_file, " * %d];\n",
8047 automaton->insn_equiv_classes_num);
8050 fprintf (output_file, " break;\n }\n\n");
8053 /* Output function `internal_state_alts'. */
8055 output_internal_state_alts_func ()
8057 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8058 INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
8059 fprintf (output_file,
8060 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8061 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8062 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8063 CHIP_PARAMETER_NAME);
8064 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8065 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8066 output_insn_code_cases (output_automata_list_state_alts_code);
8067 fprintf (output_file,
8068 "\n default:\n %s = 0;\n break;\n }\n",
8069 RESULT_VARIABLE_NAME);
8070 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8071 fprintf (output_file, "}\n\n");
8074 /* The function outputs PHR interface function `state_alts'. */
8076 output_state_alts_func ()
8078 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8079 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8080 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8081 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8082 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8083 INTERNAL_INSN_CODE_NAME, 0);
8084 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8085 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8088 /* Output function `min_issue_delay'. */
8090 output_min_issue_delay_func ()
8092 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8093 MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8094 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8095 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8096 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8097 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8098 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8099 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8100 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8101 fprintf (output_file, " }\n else\n %s = %s;\n",
8102 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8103 fprintf (output_file, "\n return %s (%s, %s);\n",
8104 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8106 fprintf (output_file, "}\n\n");
8109 /* Output function `internal_dead_lock'. */
8111 output_internal_dead_lock_func ()
8113 automaton_t automaton;
8115 fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
8116 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
8117 fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8118 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
8119 CHIP_PARAMETER_NAME);
8120 fprintf (output_file, "{\n");
8121 for (automaton = description->first_automaton;
8123 automaton = automaton->next_automaton)
8125 fprintf (output_file, " if (");
8126 output_dead_lock_vect_name (output_file, automaton);
8127 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8128 output_chip_member_name (output_file, automaton);
8129 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8131 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8134 /* The function outputs PHR interface function `state_dead_lock_p'. */
8136 output_dead_lock_func ()
8138 fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
8139 DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8140 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8141 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8144 /* Output function `internal_reset'. */
8146 output_internal_reset_func ()
8148 fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
8149 INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8150 fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8151 INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
8152 CHIP_NAME, CHIP_PARAMETER_NAME);
8153 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8154 CHIP_PARAMETER_NAME, CHIP_NAME);
8157 /* The function outputs PHR interface function `state_size'. */
8161 fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
8162 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8165 /* The function outputs PHR interface function `state_reset'. */
8167 output_reset_func ()
8169 fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
8170 RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8171 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8175 /* Output function `min_insn_conflict_delay'. */
8177 output_min_insn_conflict_delay_func ()
8179 fprintf (output_file,
8180 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8181 MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
8182 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8183 STATE_TYPE_NAME, STATE_NAME,
8184 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8185 fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
8186 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8187 INTERNAL_INSN2_CODE_NAME);
8188 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8189 INTERNAL_INSN_CODE_NAME, 0);
8190 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8191 INTERNAL_INSN2_CODE_NAME, 0);
8192 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8193 CHIP_NAME, STATE_NAME, CHIP_NAME);
8194 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8195 fprintf (output_file, " if (%s (%s, &%s) > 0)\n abort ();\n",
8196 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8197 fprintf (output_file, " return %s (%s, &%s);\n",
8198 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8200 fprintf (output_file, "}\n\n");
8203 /* Output function `internal_insn_latency'. */
8205 output_internal_insn_latency_func ()
8208 struct bypass_decl *bypass;
8211 fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8212 INTERNAL_INSN_LATENCY_FUNC_NAME);
8213 fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
8214 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8215 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8216 INSN2_PARAMETER_NAME);
8217 fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
8218 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8219 fprintf (output_file,
8220 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8221 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8222 fprintf (output_file, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8223 for (i = 0; i < description->decls_num; i++)
8225 decl = description->decls [i];
8226 if (decl->mode == dm_insn_reserv)
8228 fprintf (output_file, " case %d:\n",
8229 decl->decl.insn_reserv.insn_num);
8230 if (decl->decl.insn_reserv.bypass_list == NULL)
8231 fprintf (output_file, " return (%s != %s ? %d : 0);\n",
8232 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8233 decl->decl.insn_reserv.default_latency);
8236 fprintf (output_file, " switch (%s)\n {\n",
8237 INTERNAL_INSN2_CODE_NAME);
8238 for (bypass = decl->decl.insn_reserv.bypass_list;
8240 bypass = bypass->next)
8242 fprintf (output_file, " case %d:\n",
8243 bypass->in_insn_reserv->insn_num);
8244 if (bypass->bypass_guard_name == NULL)
8245 fprintf (output_file, " return %d;\n",
8248 fprintf (output_file,
8249 " return (%s (%s, %s) ? %d : %d);\n",
8250 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8251 INSN2_PARAMETER_NAME, bypass->latency,
8252 decl->decl.insn_reserv.default_latency);
8254 fprintf (output_file, " default:\n");
8255 fprintf (output_file,
8256 " return (%s != %s ? %d : 0);\n }\n",
8257 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8258 decl->decl.insn_reserv.default_latency);
8263 fprintf (output_file, " default:\n return 0;\n }\n}\n\n");
8266 /* The function outputs PHR interface function `insn_latency'. */
8268 output_insn_latency_func ()
8270 fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8271 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8272 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8273 fprintf (output_file, "{\n int %s, %s;\n",
8274 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8275 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8276 INTERNAL_INSN_CODE_NAME, 0);
8277 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8278 INTERNAL_INSN2_CODE_NAME, 0);
8279 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8280 INTERNAL_INSN_LATENCY_FUNC_NAME,
8281 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8282 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8285 /* The function outputs PHR interface function `print_reservation'. */
8287 output_print_reservation_func ()
8292 fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8293 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8294 INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8295 INSN_PARAMETER_NAME);
8296 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8297 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8298 fprintf (output_file, " %s = %s (%s);\n",
8299 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8300 INSN_PARAMETER_NAME);
8301 fprintf (output_file, " if (%s > %s)\n",
8302 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8303 fprintf (output_file, " {\n fprintf (%s, \"%s\");\n",
8304 FILE_PARAMETER_NAME, NOTHING_NAME);
8305 fprintf (output_file, " return;\n }\n");
8306 fprintf (output_file, " }\n else\n");
8307 fprintf (output_file,
8308 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8309 FILE_PARAMETER_NAME, NOTHING_NAME);
8310 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8311 for (i = 0; i < description->decls_num; i++)
8313 decl = description->decls [i];
8314 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8316 fprintf (output_file,
8317 " case %d:\n", decl->decl.insn_reserv.insn_num);
8318 fprintf (output_file,
8319 " fprintf (%s, \"%s\");\n break;\n",
8320 FILE_PARAMETER_NAME,
8321 regexp_representation (decl->decl.insn_reserv.regexp));
8322 finish_regexp_representation ();
8325 fprintf (output_file, " default:\n fprintf (%s, \"%s\");\n }\n",
8326 FILE_PARAMETER_NAME, NOTHING_NAME);
8327 fprintf (output_file, "}\n\n");
8330 /* The following function is used to sort unit declaration by their
8333 units_cmp (unit1, unit2)
8334 const void *unit1, *unit2;
8336 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8337 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8339 return strcmp (u1->name, u2->name);
8342 /* The following macro value is name of struct containing unit name
8344 #define NAME_CODE_STRUCT_NAME "name_code"
8346 /* The following macro value is name of table of struct name_code. */
8347 #define NAME_CODE_TABLE_NAME "name_code_table"
8349 /* The following macro values are member names for struct name_code. */
8350 #define NAME_MEMBER_NAME "name"
8351 #define CODE_MEMBER_NAME "code"
8353 /* The following macro values are local variable names for function
8354 `get_cpu_unit_code'. */
8355 #define CMP_VARIABLE_NAME "cmp"
8356 #define LOW_VARIABLE_NAME "l"
8357 #define MIDDLE_VARIABLE_NAME "m"
8358 #define HIGH_VARIABLE_NAME "h"
8360 /* The following function outputs function to obtain internal cpu unit
8361 code by the cpu unit name. */
8363 output_get_cpu_unit_code_func ()
8368 fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8369 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8370 CPU_UNIT_NAME_PARAMETER_NAME);
8371 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8372 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8373 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8374 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8375 fprintf (output_file, " static struct %s %s [] =\n {\n",
8376 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8377 units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
8378 * description->units_num);
8379 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8380 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8381 for (i = 0; i < description->units_num; i++)
8382 if (units [i]->query_p)
8383 fprintf (output_file, " {\"%s\", %d},\n",
8384 units[i]->name, units[i]->query_num);
8385 fprintf (output_file, " };\n\n");
8386 fprintf (output_file, " /* The following is binary search: */\n");
8387 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8388 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8389 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8390 fprintf (output_file, " while (%s <= %s)\n {\n",
8391 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8392 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8393 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8394 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8395 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8396 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8397 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8398 fprintf (output_file, " %s = %s - 1;\n",
8399 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8400 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8401 fprintf (output_file, " %s = %s + 1;\n",
8402 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8403 fprintf (output_file, " else\n");
8404 fprintf (output_file, " return %s [%s].%s;\n }\n",
8405 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8406 fprintf (output_file, " return -1;\n}\n\n");
8410 /* The following function outputs function to check reservation of cpu
8411 unit (its internal code will be passed as the function argument) in
8414 output_cpu_unit_reservation_p ()
8416 automaton_t automaton;
8418 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8419 CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8420 CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8421 CPU_CODE_PARAMETER_NAME);
8422 fprintf (output_file, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8423 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8424 description->query_units_num);
8425 for (automaton = description->first_automaton;
8427 automaton = automaton->next_automaton)
8429 fprintf (output_file, " if ((");
8430 output_reserved_units_table_name (output_file, automaton);
8431 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8432 output_chip_member_name (output_file, automaton);
8433 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8434 (description->query_units_num + 7) / 8,
8435 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8436 fprintf (output_file, " return 1;\n");
8438 fprintf (output_file, " return 0;\n}\n\n");
8441 /* The function outputs PHR interface function `dfa_start'. */
8443 output_dfa_start_func ()
8445 fprintf (output_file,
8446 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8447 DFA_START_FUNC_NAME, I_VARIABLE_NAME,
8448 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8449 fprintf (output_file, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8450 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8451 fprintf (output_file,
8452 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8453 I_VARIABLE_NAME, I_VARIABLE_NAME,
8454 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8455 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8458 /* The function outputs PHR interface function `dfa_finish'. */
8460 output_dfa_finish_func ()
8462 fprintf (output_file, "void\n%s ()\n{\n free (%s);\n}\n\n",
8463 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8468 /* The page contains code for output description file (readable
8469 representation of original description and generated DFA(s). */
8471 /* The function outputs string representation of IR reservation. */
8473 output_regexp (regexp)
8476 fprintf (output_description_file, "%s", regexp_representation (regexp));
8477 finish_regexp_representation ();
8480 /* Output names of units in LIST separated by comma. */
8482 output_unit_set_el_list (list)
8487 for (el = list; el != NULL; el = el->next_unit_set_el)
8490 fprintf (output_description_file, ",");
8491 fprintf (output_description_file, "%s", el->unit_decl->name);
8495 /* The function outputs string representation of IR define_reservation
8496 and define_insn_reservation. */
8498 output_description ()
8503 for (i = 0; i < description->decls_num; i++)
8505 decl = description->decls [i];
8506 if (decl->mode == dm_unit)
8508 if (decl->decl.unit.excl_list != NULL)
8510 fprintf (output_description_file, "unit %s exlusion_set: ",
8511 decl->decl.unit.name);
8512 output_unit_set_el_list (decl->decl.unit.excl_list);
8513 fprintf (output_description_file, "\n");
8515 if (decl->decl.unit.presence_list != NULL)
8517 fprintf (output_description_file, "unit %s presence_set: ",
8518 decl->decl.unit.name);
8519 output_unit_set_el_list (decl->decl.unit.presence_list);
8520 fprintf (output_description_file, "\n");
8522 if (decl->decl.unit.absence_list != NULL)
8524 fprintf (output_description_file, "unit %s absence_set: ",
8525 decl->decl.unit.name);
8526 output_unit_set_el_list (decl->decl.unit.absence_list);
8527 fprintf (output_description_file, "\n");
8531 fprintf (output_description_file, "\n");
8532 for (i = 0; i < description->decls_num; i++)
8534 decl = description->decls [i];
8535 if (decl->mode == dm_reserv)
8537 fprintf (output_description_file, "reservation ");
8538 fprintf (output_description_file, decl->decl.reserv.name);
8539 fprintf (output_description_file, ": ");
8540 output_regexp (decl->decl.reserv.regexp);
8541 fprintf (output_description_file, "\n");
8543 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8545 fprintf (output_description_file, "insn reservation %s ",
8546 decl->decl.insn_reserv.name);
8547 print_rtl (output_description_file, decl->decl.insn_reserv.condexp);
8548 fprintf (output_description_file, ": ");
8549 output_regexp (decl->decl.insn_reserv.regexp);
8550 fprintf (output_description_file, "\n");
8552 else if (decl->mode == dm_bypass)
8553 fprintf (output_description_file, "bypass %d %s %s\n",
8554 decl->decl.bypass.latency, decl->decl.bypass.out_insn_name,
8555 decl->decl.bypass.in_insn_name);
8557 fprintf (output_description_file, "\n\f\n");
8560 /* The function outputs name of AUTOMATON. */
8562 output_automaton_name (f, automaton)
8564 automaton_t automaton;
8566 if (automaton->corresponding_automaton_decl == NULL)
8567 fprintf (f, "#%d", automaton->automaton_order_num);
8569 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8572 /* Maximal length of line for pretty printing into description
8574 #define MAX_LINE_LENGTH 70
8576 /* The function outputs units name belonging to AUTOMATON. */
8578 output_automaton_units (automaton)
8579 automaton_t automaton;
8583 int curr_line_length;
8584 int there_is_an_automaton_unit;
8587 fprintf (output_description_file, "\n Coresponding units:\n");
8588 fprintf (output_description_file, " ");
8589 curr_line_length = 4;
8590 there_is_an_automaton_unit = 0;
8591 for (i = 0; i < description->decls_num; i++)
8593 decl = description->decls [i];
8594 if (decl->mode == dm_unit
8595 && (decl->decl.unit.corresponding_automaton_num
8596 == automaton->automaton_order_num))
8598 there_is_an_automaton_unit = 1;
8599 name = decl->decl.unit.name;
8600 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8602 curr_line_length = strlen (name) + 4;
8603 fprintf (output_description_file, "\n ");
8607 curr_line_length += strlen (name) + 1;
8608 fprintf (output_description_file, " ");
8610 fprintf (output_description_file, name);
8613 if (!there_is_an_automaton_unit)
8614 fprintf (output_description_file, "<None>");
8615 fprintf (output_description_file, "\n\n");
8618 /* The following variable is used for forming array of all possible cpu unit
8619 reservations described by the current DFA state. */
8620 static vla_ptr_t state_reservs;
8622 /* The function forms `state_reservs' for STATE. */
8624 add_state_reservs (state)
8627 alt_state_t curr_alt_state;
8628 reserv_sets_t reservs;
8630 if (state->component_states != NULL)
8631 for (curr_alt_state = state->component_states;
8632 curr_alt_state != NULL;
8633 curr_alt_state = curr_alt_state->next_sorted_alt_state)
8634 add_state_reservs (curr_alt_state->state);
8637 reservs = state->reservs;
8638 VLA_PTR_ADD (state_reservs, reservs);
8642 /* The function outputs readable represenatation of all out arcs of
8645 output_state_arcs (state)
8651 int curr_line_length;
8653 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8656 if (!ainsn->first_insn_with_same_reservs)
8658 fprintf (output_description_file, " ");
8659 curr_line_length = 7;
8660 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8663 insn_name = ainsn->insn_reserv_decl->name;
8664 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8666 if (ainsn != arc->insn)
8668 fprintf (output_description_file, ",\n ");
8669 curr_line_length = strlen (insn_name) + 6;
8672 curr_line_length += strlen (insn_name);
8676 curr_line_length += strlen (insn_name);
8677 if (ainsn != arc->insn)
8679 curr_line_length += 2;
8680 fprintf (output_description_file, ", ");
8683 fprintf (output_description_file, insn_name);
8684 ainsn = ainsn->next_same_reservs_insn;
8686 while (ainsn != NULL);
8687 fprintf (output_description_file, " %d (%d)\n",
8688 arc->to_state->order_state_num, arc->state_alts);
8690 fprintf (output_description_file, "\n");
8693 /* The following function is used for sorting possible cpu unit
8694 reservation of a DFA state. */
8696 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
8697 const void *reservs_ptr_1;
8698 const void *reservs_ptr_2;
8700 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
8701 *(reserv_sets_t *) reservs_ptr_2);
8704 /* The following function is used for sorting possible cpu unit
8705 reservation of a DFA state. */
8707 remove_state_duplicate_reservs ()
8709 reserv_sets_t *reservs_ptr;
8710 reserv_sets_t *last_formed_reservs_ptr;
8712 last_formed_reservs_ptr = NULL;
8713 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8714 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8716 if (last_formed_reservs_ptr == NULL)
8717 last_formed_reservs_ptr = reservs_ptr;
8718 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
8720 ++last_formed_reservs_ptr;
8721 *last_formed_reservs_ptr = *reservs_ptr;
8723 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
8726 /* The following function output readable representation of DFA(s)
8727 state used for fast recognition of pipeline hazards. State is
8728 described by possible (current and scehduled) cpu unit
8731 output_state (state)
8734 reserv_sets_t *reservs_ptr;
8736 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
8737 fprintf (output_description_file, " State #%d", state->order_state_num);
8738 fprintf (output_description_file,
8739 state->new_cycle_p ? " (new cycle)\n" : "\n");
8740 add_state_reservs (state);
8741 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
8742 sizeof (reserv_sets_t), state_reservs_cmp);
8743 remove_state_duplicate_reservs ();
8744 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8745 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8748 fprintf (output_description_file, " ");
8749 output_reserv_sets (output_description_file, *reservs_ptr);
8750 fprintf (output_description_file, "\n");
8752 fprintf (output_description_file, "\n");
8753 output_state_arcs (state);
8754 VLA_PTR_DELETE (state_reservs);
8757 /* The following function output readable representation of
8758 DFAs used for fast recognition of pipeline hazards. */
8760 output_automaton_descriptions ()
8762 automaton_t automaton;
8764 for (automaton = description->first_automaton;
8766 automaton = automaton->next_automaton)
8768 fprintf (output_description_file, "\nAutomaton ");
8769 output_automaton_name (output_description_file, automaton);
8770 fprintf (output_description_file, "\n");
8771 output_automaton_units (automaton);
8772 pass_states (automaton, output_state);
8778 /* The page contains top level function for generation DFA(s) used for
8781 /* The function outputs statistics about work of different phases of
8784 output_statistics (f)
8787 automaton_t automaton;
8789 int transition_comb_vect_els = 0;
8790 int transition_full_vect_els = 0;
8791 int state_alts_comb_vect_els = 0;
8792 int state_alts_full_vect_els = 0;
8793 int min_issue_delay_vect_els = 0;
8796 for (automaton = description->first_automaton;
8798 automaton = automaton->next_automaton)
8800 fprintf (f, "\nAutomaton ");
8801 output_automaton_name (f, automaton);
8802 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
8803 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
8804 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
8805 automaton->DFA_states_num, automaton->DFA_arcs_num);
8806 if (!no_minimization_flag)
8807 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8808 automaton->minimal_DFA_states_num,
8809 automaton->minimal_DFA_arcs_num);
8810 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
8811 description->insns_num, automaton->insn_equiv_classes_num);
8814 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8815 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
8816 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
8817 (comb_vect_p (automaton->trans_table)
8818 ? "use comb vect" : "use simple vect"));
8820 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8821 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
8822 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
8823 (comb_vect_p (automaton->state_alts_table)
8824 ? "use comb vect" : "use simple vect"));
8826 (f, "%5ld min delay table els, compression factor %d\n",
8827 (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
8828 automaton->min_issue_delay_table_compression_factor);
8829 transition_comb_vect_els
8830 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
8831 transition_full_vect_els
8832 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
8833 state_alts_comb_vect_els
8834 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
8835 state_alts_full_vect_els
8836 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
8837 min_issue_delay_vect_els
8838 += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
8842 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
8843 allocated_states_num, allocated_arcs_num);
8844 fprintf (f, "%5d all allocated alternative states\n",
8845 allocated_alt_states_num);
8846 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
8847 transition_comb_vect_els, transition_full_vect_els);
8849 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
8850 state_alts_comb_vect_els, state_alts_full_vect_els);
8851 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
8852 fprintf (f, "%5d locked states num\n", locked_states_num);
8856 /* The function output times of work of different phases of DFA
8859 output_time_statistics (f)
8862 fprintf (f, "\n transformation: ");
8863 print_active_time (f, transform_time);
8864 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
8865 print_active_time (f, NDFA_time);
8868 fprintf (f, ", NDFA -> DFA: ");
8869 print_active_time (f, NDFA_to_DFA_time);
8871 fprintf (f, "\n DFA minimization: ");
8872 print_active_time (f, minimize_time);
8873 fprintf (f, ", making insn equivalence: ");
8874 print_active_time (f, equiv_time);
8875 fprintf (f, "\n all automaton generation: ");
8876 print_active_time (f, automaton_generation_time);
8877 fprintf (f, ", output: ");
8878 print_active_time (f, output_time);
8882 /* The function generates DFA (deterministic finate state automaton)
8883 for fast recognition of pipeline hazards. No errors during
8884 checking must be fixed before this function call. */
8888 automata_num = split_argument;
8889 if (description->units_num < automata_num)
8890 automata_num = description->units_num;
8893 initiate_automata_lists ();
8894 initiate_pass_states ();
8895 initiate_excl_sets ();
8896 initiate_presence_absence_sets ();
8897 automaton_generation_time = create_ticker ();
8899 ticker_off (&automaton_generation_time);
8904 /* The following function creates attribute which order number of insn
8905 in pipeline hazard description translator. */
8907 make_insn_alts_attr ()
8913 condexp = rtx_alloc (COND);
8914 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8915 XEXP (condexp, 1) = make_numeric_value (0);
8916 for (i = insn_num = 0; i < description->decls_num; i++)
8918 decl = description->decls [i];
8919 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8921 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8922 XVECEXP (condexp, 0, 2 * insn_num + 1)
8923 = make_numeric_value (decl->decl.insn_reserv.transformed_regexp
8924 ->regexp.oneof.regexps_num);
8928 if (description->insns_num != insn_num + 1)
8930 make_internal_attr (attr_printf (sizeof ("*")
8931 + strlen (INSN_ALTS_FUNC_NAME) + 1,
8932 "*%s", INSN_ALTS_FUNC_NAME),
8938 /* The following function creates attribute which is order number of
8939 insn in pipeline hazard description translator. */
8941 make_internal_dfa_insn_code_attr ()
8947 condexp = rtx_alloc (COND);
8948 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8949 XEXP (condexp, 1) = make_numeric_value (advance_cycle_insn_decl
8950 ->decl.insn_reserv.insn_num + 1);
8951 for (i = insn_num = 0; i < description->decls_num; i++)
8953 decl = description->decls [i];
8954 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8956 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8957 XVECEXP (condexp, 0, 2 * insn_num + 1)
8958 = make_numeric_value (decl->decl.insn_reserv.insn_num);
8962 if (description->insns_num != insn_num + 1)
8965 (attr_printf (sizeof ("*")
8966 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
8967 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
8973 /* The following function creates attribute which order number of insn
8974 in pipeline hazard description translator. */
8976 make_default_insn_latency_attr ()
8982 condexp = rtx_alloc (COND);
8983 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8984 XEXP (condexp, 1) = make_numeric_value (0);
8985 for (i = insn_num = 0; i < description->decls_num; i++)
8987 decl = description->decls [i];
8988 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8990 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8991 XVECEXP (condexp, 0, 2 * insn_num + 1)
8992 = make_numeric_value (decl->decl.insn_reserv.default_latency);
8996 if (description->insns_num != insn_num + 1)
8998 make_internal_attr (attr_printf (sizeof ("*")
8999 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9000 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9006 /* The following function creates attribute which returns 1 if given
9007 output insn has bypassing and 0 otherwise. */
9012 int bypass_insns_num = 0;
9016 for (i = 0; i < description->decls_num; i++)
9018 decl = description->decls [i];
9019 if (decl->mode == dm_insn_reserv
9020 && decl->decl.insn_reserv.condexp != NULL
9021 && decl->decl.insn_reserv.bypass_list != NULL)
9024 if (bypass_insns_num == 0)
9025 result_rtx = make_numeric_value (0);
9028 result_rtx = rtx_alloc (COND);
9029 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9030 XEXP (result_rtx, 1) = make_numeric_value (0);
9032 for (i = bypass_insn = 0; i < description->decls_num; i++)
9034 decl = description->decls [i];
9035 if (decl->mode == dm_insn_reserv
9036 && decl->decl.insn_reserv.condexp != NULL
9037 && decl->decl.insn_reserv.bypass_list != NULL)
9039 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9040 = decl->decl.insn_reserv.condexp;
9041 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9042 = make_numeric_value (1);
9047 make_internal_attr (attr_printf (sizeof ("*")
9048 + strlen (BYPASS_P_FUNC_NAME) + 1,
9049 "*%s", BYPASS_P_FUNC_NAME),
9055 /* This page mainly contains top level functions of pipeline hazards
9056 description translator. */
9058 /* The following macro value is suffix of name of description file of
9059 pipeline hazards description translator. */
9060 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9062 /* The function returns suffix of given file name. The returned
9063 string can not be changed. */
9065 file_name_suffix (file_name)
9066 const char *file_name;
9068 const char *last_period;
9070 for (last_period = NULL; *file_name != '\0'; file_name++)
9071 if (*file_name == '.')
9072 last_period = file_name;
9073 return (last_period == NULL ? file_name : last_period);
9076 /* The function returns base name of given file name, i.e. pointer to
9077 first char after last `/' (or `\' for WIN32) in given file name,
9078 given file name itself if the directory name is absent. The
9079 returned string can not be changed. */
9081 base_file_name (file_name)
9082 const char *file_name;
9084 int directory_name_length;
9086 directory_name_length = strlen (file_name);
9088 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9089 && file_name[directory_name_length] != '\\')
9091 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9093 directory_name_length--;
9094 return file_name + directory_name_length + 1;
9097 /* The following is top level function to initialize the work of
9098 pipeline hazards description translator. */
9100 initiate_automaton_gen (argc, argv)
9104 const char *base_name;
9108 split_argument = 0; /* default value */
9109 no_minimization_flag = 0;
9113 for (i = 2; i < argc; i++)
9114 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9115 no_minimization_flag = 1;
9116 else if (strcmp (argv [i], "-time") == 0)
9118 else if (strcmp (argv [i], "-v") == 0)
9120 else if (strcmp (argv [i], W_OPTION) == 0)
9122 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9124 else if (strcmp (argv [i], "-split") == 0)
9127 fatal ("-split has no argument.");
9128 fatal ("option `-split' has not been implemented yet\n");
9129 /* split_argument = atoi (argument_vect [i + 1]); */
9131 VLA_PTR_CREATE (decls, 150, "decls");
9132 /* Initialize IR storage. */
9133 obstack_init (&irp);
9134 initiate_automaton_decl_table ();
9135 initiate_insn_decl_table ();
9136 initiate_decl_table ();
9137 output_file = stdout;
9138 output_description_file = NULL;
9139 base_name = base_file_name (argv[1]);
9140 obstack_grow (&irp, base_name,
9141 strlen (base_name) - strlen (file_name_suffix (base_name)));
9142 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9143 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9144 obstack_1grow (&irp, '\0');
9145 output_description_file_name = obstack_base (&irp);
9146 obstack_finish (&irp);
9149 /* The following function checks existence at least one arc marked by
9152 check_automata_insn_issues ()
9154 automaton_t automaton;
9155 ainsn_t ainsn, reserv_ainsn;
9157 for (automaton = description->first_automaton;
9159 automaton = automaton->next_automaton)
9161 for (ainsn = automaton->ainsn_list;
9163 ainsn = ainsn->next_ainsn)
9164 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9166 for (reserv_ainsn = ainsn;
9167 reserv_ainsn != NULL;
9168 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9169 if (automaton->corresponding_automaton_decl != NULL)
9172 error ("Automaton `%s': Insn `%s' will never be issued",
9173 automaton->corresponding_automaton_decl->name,
9174 reserv_ainsn->insn_reserv_decl->name);
9177 ("Automaton `%s': Insn `%s' will never be issued",
9178 automaton->corresponding_automaton_decl->name,
9179 reserv_ainsn->insn_reserv_decl->name);
9184 error ("Insn `%s' will never be issued",
9185 reserv_ainsn->insn_reserv_decl->name);
9187 warning ("Insn `%s' will never be issued",
9188 reserv_ainsn->insn_reserv_decl->name);
9194 /* The following vla is used for storing pointers to all achieved
9196 static vla_ptr_t automaton_states;
9198 /* This function is called by function pass_states to add an achieved
9201 add_automaton_state (state)
9204 VLA_PTR_ADD (automaton_states, state);
9207 /* The following function forms list of important automata (whose
9208 states may be changed after the insn issue) for each insn. */
9210 form_important_insn_automata_lists ()
9212 automaton_t automaton;
9219 VLA_PTR_CREATE (automaton_states, 1500,
9220 "automaton states for forming important insn automata sets");
9221 /* Mark important ainsns. */
9222 for (automaton = description->first_automaton;
9224 automaton = automaton->next_automaton)
9226 VLA_PTR_NULLIFY (automaton_states);
9227 pass_states (automaton, add_automaton_state);
9228 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9229 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9232 for (arc = first_out_arc (*state_ptr);
9234 arc = next_out_arc (arc))
9235 if (arc->to_state != *state_ptr)
9237 if (!arc->insn->first_insn_with_same_reservs)
9239 for (ainsn = arc->insn;
9241 ainsn = ainsn->next_same_reservs_insn)
9242 ainsn->important_p = TRUE;
9246 VLA_PTR_DELETE (automaton_states);
9247 /* Create automata sets for the insns. */
9248 for (i = 0; i < description->decls_num; i++)
9250 decl = description->decls [i];
9251 if (decl->mode == dm_insn_reserv)
9253 automata_list_start ();
9254 for (automaton = description->first_automaton;
9256 automaton = automaton->next_automaton)
9257 for (ainsn = automaton->ainsn_list;
9259 ainsn = ainsn->next_ainsn)
9260 if (ainsn->important_p
9261 && ainsn->insn_reserv_decl == &decl->decl.insn_reserv)
9263 automata_list_add (automaton);
9266 decl->decl.insn_reserv.important_automata_list
9267 = automata_list_finish ();
9273 /* The following is top level function to generate automat(a,on) for
9274 fast recognition of pipeline hazards. */
9280 description = create_node (sizeof (struct description)
9281 /* One entry for cycle advancing insn. */
9282 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9283 description->decls_num = VLA_PTR_LENGTH (decls);
9284 description->query_units_num = 0;
9285 for (i = 0; i < description->decls_num; i++)
9287 description->decls [i] = VLA_PTR (decls, i);
9288 if (description->decls [i]->mode == dm_unit
9289 && description->decls [i]->decl.unit.query_p)
9290 description->decls [i]->decl.unit.query_num
9291 = description->query_units_num++;
9293 all_time = create_ticker ();
9294 check_time = create_ticker ();
9295 fprintf (stderr, "Check description...");
9297 check_all_description ();
9298 fprintf (stderr, "done\n");
9299 ticker_off (&check_time);
9300 generation_time = create_ticker ();
9303 transform_insn_regexps ();
9304 check_unit_distributions_to_automata ();
9309 check_automata_insn_issues ();
9313 form_important_insn_automata_lists ();
9314 fprintf (stderr, "Generation of attributes...");
9316 make_internal_dfa_insn_code_attr ();
9317 make_insn_alts_attr ();
9318 make_default_insn_latency_attr ();
9319 make_bypass_attr ();
9320 fprintf (stderr, "done\n");
9322 ticker_off (&generation_time);
9323 ticker_off (&all_time);
9324 fprintf (stderr, "All other genattrtab stuff...");
9328 /* The following is top level function to output PHR and to finish
9329 work with pipeline description translator. */
9333 fprintf (stderr, "done\n");
9335 fatal ("Errors in DFA description");
9336 ticker_on (&all_time);
9337 output_time = create_ticker ();
9338 fprintf (stderr, "Forming and outputing automata tables...");
9340 output_dfa_max_issue_rate ();
9342 fprintf (stderr, "done\n");
9343 fprintf (stderr, "Output functions to work with automata...");
9345 output_chip_definitions ();
9346 output_max_insn_queue_index_def ();
9347 output_internal_min_issue_delay_func ();
9348 output_internal_trans_func ();
9349 /* Cache of insn dfa codes: */
9350 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9351 fprintf (output_file, "\nstatic int %s;\n\n",
9352 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9353 output_dfa_insn_code_func ();
9354 output_trans_func ();
9355 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9356 output_internal_state_alts_func ();
9357 output_state_alts_func ();
9358 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9359 AUTOMATON_STATE_ALTS_MACRO_NAME);
9360 output_min_issue_delay_func ();
9361 output_internal_dead_lock_func ();
9362 output_dead_lock_func ();
9363 output_size_func ();
9364 output_internal_reset_func ();
9365 output_reset_func ();
9366 output_min_insn_conflict_delay_func ();
9367 output_internal_insn_latency_func ();
9368 output_insn_latency_func ();
9369 output_print_reservation_func ();
9370 if (no_minimization_flag)
9372 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9373 output_get_cpu_unit_code_func ();
9374 output_cpu_unit_reservation_p ();
9375 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9376 CPU_UNITS_QUERY_MACRO_NAME);
9378 output_dfa_start_func ();
9379 output_dfa_finish_func ();
9380 fprintf (stderr, "done\n");
9383 output_description_file = fopen (output_description_file_name, "w");
9384 if (output_description_file == NULL)
9386 perror (output_description_file_name);
9387 exit (FATAL_EXIT_CODE);
9389 fprintf (stderr, "Output automata description...");
9391 output_description ();
9392 output_automaton_descriptions ();
9393 fprintf (stderr, "done\n");
9394 output_statistics (output_description_file);
9396 output_statistics (stderr);
9397 ticker_off (&output_time);
9398 output_time_statistics (stderr);
9401 finish_automata_lists ();
9404 fprintf (stderr, "Summary:\n");
9405 fprintf (stderr, " check time ");
9406 print_active_time (stderr, check_time);
9407 fprintf (stderr, ", generation time ");
9408 print_active_time (stderr, generation_time);
9409 fprintf (stderr, ", all time ");
9410 print_active_time (stderr, all_time);
9411 fprintf (stderr, "\n");
9413 /* Finish all work. */
9414 if (output_description_file != NULL)
9416 fflush (output_description_file);
9417 if (ferror (stdout) != 0)
9418 fatal ("Error in writing DFA description file %s",
9419 output_description_file_name);
9420 fclose (output_description_file);
9422 finish_automaton_decl_table ();
9423 finish_insn_decl_table ();
9424 finish_decl_table ();
9425 obstack_free (&irp, NULL);
9426 if (have_error && output_description_file != NULL)
9427 remove (output_description_file_name);