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 ? VLA_PTR_BEGIN (units_container) : NULL);
3897 for (i = 0; i < description->decls_num; i++)
3899 decl = description->decls [i];
3900 if (decl->mode == dm_unit)
3901 units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
3903 max_cycles_num = description->max_insn_reserv_cycles;
3905 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3906 / (sizeof (set_el_t) * CHAR_BIT));
3907 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3908 curr_unique_state_num = 0;
3909 initiate_alt_states ();
3910 VLA_PTR_CREATE (free_states, 1500, "free states");
3911 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3912 empty_reserv = alloc_empty_reserv_sets ();
3915 /* Finisging work with the abstract data. */
3919 VLA_PTR_DELETE (units_container);
3920 htab_delete (state_table);
3921 VLA_PTR_DELETE (free_states);
3922 finish_alt_states ();
3927 /* Abstract data `arcs'. */
3929 /* List of free arcs. */
3930 static arc_t first_free_arc;
3933 /* The following variables is maximal number of allocated nodes
3935 static int allocated_arcs_num = 0;
3938 /* The function frees node ARC. */
3943 arc->next_out_arc = first_free_arc;
3944 first_free_arc = arc;
3947 /* The function removes and frees ARC staring from FROM_STATE. */
3949 remove_arc (from_state, arc)
3958 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3960 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3961 if (curr_arc == arc)
3963 if (curr_arc == NULL)
3965 if (prev_arc == NULL)
3966 from_state->first_out_arc = arc->next_out_arc;
3968 prev_arc->next_out_arc = arc->next_out_arc;
3972 /* The functions returns arc with given characteristics (or NULL if
3973 the arc does not exist). */
3975 find_arc (from_state, to_state, insn)
3982 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3983 if (arc->to_state == to_state && arc->insn == insn)
3988 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
3989 and with given STATE_ALTS. The function returns added arc (or
3990 already existing arc). */
3992 add_arc (from_state, to_state, ainsn, state_alts)
4000 new_arc = find_arc (from_state, to_state, ainsn);
4001 if (new_arc != NULL)
4003 if (first_free_arc == NULL)
4006 allocated_arcs_num++;
4008 new_arc = create_node (sizeof (struct arc));
4009 new_arc->to_state = NULL;
4010 new_arc->insn = NULL;
4011 new_arc->next_out_arc = NULL;
4015 new_arc = first_free_arc;
4016 first_free_arc = first_free_arc->next_out_arc;
4018 new_arc->to_state = to_state;
4019 new_arc->insn = ainsn;
4020 ainsn->arc_exists_p = 1;
4021 new_arc->next_out_arc = from_state->first_out_arc;
4022 from_state->first_out_arc = new_arc;
4023 new_arc->next_arc_marked_by_insn = NULL;
4024 new_arc->state_alts = state_alts;
4028 /* The function returns the first arc starting from STATE. */
4030 first_out_arc (state)
4033 return state->first_out_arc;
4036 /* The function returns next out arc after ARC. */
4041 return arc->next_out_arc;
4044 /* Initialization of the abstract data. */
4048 first_free_arc = NULL;
4051 /* Finishing work with the abstract data. */
4059 /* Abstract data `automata lists'. */
4061 /* List of free states. */
4062 static automata_list_el_t first_free_automata_list_el;
4064 /* The list being formed. */
4065 static automata_list_el_t current_automata_list;
4067 /* Hash table of automata lists. */
4068 static htab_t automata_list_table;
4070 /* The following function returns free automata list el. It may be
4071 new allocated node or node freed earlier. */
4072 static automata_list_el_t
4073 get_free_automata_list_el ()
4075 automata_list_el_t result;
4077 if (first_free_automata_list_el != NULL)
4079 result = first_free_automata_list_el;
4080 first_free_automata_list_el
4081 = first_free_automata_list_el->next_automata_list_el;
4084 result = create_node (sizeof (struct automata_list_el));
4085 result->automaton = NULL;
4086 result->next_automata_list_el = NULL;
4090 /* The function frees node AUTOMATA_LIST_EL. */
4092 free_automata_list_el (automata_list_el)
4093 automata_list_el_t automata_list_el;
4095 if (automata_list_el == NULL)
4097 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4098 first_free_automata_list_el = automata_list_el;
4101 /* The function frees list AUTOMATA_LIST. */
4103 free_automata_list (automata_list)
4104 automata_list_el_t automata_list;
4106 automata_list_el_t curr_automata_list_el;
4107 automata_list_el_t next_automata_list_el;
4109 for (curr_automata_list_el = automata_list;
4110 curr_automata_list_el != NULL;
4111 curr_automata_list_el = next_automata_list_el)
4113 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4114 free_automata_list_el (curr_automata_list_el);
4118 /* Hash value of AUTOMATA_LIST. */
4120 automata_list_hash (automata_list)
4121 const void *automata_list;
4123 unsigned int hash_value;
4124 automata_list_el_t curr_automata_list_el;
4127 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4128 curr_automata_list_el != NULL;
4129 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4130 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4131 | (hash_value << CHAR_BIT))
4132 + curr_automata_list_el->automaton->automaton_order_num);
4136 /* Return nonzero value if the automata_lists are the same. */
4138 automata_list_eq_p (automata_list_1, automata_list_2)
4139 const void *automata_list_1;
4140 const void *automata_list_2;
4142 automata_list_el_t automata_list_el_1;
4143 automata_list_el_t automata_list_el_2;
4145 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4146 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4147 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4148 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4149 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4150 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4152 return automata_list_el_1 == automata_list_el_2;
4155 /* Initialization of the abstract data. */
4157 initiate_automata_lists ()
4159 first_free_automata_list_el = NULL;
4160 automata_list_table = htab_create (1500, automata_list_hash,
4161 automata_list_eq_p, (htab_del) 0);
4164 /* The following function starts new automata list and makes it the
4167 automata_list_start ()
4169 current_automata_list = NULL;
4172 /* The following function adds AUTOMATON to the current list. */
4174 automata_list_add (automaton)
4175 automaton_t automaton;
4177 automata_list_el_t el;
4179 el = get_free_automata_list_el ();
4180 el->automaton = automaton;
4181 el->next_automata_list_el = current_automata_list;
4182 current_automata_list = el;
4185 /* The following function finishes forming the current list, inserts
4186 it into the table and returns it. */
4187 static automata_list_el_t
4188 automata_list_finish ()
4192 if (current_automata_list == NULL)
4194 entry_ptr = htab_find_slot (automata_list_table,
4195 (void *) current_automata_list, 1);
4196 if (*entry_ptr == NULL)
4197 *entry_ptr = (void *) current_automata_list;
4199 free_automata_list (current_automata_list);
4200 current_automata_list = NULL;
4201 return (automata_list_el_t) *entry_ptr;
4204 /* Finishing work with the abstract data. */
4206 finish_automata_lists ()
4208 htab_delete (automata_list_table);
4213 /* The page contains abstract data for work with exclusion sets (see
4214 exclusion_set in file rtl.def). */
4216 /* The following variable refers to an exclusion set returned by
4217 get_excl_set. This is bit string of length equal to cpu units
4218 number. If exclusion set for given unit contains 1 for a unit,
4219 then simultaneous reservation of the units is prohibited. */
4220 static reserv_sets_t excl_set;
4222 /* The array contains exclusion sets for each unit. */
4223 static reserv_sets_t *unit_excl_set_table;
4225 /* The following function forms the array containing exclusion sets
4228 initiate_excl_sets ()
4231 reserv_sets_t unit_excl_set;
4235 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4236 excl_set = (reserv_sets_t) obstack_base (&irp);
4237 obstack_finish (&irp);
4238 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4239 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4240 obstack_finish (&irp);
4241 /* Evaluate unit exclusion sets. */
4242 for (i = 0; i < description->decls_num; i++)
4244 decl = description->decls [i];
4245 if (decl->mode == dm_unit)
4247 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4248 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4249 obstack_finish (&irp);
4250 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4251 for (el = decl->decl.unit.excl_list;
4253 el = el->next_unit_set_el)
4254 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4255 unit_excl_set_table [decl->decl.unit.unit_num] = unit_excl_set;
4260 /* The function sets up and return EXCL_SET which is union of
4261 exclusion sets for each unit in IN_SET. */
4262 static reserv_sets_t
4263 get_excl_set (in_set)
4264 reserv_sets_t in_set;
4272 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4273 memset (excl_set, 0, chars_num);
4274 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4275 if (((unsigned char *) in_set) [excl_char_num])
4276 for (i = CHAR_BIT - 1; i >= 0; i--)
4277 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4279 start_unit_num = excl_char_num * CHAR_BIT + i;
4280 if (start_unit_num >= description->units_num)
4282 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4285 |= unit_excl_set_table [start_unit_num] [unit_num];
4293 /* The page contains abstract data for work with presence/absence sets
4294 (see presence_set/absence_set in file rtl.def). */
4296 /* The following variables refer to correspondingly an presence and an
4297 absence set returned by get_presence_absence_set. This is bit
4298 string of length equal to cpu units number. */
4299 static reserv_sets_t presence_set, absence_set;
4301 /* The following arrays contain correspondingly presence and absence
4302 sets for each unit. */
4303 static reserv_sets_t *unit_presence_set_table, *unit_absence_set_table;
4305 /* The following function forms the array containing presence and
4306 absence sets for each unit */
4308 initiate_presence_absence_sets ()
4311 reserv_sets_t unit_set;
4315 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4316 presence_set = (reserv_sets_t) obstack_base (&irp);
4317 obstack_finish (&irp);
4318 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4319 unit_presence_set_table = (reserv_sets_t *) obstack_base (&irp);
4320 obstack_finish (&irp);
4321 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4322 absence_set = (reserv_sets_t) obstack_base (&irp);
4323 obstack_finish (&irp);
4324 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4325 unit_absence_set_table = (reserv_sets_t *) obstack_base (&irp);
4326 obstack_finish (&irp);
4327 /* Evaluate unit presence/absence sets. */
4328 for (i = 0; i < description->decls_num; i++)
4330 decl = description->decls [i];
4331 if (decl->mode == dm_unit)
4333 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4334 unit_set = (reserv_sets_t) obstack_base (&irp);
4335 obstack_finish (&irp);
4336 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4337 for (el = decl->decl.unit.presence_list;
4339 el = el->next_unit_set_el)
4340 SET_BIT (unit_set, el->unit_decl->unit_num);
4341 unit_presence_set_table [decl->decl.unit.unit_num] = unit_set;
4343 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4344 unit_set = (reserv_sets_t) obstack_base (&irp);
4345 obstack_finish (&irp);
4346 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4347 for (el = decl->decl.unit.absence_list;
4349 el = el->next_unit_set_el)
4350 SET_BIT (unit_set, el->unit_decl->unit_num);
4351 unit_absence_set_table [decl->decl.unit.unit_num] = unit_set;
4356 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4357 ABSENCE_SET which is union of corresponding sets for each unit in
4359 static reserv_sets_t
4360 get_presence_absence_set (in_set, presence_p)
4361 reserv_sets_t in_set;
4370 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4372 memset (presence_set, 0, chars_num);
4374 memset (absence_set, 0, chars_num);
4375 for (char_num = 0; char_num < chars_num; char_num++)
4376 if (((unsigned char *) in_set) [char_num])
4377 for (i = CHAR_BIT - 1; i >= 0; i--)
4378 if ((((unsigned char *) in_set) [char_num] >> i) & 1)
4380 start_unit_num = char_num * CHAR_BIT + i;
4381 if (start_unit_num >= description->units_num)
4382 return (presence_p ? presence_set : absence_set);
4383 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4385 presence_set [unit_num]
4386 |= unit_presence_set_table [start_unit_num] [unit_num];
4388 absence_set [unit_num]
4389 |= unit_absence_set_table [start_unit_num] [unit_num];
4391 return (presence_p ? presence_set : absence_set);
4396 /* This page contains code for transformation of original reservations
4397 described in .md file. The main goal of transformations is
4398 simplifying reservation and lifting up all `|' on the top of IR
4399 reservation representation. */
4402 /* The following function makes copy of IR representation of
4403 reservation. The function also substitutes all reservations
4404 defined by define_reservation by corresponding value during making
4407 copy_insn_regexp (regexp)
4413 if (regexp->mode == rm_reserv)
4414 result = copy_insn_regexp (regexp->regexp.reserv.reserv_decl->regexp);
4415 else if (regexp->mode == rm_unit)
4416 result = copy_node (regexp, sizeof (struct regexp));
4417 else if (regexp->mode == rm_repeat)
4419 result = copy_node (regexp, sizeof (struct regexp));
4420 result->regexp.repeat.regexp
4421 = copy_insn_regexp (regexp->regexp.repeat.regexp);
4423 else if (regexp->mode == rm_sequence)
4425 result = copy_node (regexp,
4426 sizeof (struct regexp) + sizeof (regexp_t)
4427 * (regexp->regexp.sequence.regexps_num - 1));
4428 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4429 result->regexp.sequence.regexps [i]
4430 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4432 else if (regexp->mode == rm_allof)
4434 result = copy_node (regexp,
4435 sizeof (struct regexp) + sizeof (regexp_t)
4436 * (regexp->regexp.allof.regexps_num - 1));
4437 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4438 result->regexp.allof.regexps [i]
4439 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4441 else if (regexp->mode == rm_oneof)
4443 result = copy_node (regexp,
4444 sizeof (struct regexp) + sizeof (regexp_t)
4445 * (regexp->regexp.oneof.regexps_num - 1));
4446 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4447 result->regexp.oneof.regexps [i]
4448 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4452 if (regexp->mode != rm_nothing)
4454 result = copy_node (regexp, sizeof (struct regexp));
4459 /* The following variable is set up 1 if a transformation has been
4461 static int regexp_transformed_p;
4463 /* The function makes transformation
4466 transform_1 (regexp)
4474 if (regexp->mode == rm_repeat)
4476 repeat_num = regexp->regexp.repeat.repeat_num;
4477 if (repeat_num <= 1)
4479 operand = regexp->regexp.repeat.regexp;
4481 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4482 * (repeat_num - 1));
4483 regexp->mode = rm_sequence;
4485 regexp->regexp.sequence.regexps_num = repeat_num;
4486 for (i = 0; i < repeat_num; i++)
4487 regexp->regexp.sequence.regexps [i] = copy_insn_regexp (operand);
4488 regexp_transformed_p = 1;
4493 /* The function makes transformations
4494 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4495 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4496 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4498 transform_2 (regexp)
4501 if (regexp->mode == rm_sequence)
4508 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4509 if (regexp->regexp.sequence.regexps [i]->mode == rm_sequence)
4512 sequence = regexp->regexp.sequence.regexps [i];
4515 if (i < regexp->regexp.sequence.regexps_num)
4517 if (sequence->regexp.sequence.regexps_num <= 1
4518 || regexp->regexp.sequence.regexps_num <= 1)
4520 result = create_node (sizeof (struct regexp)
4522 * (regexp->regexp.sequence.regexps_num
4523 + sequence->regexp.sequence.regexps_num
4525 result->mode = rm_sequence;
4526 result->pos = regexp->pos;
4527 result->regexp.sequence.regexps_num
4528 = (regexp->regexp.sequence.regexps_num
4529 + sequence->regexp.sequence.regexps_num - 1);
4530 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4531 if (i < sequence_index)
4532 result->regexp.sequence.regexps [i]
4533 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4534 else if (i > sequence_index)
4535 result->regexp.sequence.regexps
4536 [i + sequence->regexp.sequence.regexps_num - 1]
4537 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4539 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4540 result->regexp.sequence.regexps [i + j]
4541 = copy_insn_regexp (sequence->regexp.sequence.regexps [j]);
4542 regexp_transformed_p = 1;
4546 else if (regexp->mode == rm_allof)
4553 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4554 if (regexp->regexp.allof.regexps [i]->mode == rm_allof)
4557 allof = regexp->regexp.allof.regexps [i];
4560 if (i < regexp->regexp.allof.regexps_num)
4562 if (allof->regexp.allof.regexps_num <= 1
4563 || regexp->regexp.allof.regexps_num <= 1)
4565 result = create_node (sizeof (struct regexp)
4567 * (regexp->regexp.allof.regexps_num
4568 + allof->regexp.allof.regexps_num - 2));
4569 result->mode = rm_allof;
4570 result->pos = regexp->pos;
4571 result->regexp.allof.regexps_num
4572 = (regexp->regexp.allof.regexps_num
4573 + allof->regexp.allof.regexps_num - 1);
4574 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4575 if (i < allof_index)
4576 result->regexp.allof.regexps [i]
4577 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4578 else if (i > allof_index)
4579 result->regexp.allof.regexps
4580 [i + allof->regexp.allof.regexps_num - 1]
4581 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4583 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4584 result->regexp.allof.regexps [i + j]
4585 = copy_insn_regexp (allof->regexp.allof.regexps [j]);
4586 regexp_transformed_p = 1;
4590 else if (regexp->mode == rm_oneof)
4597 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4598 if (regexp->regexp.oneof.regexps [i]->mode == rm_oneof)
4601 oneof = regexp->regexp.oneof.regexps [i];
4604 if (i < regexp->regexp.oneof.regexps_num)
4606 if (oneof->regexp.oneof.regexps_num <= 1
4607 || regexp->regexp.oneof.regexps_num <= 1)
4609 result = create_node (sizeof (struct regexp)
4611 * (regexp->regexp.oneof.regexps_num
4612 + oneof->regexp.oneof.regexps_num - 2));
4613 result->mode = rm_oneof;
4614 result->pos = regexp->pos;
4615 result->regexp.oneof.regexps_num
4616 = (regexp->regexp.oneof.regexps_num
4617 + oneof->regexp.oneof.regexps_num - 1);
4618 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4619 if (i < oneof_index)
4620 result->regexp.oneof.regexps [i]
4621 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4622 else if (i > oneof_index)
4623 result->regexp.oneof.regexps
4624 [i + oneof->regexp.oneof.regexps_num - 1]
4625 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4627 for (j = 0; j < oneof->regexp.oneof.regexps_num; j++)
4628 result->regexp.oneof.regexps [i + j]
4629 = copy_insn_regexp (oneof->regexp.oneof.regexps [j]);
4630 regexp_transformed_p = 1;
4637 /* The function makes transformations
4638 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4639 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|... */
4641 transform_3 (regexp)
4644 if (regexp->mode == rm_sequence)
4652 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4653 if (regexp->regexp.sequence.regexps [i]->mode == rm_oneof)
4656 oneof = regexp->regexp.sequence.regexps [i];
4659 if (i < regexp->regexp.sequence.regexps_num)
4661 if (oneof->regexp.oneof.regexps_num <= 1
4662 || regexp->regexp.sequence.regexps_num <= 1)
4664 result = create_node (sizeof (struct regexp)
4666 * (oneof->regexp.oneof.regexps_num - 1));
4667 result->mode = rm_oneof;
4668 result->pos = regexp->pos;
4669 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4670 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4673 = create_node (sizeof (struct regexp)
4675 * (regexp->regexp.sequence.regexps_num - 1));
4676 sequence->mode = rm_sequence;
4677 sequence->pos = regexp->pos;
4678 sequence->regexp.sequence.regexps_num
4679 = regexp->regexp.sequence.regexps_num;
4680 result->regexp.oneof.regexps [i] = sequence;
4681 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4682 if (j != oneof_index)
4683 sequence->regexp.sequence.regexps [j]
4684 = copy_insn_regexp (regexp->regexp.sequence.regexps [j]);
4686 sequence->regexp.sequence.regexps [j]
4687 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4689 regexp_transformed_p = 1;
4693 else if (regexp->mode == rm_allof)
4701 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4702 if (regexp->regexp.allof.regexps [i]->mode == rm_oneof)
4705 oneof = regexp->regexp.allof.regexps [i];
4708 if (i < regexp->regexp.allof.regexps_num)
4710 if (oneof->regexp.oneof.regexps_num <= 1
4711 || regexp->regexp.allof.regexps_num <= 1)
4713 result = create_node (sizeof (struct regexp)
4715 * (oneof->regexp.oneof.regexps_num - 1));
4716 result->mode = rm_oneof;
4717 result->pos = regexp->pos;
4718 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4719 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4722 = create_node (sizeof (struct regexp)
4724 * (regexp->regexp.allof.regexps_num - 1));
4725 allof->mode = rm_allof;
4726 allof->pos = regexp->pos;
4727 allof->regexp.allof.regexps_num
4728 = regexp->regexp.allof.regexps_num;
4729 result->regexp.oneof.regexps [i] = allof;
4730 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4731 if (j != oneof_index)
4732 allof->regexp.allof.regexps [j]
4733 = copy_insn_regexp (regexp->regexp.allof.regexps [j]);
4735 allof->regexp.allof.regexps [j]
4736 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4738 regexp_transformed_p = 1;
4745 /* The function traverses IR of reservation and applies transformations
4746 implemented by FUNC. */
4748 regexp_transform_func (regexp, func)
4750 regexp_t (*func) PARAMS ((regexp_t regexp));
4754 if (regexp->mode == rm_sequence)
4755 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4756 regexp->regexp.sequence.regexps [i]
4757 = regexp_transform_func (regexp->regexp.sequence.regexps [i], func);
4758 else if (regexp->mode == rm_allof)
4759 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4760 regexp->regexp.allof.regexps [i]
4761 = regexp_transform_func (regexp->regexp.allof.regexps [i], func);
4762 else if (regexp->mode == rm_oneof)
4763 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4764 regexp->regexp.oneof.regexps [i]
4765 = regexp_transform_func (regexp->regexp.oneof.regexps [i], func);
4766 else if (regexp->mode == rm_repeat)
4767 regexp->regexp.repeat.regexp
4768 = regexp_transform_func (regexp->regexp.repeat.regexp, func);
4769 else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
4771 return (*func) (regexp);
4774 /* The function applies all transformations for IR representation of
4775 reservation REGEXP. */
4777 transform_regexp (regexp)
4780 regexp = regexp_transform_func (regexp, transform_1);
4783 regexp_transformed_p = 0;
4784 regexp = regexp_transform_func (regexp, transform_2);
4785 regexp = regexp_transform_func (regexp, transform_3);
4787 while (regexp_transformed_p);
4791 /* The function applys all transformations for reservations of all
4792 insn declarations. */
4794 transform_insn_regexps ()
4799 transform_time = create_ticker ();
4800 add_advance_cycle_insn_decl ();
4801 fprintf (stderr, "Reservation transformation...");
4803 for (i = 0; i < description->decls_num; i++)
4805 decl = description->decls [i];
4806 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4807 decl->decl.insn_reserv.transformed_regexp
4808 = transform_regexp (copy_insn_regexp
4809 (decl->decl.insn_reserv.regexp));
4811 fprintf (stderr, "done\n");
4812 ticker_off (&transform_time);
4818 /* The following variable is an array indexed by cycle. Each element
4819 contains cyclic list of units which should be in the same cycle. */
4820 static unit_decl_t *the_same_automaton_lists;
4822 /* The function processes all alternative reservations on CYCLE in
4823 given REGEXP to check the UNIT is not reserved on the all
4824 alternatives. If it is true, the unit should be in the same
4825 automaton with other analogous units reserved on CYCLE in given
4828 process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
4834 regexp_t seq, allof;
4835 unit_decl_t unit_decl, last;
4837 if (regexp == NULL || regexp->mode != rm_oneof)
4839 unit_decl = unit->regexp.unit.unit_decl;
4840 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4842 seq = regexp->regexp.oneof.regexps [i];
4843 if (seq->mode == rm_sequence)
4845 if (cycle >= seq->regexp.sequence.regexps_num)
4847 allof = seq->regexp.sequence.regexps [cycle];
4848 if (allof->mode == rm_allof)
4850 for (k = 0; k < allof->regexp.allof.regexps_num; k++)
4851 if (allof->regexp.allof.regexps [k]->mode == rm_unit
4852 && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
4855 if (k >= allof->regexp.allof.regexps_num)
4858 else if (allof->mode == rm_unit
4859 && allof->regexp.unit.unit_decl != unit_decl)
4862 else if (cycle != 0)
4864 else if (seq->mode == rm_allof)
4866 for (k = 0; k < seq->regexp.allof.regexps_num; k++)
4867 if (seq->regexp.allof.regexps [k]->mode == rm_unit
4868 && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
4871 if (k >= seq->regexp.allof.regexps_num)
4874 else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
4879 if (the_same_automaton_lists [cycle] == NULL)
4880 the_same_automaton_lists [cycle] = unit_decl;
4883 for (last = the_same_automaton_lists [cycle];;)
4885 if (last == unit_decl)
4887 if (last->the_same_automaton_unit
4888 == the_same_automaton_lists [cycle])
4890 last = last->the_same_automaton_unit;
4892 last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
4893 unit_decl->the_same_automaton_unit
4894 = the_same_automaton_lists [cycle];
4899 /* The function processes given REGEXP to find units which should be
4900 in the same automaton. */
4902 form_the_same_automaton_unit_lists_from_regexp (regexp)
4906 regexp_t seq, allof, unit;
4908 if (regexp == NULL || regexp->mode != rm_oneof)
4910 for (i = 0; i < description->max_insn_reserv_cycles; i++)
4911 the_same_automaton_lists [i] = NULL;
4912 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4914 seq = regexp->regexp.oneof.regexps [i];
4915 if (seq->mode == rm_sequence)
4916 for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
4918 allof = seq->regexp.sequence.regexps [j];
4919 if (allof->mode == rm_allof)
4920 for (k = 0; k < allof->regexp.allof.regexps_num; k++)
4922 unit = allof->regexp.allof.regexps [k];
4923 if (unit->mode == rm_unit)
4924 process_unit_to_form_the_same_automaton_unit_lists
4926 else if (allof->mode != rm_nothing)
4929 else if (allof->mode == rm_unit)
4930 process_unit_to_form_the_same_automaton_unit_lists
4932 else if (allof->mode != rm_nothing)
4935 else if (seq->mode == rm_allof)
4936 for (k = 0; k < seq->regexp.allof.regexps_num; k++)
4938 unit = seq->regexp.allof.regexps [k];
4939 if (unit->mode == rm_unit)
4940 process_unit_to_form_the_same_automaton_unit_lists
4942 else if (unit->mode != rm_nothing)
4945 else if (seq->mode == rm_unit)
4946 process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
4947 else if (seq->mode != rm_nothing)
4952 /* The function initializes data to search for units which should be
4953 in the same automaton and call function
4954 `form_the_same_automaton_unit_lists_from_regexp' for each insn
4955 reservation regexp. */
4957 form_the_same_automaton_unit_lists ()
4962 the_same_automaton_lists
4963 = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
4964 * sizeof (unit_decl_t));
4965 for (i = 0; i < description->decls_num; i++)
4967 decl = description->decls [i];
4968 if (decl->mode == dm_unit)
4970 decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
4971 decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
4974 for (i = 0; i < description->decls_num; i++)
4976 decl = description->decls [i];
4977 if (decl->mode == dm_insn_reserv)
4978 form_the_same_automaton_unit_lists_from_regexp
4979 (decl->decl.insn_reserv.transformed_regexp);
4981 free (the_same_automaton_lists);
4984 /* The function finds units which should be in the same automaton and,
4985 if they are not, reports about it. */
4987 check_unit_distributions_to_automata ()
4990 unit_decl_t start_unit_decl, unit_decl;
4993 form_the_same_automaton_unit_lists ();
4994 for (i = 0; i < description->decls_num; i++)
4996 decl = description->decls [i];
4997 if (decl->mode == dm_unit)
4999 start_unit_decl = &decl->decl.unit;
5000 if (!start_unit_decl->the_same_automaton_message_reported_p)
5001 for (unit_decl = start_unit_decl->the_same_automaton_unit;
5002 unit_decl != start_unit_decl;
5003 unit_decl = unit_decl->the_same_automaton_unit)
5004 if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
5006 error ("Units `%s' and `%s' should be in the same automaton",
5007 start_unit_decl->name, unit_decl->name);
5008 unit_decl->the_same_automaton_message_reported_p = TRUE;
5016 /* The page contains code for building alt_states (see comments for
5017 IR) describing all possible insns reservations of an automaton. */
5019 /* Current state being formed for which the current alt_state
5021 static state_t state_being_formed;
5023 /* Current alt_state being formed. */
5024 static alt_state_t alt_state_being_formed;
5026 /* This recursive function processes `,' and units in reservation
5027 REGEXP for forming alt_states of AUTOMATON. It is believed that
5028 CURR_CYCLE is start cycle of all reservation REGEXP. */
5030 process_seq_for_forming_states (regexp, automaton, curr_cycle)
5032 automaton_t automaton;
5039 else if (regexp->mode == rm_unit)
5041 if (regexp->regexp.unit.unit_decl->corresponding_automaton_num
5042 == automaton->automaton_order_num)
5043 set_state_reserv (state_being_formed, curr_cycle,
5044 regexp->regexp.unit.unit_decl->unit_num);
5047 else if (regexp->mode == rm_sequence)
5049 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
5051 = process_seq_for_forming_states
5052 (regexp->regexp.sequence.regexps [i], automaton, curr_cycle) + 1;
5055 else if (regexp->mode == rm_allof)
5057 int finish_cycle = 0;
5060 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
5063 = process_seq_for_forming_states (regexp->regexp.allof.regexps [i],
5064 automaton, curr_cycle);
5065 if (finish_cycle < cycle)
5066 finish_cycle = cycle;
5068 return finish_cycle;
5072 if (regexp->mode != rm_nothing)
5078 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5079 inserts alt_state into the table. */
5081 finish_forming_alt_state (alt_state, automaton)
5082 alt_state_t alt_state;
5083 automaton_t automaton ATTRIBUTE_UNUSED;
5085 state_t state_in_table;
5086 state_t corresponding_state;
5088 corresponding_state = alt_state->state;
5089 state_in_table = insert_state (corresponding_state);
5090 if (state_in_table != corresponding_state)
5092 free_state (corresponding_state);
5093 alt_state->state = state_in_table;
5097 /* The following variable value is current automaton insn for whose
5098 reservation the alt states are created. */
5099 static ainsn_t curr_ainsn;
5101 /* This recursive function processes `|' in reservation REGEXP for
5102 forming alt_states of AUTOMATON. List of the alt states should
5103 have the same order as in the description. */
5105 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
5107 automaton_t automaton;
5112 if (regexp->mode != rm_oneof)
5114 alt_state_being_formed = get_free_alt_state ();
5115 state_being_formed = get_free_state (1, automaton);
5116 alt_state_being_formed->state = state_being_formed;
5117 /* We inserts in reverse order but we process alternatives also
5118 in reverse order. So we have the same order of alternative
5119 as in the description. */
5120 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5121 curr_ainsn->alt_states = alt_state_being_formed;
5122 (void) process_seq_for_forming_states (regexp, automaton, 0);
5123 finish_forming_alt_state (alt_state_being_formed, automaton);
5129 /* We processes it in reverse order to get list with the same
5130 order as in the description. See also the previous
5132 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
5133 process_alts_for_forming_states (regexp->regexp.oneof.regexps [i],
5138 /* Create nodes alt_state for all AUTOMATON insns. */
5140 create_alt_states (automaton)
5141 automaton_t automaton;
5143 struct insn_reserv_decl *reserv_decl;
5145 for (curr_ainsn = automaton->ainsn_list;
5147 curr_ainsn = curr_ainsn->next_ainsn)
5149 reserv_decl = curr_ainsn->insn_reserv_decl;
5150 if (reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5152 curr_ainsn->alt_states = NULL;
5153 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5155 curr_ainsn->sorted_alt_states
5156 = uniq_sort_alt_states (curr_ainsn->alt_states);
5163 /* The page contains major code for building DFA(s) for fast pipeline
5164 hazards recognition. */
5166 /* The function forms list of ainsns of AUTOMATON with the same
5169 form_ainsn_with_same_reservs (automaton)
5170 automaton_t automaton;
5174 vla_ptr_t first_insns;
5175 vla_ptr_t last_insns;
5177 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5178 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5179 for (curr_ainsn = automaton->ainsn_list;
5181 curr_ainsn = curr_ainsn->next_ainsn)
5182 if (curr_ainsn->insn_reserv_decl
5183 == &advance_cycle_insn_decl->decl.insn_reserv)
5185 curr_ainsn->next_same_reservs_insn = NULL;
5186 curr_ainsn->first_insn_with_same_reservs = 1;
5190 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5192 (curr_ainsn->sorted_alt_states,
5193 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5195 curr_ainsn->next_same_reservs_insn = NULL;
5196 if (i < VLA_PTR_LENGTH (first_insns))
5198 curr_ainsn->first_insn_with_same_reservs = 0;
5199 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5201 VLA_PTR (last_insns, i) = curr_ainsn;
5205 VLA_PTR_ADD (first_insns, curr_ainsn);
5206 VLA_PTR_ADD (last_insns, curr_ainsn);
5207 curr_ainsn->first_insn_with_same_reservs = 1;
5210 VLA_PTR_DELETE (first_insns);
5211 VLA_PTR_DELETE (last_insns);
5214 /* The following function creates all states of nondeterministic (if
5215 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5217 make_automaton (automaton)
5218 automaton_t automaton;
5221 struct insn_reserv_decl *insn_reserv_decl;
5222 alt_state_t alt_state;
5224 state_t start_state;
5226 ainsn_t advance_cycle_ainsn;
5228 vla_ptr_t state_stack;
5230 VLA_PTR_CREATE (state_stack, 150, "state stack");
5231 /* Create the start state (empty state). */
5232 start_state = insert_state (get_free_state (1, automaton));
5233 automaton->start_state = start_state;
5234 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5235 VLA_PTR_ADD (state_stack, start_state);
5236 while (VLA_PTR_LENGTH (state_stack) != 0)
5238 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5239 VLA_PTR_SHORTEN (state_stack, 1);
5240 advance_cycle_ainsn = NULL;
5241 for (ainsn = automaton->ainsn_list;
5243 ainsn = ainsn->next_ainsn)
5244 if (ainsn->first_insn_with_same_reservs)
5246 insn_reserv_decl = ainsn->insn_reserv_decl;
5247 if (insn_reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5249 /* We process alt_states in the same order as they are
5250 present in the description. */
5252 for (alt_state = ainsn->alt_states;
5254 alt_state = alt_state->next_alt_state)
5256 state2 = alt_state->state;
5257 if (!intersected_state_reservs_p (state, state2))
5259 state2 = states_union (state, state2);
5260 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5262 state2->it_was_placed_in_stack_for_NDFA_forming
5264 VLA_PTR_ADD (state_stack, state2);
5266 added_arc = add_arc (state, state2, ainsn, 1);
5271 if (!ndfa_flag && added_arc != NULL)
5273 added_arc->state_alts = 0;
5274 for (alt_state = ainsn->alt_states;
5276 alt_state = alt_state->next_alt_state)
5278 state2 = alt_state->state;
5279 if (!intersected_state_reservs_p (state, state2))
5280 added_arc->state_alts++;
5285 advance_cycle_ainsn = ainsn;
5287 /* Add transition to advance cycle. */
5288 state2 = state_shift (state);
5289 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5291 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5292 VLA_PTR_ADD (state_stack, state2);
5294 if (advance_cycle_ainsn == NULL)
5296 add_arc (state, state2, advance_cycle_ainsn, 1);
5298 VLA_PTR_DELETE (state_stack);
5301 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5303 form_arcs_marked_by_insn (state)
5310 for (i = 0; i < description->decls_num; i++)
5312 decl = description->decls [i];
5313 if (decl->mode == dm_insn_reserv)
5314 decl->decl.insn_reserv.arcs_marked_by_insn = NULL;
5316 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5318 if (arc->insn == NULL)
5320 arc->next_arc_marked_by_insn
5321 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5322 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5326 /* The function creates composed state (see comments for IR) from
5327 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5328 same insn. If the composed state is not in STATE_STACK yet, it is
5329 popped to STATE_STACK. */
5331 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5332 state_t original_state;
5333 arc_t arcs_marked_by_insn;
5334 vla_ptr_t *state_stack;
5337 alt_state_t curr_alt_state;
5338 alt_state_t new_alt_state;
5341 state_t state_in_table;
5343 alt_state_t canonical_alt_states_list;
5346 if (arcs_marked_by_insn == NULL)
5348 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5349 state = arcs_marked_by_insn->to_state;
5354 /* Create composed state. */
5355 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5356 curr_alt_state = NULL;
5357 for (curr_arc = arcs_marked_by_insn;
5359 curr_arc = curr_arc->next_arc_marked_by_insn)
5361 new_alt_state = get_free_alt_state ();
5362 new_alt_state->next_alt_state = curr_alt_state;
5363 new_alt_state->state = curr_arc->to_state;
5364 if (curr_arc->to_state->component_states != NULL)
5366 curr_alt_state = new_alt_state;
5368 /* There are not identical sets in the alt state list. */
5369 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5370 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5373 state = canonical_alt_states_list->state;
5374 free_state (temp_state);
5378 state->component_states = canonical_alt_states_list;
5379 state_in_table = insert_state (state);
5380 if (state_in_table != state)
5382 if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5385 state = state_in_table;
5389 if (state->it_was_placed_in_stack_for_DFA_forming)
5391 for (curr_alt_state = state->component_states;
5392 curr_alt_state != NULL;
5393 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5394 for (curr_arc = first_out_arc (curr_alt_state->state);
5396 curr_arc = next_out_arc (curr_arc))
5397 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5399 arcs_marked_by_insn->to_state = state;
5400 for (alts_number = 0,
5401 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5403 curr_arc = next_arc)
5405 next_arc = curr_arc->next_arc_marked_by_insn;
5406 remove_arc (original_state, curr_arc);
5409 arcs_marked_by_insn->state_alts = alts_number;
5412 if (!state->it_was_placed_in_stack_for_DFA_forming)
5414 state->it_was_placed_in_stack_for_DFA_forming = 1;
5415 VLA_PTR_ADD (*state_stack, state);
5419 /* The function transformes nondeterminstic AUTOMATON into
5422 NDFA_to_DFA (automaton)
5423 automaton_t automaton;
5425 state_t start_state;
5428 vla_ptr_t state_stack;
5431 VLA_PTR_CREATE (state_stack, 150, "state stack");
5432 /* Create the start state (empty state). */
5433 start_state = automaton->start_state;
5434 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5435 VLA_PTR_ADD (state_stack, start_state);
5436 while (VLA_PTR_LENGTH (state_stack) != 0)
5438 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5439 VLA_PTR_SHORTEN (state_stack, 1);
5440 form_arcs_marked_by_insn (state);
5441 for (i = 0; i < description->decls_num; i++)
5443 decl = description->decls [i];
5444 if (decl->mode == dm_insn_reserv)
5445 create_composed_state
5446 (state, decl->decl.insn_reserv.arcs_marked_by_insn,
5450 VLA_PTR_DELETE (state_stack);
5453 /* The following variable value is current number (1, 2, ...) of passing
5455 static int curr_state_graph_pass_num;
5457 /* This recursive function passes all states achieved from START_STATE
5458 and applies APPLIED_FUNC to them. */
5460 pass_state_graph (start_state, applied_func)
5461 state_t start_state;
5462 void (*applied_func) PARAMS ((state_t state));
5466 if (start_state->pass_num == curr_state_graph_pass_num)
5468 start_state->pass_num = curr_state_graph_pass_num;
5469 (*applied_func) (start_state);
5470 for (arc = first_out_arc (start_state);
5472 arc = next_out_arc (arc))
5473 pass_state_graph (arc->to_state, applied_func);
5476 /* This recursive function passes all states of AUTOMATON and applies
5477 APPLIED_FUNC to them. */
5479 pass_states (automaton, applied_func)
5480 automaton_t automaton;
5481 void (*applied_func) PARAMS ((state_t state));
5483 curr_state_graph_pass_num++;
5484 pass_state_graph (automaton->start_state, applied_func);
5487 /* The function initializes code for passing of all states. */
5489 initiate_pass_states ()
5491 curr_state_graph_pass_num = 0;
5494 /* The following vla is used for storing pointers to all achieved
5496 static vla_ptr_t all_achieved_states;
5498 /* This function is called by function pass_states to add an achieved
5501 add_achieved_state (state)
5504 VLA_PTR_ADD (all_achieved_states, state);
5507 /* The function sets up equivalence numbers of insns which mark all
5508 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5509 nonzero value) or by equiv_class_num_2 of the destination state.
5510 The function returns number of out arcs of STATE. */
5512 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
5514 int odd_iteration_flag;
5516 int state_out_arcs_num;
5519 state_out_arcs_num = 0;
5520 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5522 if (arc->insn->insn_reserv_decl->equiv_class_num != 0
5523 || arc->insn->insn_reserv_decl->state_alts != 0)
5525 state_out_arcs_num++;
5526 arc->insn->insn_reserv_decl->equiv_class_num
5527 = (odd_iteration_flag
5528 ? arc->to_state->equiv_class_num_1
5529 : arc->to_state->equiv_class_num_2);
5530 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5531 if (arc->insn->insn_reserv_decl->equiv_class_num == 0
5532 || arc->insn->insn_reserv_decl->state_alts <= 0)
5535 return state_out_arcs_num;
5538 /* The function clears equivalence numbers and alt_states in all insns
5539 which mark all out arcs of STATE. */
5541 clear_arc_insns_equiv_num (state)
5546 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5548 arc->insn->insn_reserv_decl->equiv_class_num = 0;
5549 arc->insn->insn_reserv_decl->state_alts = 0;
5553 /* The function copies pointers to equivalent states from vla FROM
5556 copy_equiv_class (to, from)
5558 const vla_ptr_t *from;
5562 VLA_PTR_NULLIFY (*to);
5563 for (class_ptr = VLA_PTR_BEGIN (*from);
5564 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
5566 VLA_PTR_ADD (*to, *class_ptr);
5569 /* The function returns nonzero value if STATE is not equivalent to
5570 another state from the same current partition on equivalence
5571 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5572 output arcs. Iteration of making equivalence partition is defined
5573 by ODD_ITERATION_FLAG. */
5575 state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
5577 int original_state_out_arcs_num;
5578 int odd_iteration_flag;
5581 int state_out_arcs_num;
5583 state_out_arcs_num = 0;
5584 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5586 state_out_arcs_num++;
5587 if ((odd_iteration_flag
5588 ? arc->to_state->equiv_class_num_1
5589 : arc->to_state->equiv_class_num_2)
5590 != arc->insn->insn_reserv_decl->equiv_class_num
5591 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
5594 return state_out_arcs_num != original_state_out_arcs_num;
5597 /* The function makes initial partition of STATES on equivalent
5600 init_equiv_class (states, states_num)
5605 state_t result_equiv_class;
5607 result_equiv_class = NULL;
5608 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
5610 (*state_ptr)->equiv_class_num_1 = 1;
5611 (*state_ptr)->next_equiv_class_state = result_equiv_class;
5612 result_equiv_class = *state_ptr;
5614 return result_equiv_class;
5617 /* The function processes equivalence class given by its pointer
5618 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5619 are not equvalent states, the function partitions the class
5620 removing nonequivalent states and placing them in
5621 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5622 assigns it to the state equivalence number. If the class has been
5623 partitioned, the function returns nonzero value. */
5625 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5626 next_iteration_classes, new_equiv_class_num_ptr)
5627 state_t *equiv_class_ptr;
5628 int odd_iteration_flag;
5629 vla_ptr_t *next_iteration_classes;
5630 int *new_equiv_class_num_ptr;
5632 state_t new_equiv_class;
5634 state_t first_state;
5641 if (*equiv_class_ptr == NULL)
5643 for (first_state = *equiv_class_ptr;
5644 first_state != NULL;
5645 first_state = new_equiv_class)
5647 new_equiv_class = NULL;
5648 if (first_state->next_equiv_class_state != NULL)
5650 /* There are more one states in the class equivalence. */
5651 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
5652 odd_iteration_flag);
5653 for (prev_state = first_state,
5654 curr_state = first_state->next_equiv_class_state;
5656 curr_state = next_state)
5658 next_state = curr_state->next_equiv_class_state;
5659 if (state_is_differed (curr_state, out_arcs_num,
5660 odd_iteration_flag))
5662 /* Remove curr state from the class equivalence. */
5663 prev_state->next_equiv_class_state = next_state;
5664 /* Add curr state to the new class equivalence. */
5665 curr_state->next_equiv_class_state = new_equiv_class;
5666 if (new_equiv_class == NULL)
5667 (*new_equiv_class_num_ptr)++;
5668 if (odd_iteration_flag)
5669 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5671 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5672 new_equiv_class = curr_state;
5676 prev_state = curr_state;
5678 clear_arc_insns_equiv_num (first_state);
5680 if (new_equiv_class != NULL)
5681 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
5686 /* The function finds equivalent states of AUTOMATON. */
5688 evaluate_equiv_classes (automaton, equiv_classes)
5689 automaton_t automaton;
5690 vla_ptr_t *equiv_classes;
5692 state_t new_equiv_class;
5693 int new_equiv_class_num;
5694 int odd_iteration_flag;
5696 vla_ptr_t next_iteration_classes;
5697 state_t *equiv_class_ptr;
5700 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
5701 pass_states (automaton, add_achieved_state);
5702 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
5703 VLA_PTR_LENGTH (all_achieved_states));
5704 odd_iteration_flag = 0;
5705 new_equiv_class_num = 1;
5706 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
5707 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
5710 odd_iteration_flag = !odd_iteration_flag;
5712 copy_equiv_class (equiv_classes, &next_iteration_classes);
5713 /* Transfer equiv numbers for the next iteration. */
5714 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
5715 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
5717 if (odd_iteration_flag)
5718 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
5720 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
5721 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5722 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5724 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5725 &next_iteration_classes,
5726 &new_equiv_class_num))
5729 while (!finish_flag);
5730 VLA_PTR_DELETE (next_iteration_classes);
5731 VLA_PTR_DELETE (all_achieved_states);
5734 /* The function merges equivalent states of AUTOMATON. */
5736 merge_states (automaton, equiv_classes)
5737 automaton_t automaton;
5738 vla_ptr_t *equiv_classes;
5740 state_t *equiv_class_ptr;
5743 state_t first_class_state;
5744 alt_state_t alt_states;
5745 alt_state_t new_alt_state;
5749 /* Create states corresponding to equivalence classes containing two
5751 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5752 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5754 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5756 /* There are more one states in the class equivalence. */
5757 /* Create new compound state. */
5758 new_state = get_free_state (0, automaton);
5760 first_class_state = *equiv_class_ptr;
5761 for (curr_state = first_class_state;
5763 curr_state = curr_state->next_equiv_class_state)
5765 curr_state->equiv_class_state = new_state;
5766 new_alt_state = get_free_alt_state ();
5767 new_alt_state->state = curr_state;
5768 new_alt_state->next_sorted_alt_state = alt_states;
5769 alt_states = new_alt_state;
5771 new_state->component_states = alt_states;
5774 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
5775 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5776 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5778 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5780 first_class_state = *equiv_class_ptr;
5781 /* Create new arcs output from the state corresponding to
5783 for (curr_arc = first_out_arc (first_class_state);
5785 curr_arc = next_out_arc (curr_arc))
5786 add_arc (first_class_state->equiv_class_state,
5787 curr_arc->to_state->equiv_class_state,
5788 curr_arc->insn, curr_arc->state_alts);
5789 /* Delete output arcs from states of given class equivalence. */
5790 for (curr_state = first_class_state;
5792 curr_state = curr_state->next_equiv_class_state)
5794 if (automaton->start_state == curr_state)
5795 automaton->start_state = curr_state->equiv_class_state;
5796 /* Delete the state and its output arcs. */
5797 for (curr_arc = first_out_arc (curr_state);
5799 curr_arc = next_arc)
5801 next_arc = next_out_arc (curr_arc);
5802 free_arc (curr_arc);
5808 /* Change `to_state' of arcs output from the state of given
5809 equivalence class. */
5810 for (curr_arc = first_out_arc (*equiv_class_ptr);
5812 curr_arc = next_out_arc (curr_arc))
5813 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
5817 /* The function sets up new_cycle_p for states if there is arc to the
5818 state marked by advance_cycle_insn_decl. */
5820 set_new_cycle_flags (state)
5825 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5826 if (arc->insn->insn_reserv_decl
5827 == &advance_cycle_insn_decl->decl.insn_reserv)
5828 arc->to_state->new_cycle_p = 1;
5831 /* The top level function for minimization of deterministic
5834 minimize_DFA (automaton)
5835 automaton_t automaton;
5837 vla_ptr_t equiv_classes;
5839 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
5840 evaluate_equiv_classes (automaton, &equiv_classes);
5841 merge_states (automaton, &equiv_classes);
5842 pass_states (automaton, set_new_cycle_flags);
5843 VLA_PTR_DELETE (equiv_classes);
5846 /* Values of two variables are counted number of states and arcs in an
5848 static int curr_counted_states_num;
5849 static int curr_counted_arcs_num;
5851 /* The function is called by function `pass_states' to count states
5852 and arcs of an automaton. */
5854 incr_states_and_arcs_nums (state)
5859 curr_counted_states_num++;
5860 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5861 curr_counted_arcs_num++;
5864 /* The function counts states and arcs of AUTOMATON. */
5866 count_states_and_arcs (automaton, states_num, arcs_num)
5867 automaton_t automaton;
5871 curr_counted_states_num = 0;
5872 curr_counted_arcs_num = 0;
5873 pass_states (automaton, incr_states_and_arcs_nums);
5874 *states_num = curr_counted_states_num;
5875 *arcs_num = curr_counted_arcs_num;
5878 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5879 recognition after checking and simplifying IR of the
5882 build_automaton (automaton)
5883 automaton_t automaton;
5888 ticker_on (&NDFA_time);
5889 make_automaton (automaton);
5890 ticker_off (&NDFA_time);
5891 count_states_and_arcs (automaton, &states_num, &arcs_num);
5892 automaton->NDFA_states_num = states_num;
5893 automaton->NDFA_arcs_num = arcs_num;
5894 ticker_on (&NDFA_to_DFA_time);
5895 NDFA_to_DFA (automaton);
5896 ticker_off (&NDFA_to_DFA_time);
5897 count_states_and_arcs (automaton, &states_num, &arcs_num);
5898 automaton->DFA_states_num = states_num;
5899 automaton->DFA_arcs_num = arcs_num;
5900 if (!no_minimization_flag)
5902 ticker_on (&minimize_time);
5903 minimize_DFA (automaton);
5904 ticker_off (&minimize_time);
5905 count_states_and_arcs (automaton, &states_num, &arcs_num);
5906 automaton->minimal_DFA_states_num = states_num;
5907 automaton->minimal_DFA_arcs_num = arcs_num;
5913 /* The page contains code for enumeration of all states of an automaton. */
5915 /* Variable used for enumeration of all states of an automaton. Its
5916 value is current number of automaton states. */
5917 static int curr_state_order_num;
5919 /* The function is called by function `pass_states' for enumerating
5922 set_order_state_num (state)
5925 state->order_state_num = curr_state_order_num;
5926 curr_state_order_num++;
5929 /* The function enumerates all states of AUTOMATON. */
5931 enumerate_states (automaton)
5932 automaton_t automaton;
5934 curr_state_order_num = 0;
5935 pass_states (automaton, set_order_state_num);
5936 automaton->achieved_states_num = curr_state_order_num;
5941 /* The page contains code for finding equivalent automaton insns
5944 /* The function inserts AINSN into cyclic list
5945 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
5947 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
5949 ainsn_t cyclic_equiv_class_insn_list;
5951 if (cyclic_equiv_class_insn_list == NULL)
5952 ainsn->next_equiv_class_insn = ainsn;
5955 ainsn->next_equiv_class_insn
5956 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
5957 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
5962 /* The function deletes equiv_class_insn into cyclic list of
5963 equivalent ainsns. */
5965 delete_ainsn_from_equiv_class (equiv_class_insn)
5966 ainsn_t equiv_class_insn;
5968 ainsn_t curr_equiv_class_insn;
5969 ainsn_t prev_equiv_class_insn;
5971 prev_equiv_class_insn = equiv_class_insn;
5972 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
5973 curr_equiv_class_insn != equiv_class_insn;
5974 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
5975 prev_equiv_class_insn = curr_equiv_class_insn;
5976 if (prev_equiv_class_insn != equiv_class_insn)
5977 prev_equiv_class_insn->next_equiv_class_insn
5978 = equiv_class_insn->next_equiv_class_insn;
5981 /* The function processes AINSN of a state in order to find equivalent
5982 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
5985 process_insn_equiv_class (ainsn, insn_arcs_array)
5987 arc_t *insn_arcs_array;
5991 ainsn_t cyclic_insn_list;
5994 if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
5997 /* New class of ainsns which are not equivalent to given ainsn. */
5998 cyclic_insn_list = NULL;
6001 next_insn = curr_insn->next_equiv_class_insn;
6002 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6004 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6007 delete_ainsn_from_equiv_class (curr_insn);
6008 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6011 curr_insn = next_insn;
6013 while (curr_insn != ainsn);
6016 /* The function processes STATE in order to find equivalent ainsns. */
6018 process_state_for_insn_equiv_partition (state)
6022 arc_t *insn_arcs_array;
6024 vla_ptr_t insn_arcs_vect;
6026 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6027 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6028 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6029 /* Process insns of the arcs. */
6030 for (i = 0; i < description->insns_num; i++)
6031 insn_arcs_array [i] = NULL;
6032 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6033 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6034 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6035 process_insn_equiv_class (arc->insn, insn_arcs_array);
6036 VLA_PTR_DELETE (insn_arcs_vect);
6039 /* The function searches for equivalent ainsns of AUTOMATON. */
6041 set_insn_equiv_classes (automaton)
6042 automaton_t automaton;
6047 ainsn_t cyclic_insn_list;
6048 ainsn_t insn_with_same_reservs;
6049 int equiv_classes_num;
6051 /* All insns are included in one equivalence class. */
6052 cyclic_insn_list = NULL;
6053 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6054 if (ainsn->first_insn_with_same_reservs)
6055 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6057 /* Process insns in order to make equivalence partition. */
6058 pass_states (automaton, process_state_for_insn_equiv_partition);
6059 /* Enumerate equiv classes. */
6060 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6061 /* Set undefined value. */
6062 ainsn->insn_equiv_class_num = -1;
6063 equiv_classes_num = 0;
6064 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6065 if (ainsn->insn_equiv_class_num < 0)
6068 if (!first_insn->first_insn_with_same_reservs)
6070 first_insn->first_ainsn_with_given_equialence_num = 1;
6071 curr_insn = first_insn;
6074 for (insn_with_same_reservs = curr_insn;
6075 insn_with_same_reservs != NULL;
6076 insn_with_same_reservs
6077 = insn_with_same_reservs->next_same_reservs_insn)
6078 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6079 curr_insn = curr_insn->next_equiv_class_insn;
6081 while (curr_insn != first_insn);
6082 equiv_classes_num++;
6084 automaton->insn_equiv_classes_num = equiv_classes_num;
6089 /* This page contains code for creating DFA(s) and calls functions
6093 /* The following value is used to prevent floating point overflow for
6094 estimating an automaton bound. The value should be less DBL_MAX on
6095 the host machine. We use here approximate minimum of maximal
6096 double floating point value required by ANSI C standard. It
6097 will work for non ANSI sun compiler too. */
6099 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6101 /* The function estimate size of the single DFA used by PHR (pipeline
6102 hazards recognizer). */
6104 estimate_one_automaton_bound ()
6107 double one_automaton_estimation_bound;
6111 one_automaton_estimation_bound = 1.0;
6112 for (i = 0; i < description->decls_num; i++)
6114 decl = description->decls [i];
6115 if (decl->mode == dm_unit)
6117 root_value = exp (log (decl->decl.unit.max_occ_cycle_num + 1.0)
6119 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6120 > one_automaton_estimation_bound)
6121 one_automaton_estimation_bound *= root_value;
6124 return one_automaton_estimation_bound;
6127 /* The function compares unit declarations acoording to their maximal
6128 cycle in reservations. */
6130 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
6131 const void *unit_decl_1;
6132 const void *unit_decl_2;
6134 if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6135 < ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6137 else if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6138 == ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6144 /* The function makes heuristic assigning automata to units. Actually
6145 efficacy of the algorithm has been checked yet??? */
6147 units_to_automata_heuristic_distr ()
6149 double estimation_bound;
6151 decl_t *unit_decl_ptr;
6155 vla_ptr_t unit_decls;
6158 if (description->units_num == 0)
6160 estimation_bound = estimate_one_automaton_bound ();
6161 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6162 for (i = 0; i < description->decls_num; i++)
6164 decl = description->decls [i];
6165 if (decl->mode == dm_unit)
6166 VLA_PTR_ADD (unit_decls, decl);
6168 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6169 sizeof (decl_t), compare_max_occ_cycle_nums);
6171 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6172 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6173 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6174 for (unit_decl_ptr++;
6175 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6179 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6180 if (automata_num - automaton_num - 1 > rest_units_num)
6182 if (automaton_num < automata_num - 1
6183 && ((automata_num - automaton_num - 1 == rest_units_num)
6186 / ((*unit_decl_ptr)->decl.unit.max_occ_cycle_num)))))
6188 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6192 bound_value *= (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6193 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6195 if (automaton_num != automata_num - 1)
6197 VLA_PTR_DELETE (unit_decls);
6200 /* The functions creates automaton insns for each automata. Automaton
6201 insn is simply insn for given automaton which makes reservation
6202 only of units of the automaton. */
6207 ainsn_t first_ainsn;
6214 for (i = 0; i < description->decls_num; i++)
6216 decl = description->decls [i];
6217 if (decl->mode == dm_insn_reserv)
6219 curr_ainsn = create_node (sizeof (struct ainsn));
6220 curr_ainsn->insn_reserv_decl = &decl->decl.insn_reserv;
6221 curr_ainsn->important_p = FALSE;
6222 curr_ainsn->next_ainsn = NULL;
6223 if (prev_ainsn == NULL)
6224 first_ainsn = curr_ainsn;
6226 prev_ainsn->next_ainsn = curr_ainsn;
6227 prev_ainsn = curr_ainsn;
6233 /* The function assigns automata to units according to constructions
6234 `define_automaton' in the description. */
6236 units_to_automata_distr ()
6241 for (i = 0; i < description->decls_num; i++)
6243 decl = description->decls [i];
6244 if (decl->mode == dm_unit)
6246 if (decl->decl.unit.automaton_decl == NULL
6247 || (decl->decl.unit.automaton_decl->corresponding_automaton
6249 /* Distribute to the first automaton. */
6250 decl->decl.unit.corresponding_automaton_num = 0;
6252 decl->decl.unit.corresponding_automaton_num
6253 = (decl->decl.unit.automaton_decl
6254 ->corresponding_automaton->automaton_order_num);
6259 /* The function creates DFA(s) for fast pipeline hazards recognition
6260 after checking and simplifying IR of the description. */
6264 automaton_t curr_automaton;
6265 automaton_t prev_automaton;
6267 int curr_automaton_num;
6270 if (automata_num != 0)
6272 units_to_automata_heuristic_distr ();
6273 for (prev_automaton = NULL, curr_automaton_num = 0;
6274 curr_automaton_num < automata_num;
6275 curr_automaton_num++, prev_automaton = curr_automaton)
6277 curr_automaton = create_node (sizeof (struct automaton));
6278 curr_automaton->ainsn_list = create_ainsns ();
6279 curr_automaton->corresponding_automaton_decl = NULL;
6280 curr_automaton->next_automaton = NULL;
6281 curr_automaton->automaton_order_num = curr_automaton_num;
6282 if (prev_automaton == NULL)
6283 description->first_automaton = curr_automaton;
6285 prev_automaton->next_automaton = curr_automaton;
6290 curr_automaton_num = 0;
6291 prev_automaton = NULL;
6292 for (i = 0; i < description->decls_num; i++)
6294 decl = description->decls [i];
6295 if (decl->mode == dm_automaton
6296 && decl->decl.automaton.automaton_is_used)
6298 curr_automaton = create_node (sizeof (struct automaton));
6299 curr_automaton->ainsn_list = create_ainsns ();
6300 curr_automaton->corresponding_automaton_decl
6301 = &decl->decl.automaton;
6302 curr_automaton->next_automaton = NULL;
6303 decl->decl.automaton.corresponding_automaton = curr_automaton;
6304 curr_automaton->automaton_order_num = curr_automaton_num;
6305 if (prev_automaton == NULL)
6306 description->first_automaton = curr_automaton;
6308 prev_automaton->next_automaton = curr_automaton;
6309 curr_automaton_num++;
6310 prev_automaton = curr_automaton;
6313 if (curr_automaton_num == 0)
6315 curr_automaton = create_node (sizeof (struct automaton));
6316 curr_automaton->ainsn_list = create_ainsns ();
6317 curr_automaton->corresponding_automaton_decl = NULL;
6318 curr_automaton->next_automaton = NULL;
6319 description->first_automaton = curr_automaton;
6321 units_to_automata_distr ();
6323 NDFA_time = create_ticker ();
6324 ticker_off (&NDFA_time);
6325 NDFA_to_DFA_time = create_ticker ();
6326 ticker_off (&NDFA_to_DFA_time);
6327 minimize_time = create_ticker ();
6328 ticker_off (&minimize_time);
6329 equiv_time = create_ticker ();
6330 ticker_off (&equiv_time);
6331 for (curr_automaton = description->first_automaton;
6332 curr_automaton != NULL;
6333 curr_automaton = curr_automaton->next_automaton)
6335 if (curr_automaton->corresponding_automaton_decl == NULL)
6336 fprintf (stderr, "Create anonymous automaton ...");
6338 fprintf (stderr, "Create automaton `%s'...",
6339 curr_automaton->corresponding_automaton_decl->name);
6340 create_alt_states (curr_automaton);
6341 form_ainsn_with_same_reservs (curr_automaton);
6342 build_automaton (curr_automaton);
6343 enumerate_states (curr_automaton);
6344 ticker_on (&equiv_time);
6345 set_insn_equiv_classes (curr_automaton);
6346 ticker_off (&equiv_time);
6347 fprintf (stderr, "done\n");
6353 /* This page contains code for forming string representation of
6354 regexp. The representation is formed on IR obstack. So you should
6355 not work with IR obstack between regexp_representation and
6356 finish_regexp_representation calls. */
6358 /* This recursive function forms string representation of regexp
6359 (without tailing '\0'). */
6361 form_regexp (regexp)
6366 if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6368 const char *name = (regexp->mode == rm_unit
6369 ? regexp->regexp.unit.name
6370 : regexp->regexp.reserv.name);
6372 obstack_grow (&irp, name, strlen (name));
6374 else if (regexp->mode == rm_sequence)
6375 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
6378 obstack_1grow (&irp, ',');
6379 form_regexp (regexp->regexp.sequence.regexps [i]);
6381 else if (regexp->mode == rm_allof)
6383 obstack_1grow (&irp, '(');
6384 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
6387 obstack_1grow (&irp, '+');
6388 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6389 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6390 obstack_1grow (&irp, '(');
6391 form_regexp (regexp->regexp.allof.regexps [i]);
6392 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6393 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6394 obstack_1grow (&irp, ')');
6396 obstack_1grow (&irp, ')');
6398 else if (regexp->mode == rm_oneof)
6399 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
6402 obstack_1grow (&irp, '|');
6403 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6404 obstack_1grow (&irp, '(');
6405 form_regexp (regexp->regexp.oneof.regexps [i]);
6406 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6407 obstack_1grow (&irp, ')');
6409 else if (regexp->mode == rm_repeat)
6413 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6414 || regexp->regexp.repeat.regexp->mode == rm_allof
6415 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6416 obstack_1grow (&irp, '(');
6417 form_regexp (regexp->regexp.repeat.regexp);
6418 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6419 || regexp->regexp.repeat.regexp->mode == rm_allof
6420 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6421 obstack_1grow (&irp, ')');
6422 sprintf (digits, "*%d", regexp->regexp.repeat.repeat_num);
6423 obstack_grow (&irp, digits, strlen (digits));
6425 else if (regexp->mode == rm_nothing)
6426 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6431 /* The function returns string representation of REGEXP on IR
6434 regexp_representation (regexp)
6437 form_regexp (regexp);
6438 obstack_1grow (&irp, '\0');
6439 return obstack_base (&irp);
6442 /* The function frees memory allocated for last formed string
6443 representation of regexp. */
6445 finish_regexp_representation ()
6447 int length = obstack_object_size (&irp);
6449 obstack_blank_fast (&irp, -length);
6454 /* This page contains code for output PHR (pipeline hazards recognizer). */
6456 /* The function outputs minimal C type which is sufficient for
6457 representation numbers in range min_range_value and
6458 max_range_value. Because host machine and build machine may be
6459 different, we use here minimal values required by ANSI C standard
6460 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6464 output_range_type (f, min_range_value, max_range_value)
6466 long int min_range_value;
6467 long int max_range_value;
6469 if (min_range_value >= 0 && max_range_value <= 255)
6470 fprintf (f, "unsigned char");
6471 else if (min_range_value >= -127 && max_range_value <= 127)
6472 fprintf (f, "signed char");
6473 else if (min_range_value >= 0 && max_range_value <= 65535)
6474 fprintf (f, "unsigned short");
6475 else if (min_range_value >= -32767 && max_range_value <= 32767)
6476 fprintf (f, "short");
6481 /* The following macro value is used as value of member
6482 `longest_path_length' of state when we are processing path and the
6483 state on the path. */
6485 #define ON_THE_PATH -2
6487 /* The following recursive function searches for the length of the
6488 longest path starting from STATE which does not contain cycles and
6489 `cycle advance' arcs. */
6492 longest_path_length (state)
6498 if (state->longest_path_length == ON_THE_PATH)
6499 /* We don't expect the path cycle here. Our graph may contain
6500 only cycles with one state on the path not containing `cycle
6501 advance' arcs -- see comment below. */
6503 else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6504 /* We alreday visited the state. */
6505 return state->longest_path_length;
6508 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6509 /* Ignore cycles containing one state and `cycle advance' arcs. */
6510 if (arc->to_state != state
6511 && (arc->insn->insn_reserv_decl
6512 != &advance_cycle_insn_decl->decl.insn_reserv))
6514 length = longest_path_length (arc->to_state);
6515 if (length > result)
6518 state->longest_path_length = result + 1;
6522 /* The following variable value is value of the corresponding global
6523 variable in the automaton based pipeline interface. */
6525 static int max_dfa_issue_rate;
6527 /* The following function processes the longest path length staring
6528 from STATE to find MAX_DFA_ISSUE_RATE. */
6531 process_state_longest_path_length (state)
6536 value = longest_path_length (state);
6537 if (value > max_dfa_issue_rate)
6538 max_dfa_issue_rate = value;
6541 /* The following nacro value is name of the corresponding global
6542 variable in the automaton based pipeline interface. */
6544 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6546 /* The following function calculates value of the the corresponding
6547 global variable and outputs its declaration. */
6550 output_dfa_max_issue_rate ()
6552 automaton_t automaton;
6554 if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
6556 max_dfa_issue_rate = 0;
6557 for (automaton = description->first_automaton;
6559 automaton = automaton->next_automaton)
6560 pass_states (automaton, process_state_longest_path_length);
6561 fprintf (output_file, "\nint %s = %d;\n",
6562 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
6565 /* The function outputs all initialization values of VECT with length
6568 output_vect (vect, vect_length)
6575 if (vect_length == 0)
6576 fprintf (output_file,
6577 "0 /* This is dummy el because the vect is empty */");
6582 fprintf (output_file, "%5ld", (long) *vect);
6584 if (els_on_line == 10)
6587 fprintf (output_file, ",\n");
6589 else if (vect_length != 0)
6590 fprintf (output_file, ", ");
6594 while (vect_length != 0);
6598 /* The following is name of the structure which represents DFA(s) for
6600 #define CHIP_NAME "DFA_chip"
6602 /* The following is name of member which represents state of a DFA for
6605 output_chip_member_name (f, automaton)
6607 automaton_t automaton;
6609 if (automaton->corresponding_automaton_decl == NULL)
6610 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6612 fprintf (f, "%s_automaton_state",
6613 automaton->corresponding_automaton_decl->name);
6616 /* The following is name of temporary variable which stores state of a
6619 output_temp_chip_member_name (f, automaton)
6621 automaton_t automaton;
6624 output_chip_member_name (f, automaton);
6627 /* This is name of macro value which is code of pseudo_insn
6628 representing advancing cpu cycle. Its value is used as internal
6629 code unknown insn. */
6630 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6632 /* Output name of translate vector for given automaton. */
6634 output_translate_vect_name (f, automaton)
6636 automaton_t automaton;
6638 if (automaton->corresponding_automaton_decl == NULL)
6639 fprintf (f, "translate_%d", automaton->automaton_order_num);
6641 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6644 /* Output name for simple transition table representation. */
6646 output_trans_full_vect_name (f, automaton)
6648 automaton_t automaton;
6650 if (automaton->corresponding_automaton_decl == NULL)
6651 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6653 fprintf (f, "%s_transitions",
6654 automaton->corresponding_automaton_decl->name);
6657 /* Output name of comb vector of the transition table for given
6660 output_trans_comb_vect_name (f, automaton)
6662 automaton_t automaton;
6664 if (automaton->corresponding_automaton_decl == NULL)
6665 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6667 fprintf (f, "%s_transitions",
6668 automaton->corresponding_automaton_decl->name);
6671 /* Output name of check vector of the transition table for given
6674 output_trans_check_vect_name (f, automaton)
6676 automaton_t automaton;
6678 if (automaton->corresponding_automaton_decl == NULL)
6679 fprintf (f, "check_%d", automaton->automaton_order_num);
6681 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6684 /* Output name of base vector of the transition table for given
6687 output_trans_base_vect_name (f, automaton)
6689 automaton_t automaton;
6691 if (automaton->corresponding_automaton_decl == NULL)
6692 fprintf (f, "base_%d", automaton->automaton_order_num);
6694 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6697 /* Output name for simple alternatives number representation. */
6699 output_state_alts_full_vect_name (f, automaton)
6701 automaton_t automaton;
6703 if (automaton->corresponding_automaton_decl == NULL)
6704 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6706 fprintf (f, "%s_state_alts",
6707 automaton->corresponding_automaton_decl->name);
6710 /* Output name of comb vector of the alternatives number table for given
6713 output_state_alts_comb_vect_name (f, automaton)
6715 automaton_t automaton;
6717 if (automaton->corresponding_automaton_decl == NULL)
6718 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6720 fprintf (f, "%s_state_alts",
6721 automaton->corresponding_automaton_decl->name);
6724 /* Output name of check vector of the alternatives number table for given
6727 output_state_alts_check_vect_name (f, automaton)
6729 automaton_t automaton;
6731 if (automaton->corresponding_automaton_decl == NULL)
6732 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
6734 fprintf (f, "%s_check_state_alts",
6735 automaton->corresponding_automaton_decl->name);
6738 /* Output name of base vector of the alternatives number table for given
6741 output_state_alts_base_vect_name (f, automaton)
6743 automaton_t automaton;
6745 if (automaton->corresponding_automaton_decl == NULL)
6746 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
6748 fprintf (f, "%s_base_state_alts",
6749 automaton->corresponding_automaton_decl->name);
6752 /* Output name of simple min issue delay table representation. */
6754 output_min_issue_delay_vect_name (f, automaton)
6756 automaton_t automaton;
6758 if (automaton->corresponding_automaton_decl == NULL)
6759 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6761 fprintf (f, "%s_min_issue_delay",
6762 automaton->corresponding_automaton_decl->name);
6765 /* Output name of deadlock vector for given automaton. */
6767 output_dead_lock_vect_name (f, automaton)
6769 automaton_t automaton;
6771 if (automaton->corresponding_automaton_decl == NULL)
6772 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6774 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6777 /* Output name of reserved units table for AUTOMATON into file F. */
6779 output_reserved_units_table_name (f, automaton)
6781 automaton_t automaton;
6783 if (automaton->corresponding_automaton_decl == NULL)
6784 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6786 fprintf (f, "%s_reserved_units",
6787 automaton->corresponding_automaton_decl->name);
6790 /* Name of the PHR interface macro. */
6791 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6793 /* Name of the PHR interface macro. */
6794 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6796 /* Names of an internal functions: */
6797 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6799 /* This is external type of DFA(s) state. */
6800 #define STATE_TYPE_NAME "state_t"
6802 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6804 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6806 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6808 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6810 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6812 /* Name of cache of insn dfa codes. */
6813 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6815 /* Name of length of cache of insn dfa codes. */
6816 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6818 /* Names of the PHR interface functions: */
6819 #define SIZE_FUNC_NAME "state_size"
6821 #define TRANSITION_FUNC_NAME "state_transition"
6823 #define STATE_ALTS_FUNC_NAME "state_alts"
6825 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6827 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6829 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6831 #define RESET_FUNC_NAME "state_reset"
6833 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6835 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6837 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6839 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6841 #define DFA_START_FUNC_NAME "dfa_start"
6843 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6845 /* Names of parameters of the PHR interface functions. */
6846 #define STATE_NAME "state"
6848 #define INSN_PARAMETER_NAME "insn"
6850 #define INSN2_PARAMETER_NAME "insn2"
6852 #define CHIP_PARAMETER_NAME "chip"
6854 #define FILE_PARAMETER_NAME "f"
6856 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6858 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6860 /* Names of the variables whose values are internal insn code of rtx
6862 #define INTERNAL_INSN_CODE_NAME "insn_code"
6864 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6866 /* Names of temporary variables in some functions. */
6867 #define TEMPORARY_VARIABLE_NAME "temp"
6869 #define I_VARIABLE_NAME "i"
6871 /* Name of result variable in some functions. */
6872 #define RESULT_VARIABLE_NAME "res"
6874 /* Name of function (attribute) to translate insn into number of insn
6875 alternatives reservation. */
6876 #define INSN_ALTS_FUNC_NAME "insn_alts"
6878 /* Name of function (attribute) to translate insn into internal insn
6880 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6882 /* Name of function (attribute) to translate insn into internal insn
6883 code with caching. */
6884 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6886 /* Name of function (attribute) to translate insn into internal insn
6888 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6890 /* Name of function (attribute) to translate insn into internal insn
6892 #define BYPASS_P_FUNC_NAME "bypass_p"
6894 /* Output C type which is used for representation of codes of states
6897 output_state_member_type (f, automaton)
6899 automaton_t automaton;
6901 output_range_type (f, 0, automaton->achieved_states_num);
6904 /* Output definition of the structure representing current DFA(s)
6907 output_chip_definitions ()
6909 automaton_t automaton;
6911 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
6912 for (automaton = description->first_automaton;
6914 automaton = automaton->next_automaton)
6916 fprintf (output_file, " ");
6917 output_state_member_type (output_file, automaton);
6918 fprintf (output_file, " ");
6919 output_chip_member_name (output_file, automaton);
6920 fprintf (output_file, ";\n");
6922 fprintf (output_file, "};\n\n");
6924 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
6929 /* The function outputs translate vector of internal insn code into
6930 insn equivalence class number. The equivalence class number is
6931 used to access to table and vectors reprewsenting DFA(s). */
6933 output_translate_vect (automaton)
6934 automaton_t automaton;
6938 vla_hwint_t translate_vect;
6940 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
6941 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
6942 for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
6943 /* Undefined value */
6944 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
6945 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6946 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
6947 = ainsn->insn_equiv_class_num;
6948 fprintf (output_file,
6949 "/* Vector translating external insn codes to internal ones.*/\n");
6950 fprintf (output_file, "static const ");
6951 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
6952 fprintf (output_file, " ");
6953 output_translate_vect_name (output_file, automaton);
6954 fprintf (output_file, "[] = {\n");
6955 output_vect (VLA_HWINT_BEGIN (translate_vect),
6956 VLA_HWINT_LENGTH (translate_vect));
6957 fprintf (output_file, "};\n\n");
6958 VLA_HWINT_DELETE (translate_vect);
6961 /* The value in a table state x ainsn -> something which represents
6963 static int undefined_vect_el_value;
6965 /* The following function returns nonzero value if the best
6966 representation of the table is comb vector. */
6969 state_ainsn_table_t tab;
6971 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
6972 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
6975 /* The following function creates new table for AUTOMATON. */
6976 static state_ainsn_table_t
6977 create_state_ainsn_table (automaton)
6978 automaton_t automaton;
6980 state_ainsn_table_t tab;
6981 int full_vect_length;
6984 tab = create_node (sizeof (struct state_ainsn_table));
6985 tab->automaton = automaton;
6986 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
6987 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
6988 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
6989 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
6990 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
6991 full_vect_length = (automaton->insn_equiv_classes_num
6992 * automaton->achieved_states_num);
6993 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
6994 for (i = 0; i < full_vect_length; i++)
6995 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
6996 tab->min_base_vect_el_value = 0;
6997 tab->max_base_vect_el_value = 0;
6998 tab->min_comb_vect_el_value = 0;
6999 tab->max_comb_vect_el_value = 0;
7003 /* The following function outputs the best C representation of the
7004 table TAB of given TABLE_NAME. */
7006 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
7007 output_comb_vect_name_func,
7008 output_check_vect_name_func,
7009 output_base_vect_name_func)
7010 state_ainsn_table_t tab;
7012 void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
7013 void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
7014 void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
7015 void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
7017 if (!comb_vect_p (tab))
7019 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7020 fprintf (output_file, "static const ");
7021 output_range_type (output_file, tab->min_comb_vect_el_value,
7022 tab->max_comb_vect_el_value);
7023 fprintf (output_file, " ");
7024 (*output_full_vect_name_func) (output_file, tab->automaton);
7025 fprintf (output_file, "[] = {\n");
7026 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7027 VLA_HWINT_LENGTH (tab->full_vect));
7028 fprintf (output_file, "};\n\n");
7032 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7033 fprintf (output_file, "static const ");
7034 output_range_type (output_file, tab->min_comb_vect_el_value,
7035 tab->max_comb_vect_el_value);
7036 fprintf (output_file, " ");
7037 (*output_comb_vect_name_func) (output_file, tab->automaton);
7038 fprintf (output_file, "[] = {\n");
7039 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7040 VLA_HWINT_LENGTH (tab->comb_vect));
7041 fprintf (output_file, "};\n\n");
7042 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7043 fprintf (output_file, "static const ");
7044 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7045 fprintf (output_file, " ");
7046 (*output_check_vect_name_func) (output_file, tab->automaton);
7047 fprintf (output_file, "[] = {\n");
7048 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7049 VLA_HWINT_LENGTH (tab->check_vect));
7050 fprintf (output_file, "};\n\n");
7051 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7052 fprintf (output_file, "static const ");
7053 output_range_type (output_file, tab->min_base_vect_el_value,
7054 tab->max_base_vect_el_value);
7055 fprintf (output_file, " ");
7056 (*output_base_vect_name_func) (output_file, tab->automaton);
7057 fprintf (output_file, "[] = {\n");
7058 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7059 VLA_HWINT_LENGTH (tab->base_vect));
7060 fprintf (output_file, "};\n\n");
7064 /* The following function adds vector with length VECT_LENGTH and
7065 elements pointed by VECT to table TAB as its line with number
7068 add_vect (tab, vect_num, vect, vect_length)
7069 state_ainsn_table_t tab;
7074 int real_vect_length;
7075 vect_el_t *comb_vect_start;
7076 vect_el_t *check_vect_start;
7077 int comb_vect_index;
7078 int comb_vect_els_num;
7080 int first_unempty_vect_index;
7081 int additional_els_num;
7086 if (vect_length == 0)
7088 real_vect_length = tab->automaton->insn_equiv_classes_num;
7089 if (vect [vect_length - 1] == undefined_vect_el_value)
7091 /* Form full vector in the table: */
7092 for (i = 0; i < vect_length; i++)
7093 VLA_HWINT (tab->full_vect,
7094 i + tab->automaton->insn_equiv_classes_num * vect_num)
7096 /* Form comb vector in the table: */
7097 if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7099 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7100 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7101 for (first_unempty_vect_index = 0;
7102 first_unempty_vect_index < vect_length;
7103 first_unempty_vect_index++)
7104 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7106 /* Search for the place in comb vect for the inserted vect. */
7107 for (comb_vect_index = 0;
7108 comb_vect_index < comb_vect_els_num;
7111 for (vect_index = first_unempty_vect_index;
7112 vect_index < vect_length
7113 && vect_index + comb_vect_index < comb_vect_els_num;
7115 if (vect [vect_index] != undefined_vect_el_value
7116 && (comb_vect_start [vect_index + comb_vect_index]
7117 != undefined_vect_el_value))
7119 if (vect_index >= vect_length
7120 || vect_index + comb_vect_index >= comb_vect_els_num)
7123 /* Slot was found. */
7124 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7125 if (additional_els_num < 0)
7126 additional_els_num = 0;
7127 /* Expand comb and check vectors. */
7128 vect_el = undefined_vect_el_value;
7129 no_state_value = tab->automaton->achieved_states_num;
7130 while (additional_els_num > 0)
7132 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7133 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7134 additional_els_num--;
7136 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7137 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7138 if (VLA_HWINT_LENGTH (tab->comb_vect)
7139 < (size_t) (comb_vect_index + real_vect_length))
7141 /* Fill comb and check vectors. */
7142 for (vect_index = 0; vect_index < vect_length; vect_index++)
7143 if (vect [vect_index] != undefined_vect_el_value)
7145 if (comb_vect_start [comb_vect_index + vect_index]
7146 != undefined_vect_el_value)
7148 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7149 if (vect [vect_index] < 0)
7151 if (tab->max_comb_vect_el_value < vect [vect_index])
7152 tab->max_comb_vect_el_value = vect [vect_index];
7153 if (tab->min_comb_vect_el_value > vect [vect_index])
7154 tab->min_comb_vect_el_value = vect [vect_index];
7155 check_vect_start [comb_vect_index + vect_index] = vect_num;
7157 if (tab->max_base_vect_el_value < comb_vect_index)
7158 tab->max_base_vect_el_value = comb_vect_index;
7159 if (tab->min_base_vect_el_value > comb_vect_index)
7160 tab->min_base_vect_el_value = comb_vect_index;
7161 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7164 /* Return number of out arcs of STATE. */
7166 out_state_arcs_num (state)
7173 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7175 if (arc->insn == NULL)
7177 if (arc->insn->first_ainsn_with_given_equialence_num)
7183 /* Compare number of possible transitions from the states. */
7185 compare_transition_els_num (state_ptr_1, state_ptr_2)
7186 const void *state_ptr_1;
7187 const void *state_ptr_2;
7189 int transition_els_num_1;
7190 int transition_els_num_2;
7192 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7193 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7194 if (transition_els_num_1 < transition_els_num_2)
7196 else if (transition_els_num_1 == transition_els_num_2)
7202 /* The function adds element EL_VALUE to vector VECT for a table state
7205 add_vect_el (vect, ainsn, el_value)
7210 int equiv_class_num;
7215 equiv_class_num = ainsn->insn_equiv_class_num;
7216 for (vect_index = VLA_HWINT_LENGTH (*vect);
7217 vect_index <= equiv_class_num;
7219 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7220 VLA_HWINT (*vect, equiv_class_num) = el_value;
7223 /* This is for forming vector of states of an automaton. */
7224 static vla_ptr_t output_states_vect;
7226 /* The function is called by function pass_states. The function adds
7227 STATE to `output_states_vect'. */
7229 add_states_vect_el (state)
7232 VLA_PTR_ADD (output_states_vect, state);
7235 /* Form and output vectors (comb, check, base or full vector)
7236 representing transition table of AUTOMATON. */
7238 output_trans_table (automaton)
7239 automaton_t automaton;
7243 vla_hwint_t transition_vect;
7245 undefined_vect_el_value = automaton->achieved_states_num;
7246 automaton->trans_table = create_state_ainsn_table (automaton);
7247 /* Create vect of pointers to states ordered by num of transitions
7248 from the state (state with the maximum num is the first). */
7249 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7250 pass_states (automaton, add_states_vect_el);
7251 qsort (VLA_PTR_BEGIN (output_states_vect),
7252 VLA_PTR_LENGTH (output_states_vect),
7253 sizeof (state_t), compare_transition_els_num);
7254 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7255 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7256 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7259 VLA_HWINT_NULLIFY (transition_vect);
7260 for (arc = first_out_arc (*state_ptr);
7262 arc = next_out_arc (arc))
7264 if (arc->insn == NULL)
7266 if (arc->insn->first_ainsn_with_given_equialence_num)
7267 add_vect_el (&transition_vect, arc->insn,
7268 arc->to_state->order_state_num);
7270 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7271 VLA_HWINT_BEGIN (transition_vect),
7272 VLA_HWINT_LENGTH (transition_vect));
7274 output_state_ainsn_table
7275 (automaton->trans_table, (char *) "state transitions",
7276 output_trans_full_vect_name, output_trans_comb_vect_name,
7277 output_trans_check_vect_name, output_trans_base_vect_name);
7278 VLA_PTR_DELETE (output_states_vect);
7279 VLA_HWINT_DELETE (transition_vect);
7282 /* Form and output vectors (comb, check, base or simple vect)
7283 representing alts number table of AUTOMATON. The table is state x
7284 ainsn -> number of possible alternative reservations by the
7287 output_state_alts_table (automaton)
7288 automaton_t automaton;
7292 vla_hwint_t state_alts_vect;
7294 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7295 automaton->state_alts_table = create_state_ainsn_table (automaton);
7296 /* Create vect of pointers to states ordered by num of transitions
7297 from the state (state with the maximum num is the first). */
7298 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7299 pass_states (automaton, add_states_vect_el);
7300 qsort (VLA_PTR_BEGIN (output_states_vect),
7301 VLA_PTR_LENGTH (output_states_vect),
7302 sizeof (state_t), compare_transition_els_num);
7303 /* Create base, comb, and check vectors. */
7304 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7305 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7306 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7309 VLA_HWINT_NULLIFY (state_alts_vect);
7310 for (arc = first_out_arc (*state_ptr);
7312 arc = next_out_arc (arc))
7314 if (arc->insn == NULL)
7316 if (arc->insn->first_ainsn_with_given_equialence_num)
7317 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7319 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7320 VLA_HWINT_BEGIN (state_alts_vect),
7321 VLA_HWINT_LENGTH (state_alts_vect));
7323 output_state_ainsn_table
7324 (automaton->state_alts_table, (char *) "state insn alternatives",
7325 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7326 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7327 VLA_PTR_DELETE (output_states_vect);
7328 VLA_HWINT_DELETE (state_alts_vect);
7331 /* The current number of passing states to find minimal issue delay
7332 value for an ainsn and state. */
7333 static int curr_state_pass_num;
7336 /* This recursive function passes states to find minimal issue delay
7337 value for AINSN. The state being visited is STATE. The function
7338 returns minimal issue delay value for AINSN in STATE or -1 if we
7339 enter into a loop. */
7341 min_issue_delay_pass_states (state, ainsn)
7346 int min_insn_issue_delay, insn_issue_delay;
7348 if (state->state_pass_num == curr_state_pass_num
7349 || state->min_insn_issue_delay != -1)
7350 /* We've entered into a loop or already have the correct value for
7351 given state and ainsn. */
7352 return state->min_insn_issue_delay;
7353 state->state_pass_num = curr_state_pass_num;
7354 min_insn_issue_delay = -1;
7355 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7356 if (arc->insn == ainsn)
7358 min_insn_issue_delay = 0;
7363 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7364 if (insn_issue_delay != -1)
7366 if (arc->insn->insn_reserv_decl
7367 == &advance_cycle_insn_decl->decl.insn_reserv)
7369 if (min_insn_issue_delay == -1
7370 || min_insn_issue_delay > insn_issue_delay)
7372 min_insn_issue_delay = insn_issue_delay;
7373 if (insn_issue_delay == 0)
7378 return min_insn_issue_delay;
7381 /* The function searches minimal issue delay value for AINSN in STATE.
7382 The function can return negative value if we can not issue AINSN. We
7383 will report about it later. */
7385 min_issue_delay (state, ainsn)
7389 curr_state_pass_num++;
7390 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7391 return state->min_insn_issue_delay;
7394 /* The function initiates code for finding minimal issue delay values.
7395 It should be called only once. */
7397 initiate_min_issue_delay_pass_states ()
7399 curr_state_pass_num = 0;
7402 /* Form and output vectors representing minimal issue delay table of
7403 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7406 output_min_issue_delay_table (automaton)
7407 automaton_t automaton;
7409 vla_hwint_t min_issue_delay_vect;
7410 vla_hwint_t compressed_min_issue_delay_vect;
7411 vect_el_t min_delay;
7416 /* Create vect of pointers to states ordered by num of transitions
7417 from the state (state with the maximum num is the first). */
7418 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7419 pass_states (automaton, add_states_vect_el);
7420 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7421 VLA_HWINT_EXPAND (min_issue_delay_vect,
7422 VLA_HWINT_LENGTH (output_states_vect)
7423 * automaton->insn_equiv_classes_num);
7425 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7426 * automaton->insn_equiv_classes_num);
7428 VLA_HWINT (min_issue_delay_vect, i) = 0;
7429 automaton->max_min_delay = 0;
7430 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7431 if (ainsn->first_ainsn_with_given_equialence_num)
7433 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7434 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7436 (*state_ptr)->min_insn_issue_delay = -1;
7437 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7438 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7441 min_delay = min_issue_delay (*state_ptr, ainsn);
7442 if (automaton->max_min_delay < min_delay)
7443 automaton->max_min_delay = min_delay;
7444 VLA_HWINT (min_issue_delay_vect,
7445 (*state_ptr)->order_state_num
7446 * automaton->insn_equiv_classes_num
7447 + ainsn->insn_equiv_class_num) = min_delay;
7450 fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
7451 fprintf (output_file, "static const ");
7452 output_range_type (output_file, 0, automaton->max_min_delay);
7453 fprintf (output_file, " ");
7454 output_min_issue_delay_vect_name (output_file, automaton);
7455 fprintf (output_file, "[] = {\n");
7456 /* Compress the vector */
7457 if (automaton->max_min_delay < 2)
7458 automaton->min_issue_delay_table_compression_factor = 8;
7459 else if (automaton->max_min_delay < 4)
7460 automaton->min_issue_delay_table_compression_factor = 4;
7461 else if (automaton->max_min_delay < 16)
7462 automaton->min_issue_delay_table_compression_factor = 2;
7464 automaton->min_issue_delay_table_compression_factor = 1;
7465 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7466 "compressed min issue delay vector");
7467 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7468 (VLA_HWINT_LENGTH (min_issue_delay_vect)
7469 + automaton->min_issue_delay_table_compression_factor
7471 / automaton->min_issue_delay_table_compression_factor);
7473 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7475 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7476 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7477 VLA_HWINT (compressed_min_issue_delay_vect,
7478 i / automaton->min_issue_delay_table_compression_factor)
7479 |= (VLA_HWINT (min_issue_delay_vect, i)
7480 << (8 - (i % automaton->min_issue_delay_table_compression_factor
7482 * (8 / automaton->min_issue_delay_table_compression_factor)));
7483 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7484 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7485 fprintf (output_file, "};\n\n");
7486 VLA_PTR_DELETE (output_states_vect);
7487 VLA_HWINT_DELETE (min_issue_delay_vect);
7488 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7492 /* Number of states which contains transition only by advancing cpu
7494 static int locked_states_num;
7497 /* Form and output vector representing the locked states of
7500 output_dead_lock_vect (automaton)
7501 automaton_t automaton;
7505 vla_hwint_t dead_lock_vect;
7507 /* Create vect of pointers to states ordered by num of
7508 transitions from the state (state with the maximum num is the
7510 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7511 pass_states (automaton, add_states_vect_el);
7512 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7513 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7514 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7515 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7518 arc = first_out_arc (*state_ptr);
7521 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
7522 = (next_out_arc (arc) == NULL
7523 && (arc->insn->insn_reserv_decl
7524 == &advance_cycle_insn_decl->decl.insn_reserv) ? 1 : 0);
7526 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
7527 locked_states_num++;
7530 fprintf (output_file, "/* Vector for locked state flags. */\n");
7531 fprintf (output_file, "static const ");
7532 output_range_type (output_file, 0, 1);
7533 fprintf (output_file, " ");
7534 output_dead_lock_vect_name (output_file, automaton);
7535 fprintf (output_file, "[] = {\n");
7536 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
7537 VLA_HWINT_LENGTH (dead_lock_vect));
7538 fprintf (output_file, "};\n\n");
7539 VLA_HWINT_DELETE (dead_lock_vect);
7540 VLA_PTR_DELETE (output_states_vect);
7543 /* Form and output vector representing reserved units of the states of
7546 output_reserved_units_table (automaton)
7547 automaton_t automaton;
7549 state_t *curr_state_ptr;
7550 vla_hwint_t reserved_units_table;
7551 size_t state_byte_size;
7554 /* Create vect of pointers to states. */
7555 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7556 pass_states (automaton, add_states_vect_el);
7557 /* Create vector. */
7558 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
7559 state_byte_size = (description->query_units_num + 7) / 8;
7560 VLA_HWINT_EXPAND (reserved_units_table,
7561 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7563 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7565 VLA_HWINT (reserved_units_table, i) = 0;
7566 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
7567 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7570 for (i = 0; i < description->units_num; i++)
7571 if (units_array [i]->query_p)
7573 if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
7574 VLA_HWINT (reserved_units_table,
7575 (*curr_state_ptr)->order_state_num * state_byte_size
7576 + units_array [i]->query_num / 8)
7577 += (1 << (units_array [i]->query_num % 8));
7580 fprintf (output_file, "/* Vector for reserved units of states. */\n");
7581 fprintf (output_file, "static const ");
7582 output_range_type (output_file, 0, 255);
7583 fprintf (output_file, " ");
7584 output_reserved_units_table_name (output_file, automaton);
7585 fprintf (output_file, "[] = {\n");
7586 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
7587 VLA_HWINT_LENGTH (reserved_units_table));
7588 fprintf (output_file, "};\n\n");
7589 VLA_HWINT_DELETE (reserved_units_table);
7590 VLA_PTR_DELETE (output_states_vect);
7593 /* The function outputs all tables representing DFA(s) used for fast
7594 pipeline hazards recognition. */
7598 automaton_t automaton;
7601 locked_states_num = 0;
7603 initiate_min_issue_delay_pass_states ();
7604 for (automaton = description->first_automaton;
7606 automaton = automaton->next_automaton)
7608 output_translate_vect (automaton);
7609 output_trans_table (automaton);
7610 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
7611 output_state_alts_table (automaton);
7612 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7613 AUTOMATON_STATE_ALTS_MACRO_NAME);
7614 output_min_issue_delay_table (automaton);
7615 output_dead_lock_vect (automaton);
7616 if (no_minimization_flag)
7618 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
7619 output_reserved_units_table (automaton);
7620 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7621 CPU_UNITS_QUERY_MACRO_NAME);
7624 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7625 advance_cycle_insn_decl->decl.insn_reserv.insn_num);
7628 /* The function outputs definition and value of PHR interface variable
7629 `max_insn_queue_index' */
7631 output_max_insn_queue_index_def ()
7635 for (i = 0; (1 << i) <= description->max_insn_reserv_cycles; i++)
7639 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
7643 /* The function outputs switch cases for insn reseravtions using
7644 function *output_automata_list_code. */
7646 output_insn_code_cases (output_automata_list_code)
7647 void (*output_automata_list_code) (automata_list_el_t);
7649 decl_t decl, decl_2;
7652 for (i = 0; i < description->decls_num; i++)
7654 decl = description->decls [i];
7655 if (decl->mode == dm_insn_reserv)
7656 decl->decl.insn_reserv.processed_p = FALSE;
7658 for (i = 0; i < description->decls_num; i++)
7660 decl = description->decls [i];
7661 if (decl->mode == dm_insn_reserv && !decl->decl.insn_reserv.processed_p)
7663 for (j = i; j < description->decls_num; j++)
7665 decl_2 = description->decls [j];
7666 if (decl_2->mode == dm_insn_reserv
7667 && (decl_2->decl.insn_reserv.important_automata_list
7668 == decl->decl.insn_reserv.important_automata_list))
7670 decl_2->decl.insn_reserv.processed_p = TRUE;
7671 fprintf (output_file, " case %d: /* %s */\n",
7672 decl_2->decl.insn_reserv.insn_num,
7673 decl_2->decl.insn_reserv.name);
7676 (*output_automata_list_code)
7677 (decl->decl.insn_reserv.important_automata_list);
7683 /* The function outputs a code for evaluation of a minimal delay of
7684 issue of insns which have reservations in given AUTOMATA_LIST. */
7686 output_automata_list_min_issue_delay_code (automata_list)
7687 automata_list_el_t automata_list;
7689 automata_list_el_t el;
7690 automaton_t automaton;
7692 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7694 automaton = el->automaton;
7695 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7696 output_min_issue_delay_vect_name (output_file, automaton);
7697 fprintf (output_file,
7698 (automaton->min_issue_delay_table_compression_factor != 1
7700 output_translate_vect_name (output_file, automaton);
7701 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7702 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7703 output_chip_member_name (output_file, automaton);
7704 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7705 if (automaton->min_issue_delay_table_compression_factor == 1)
7706 fprintf (output_file, "];\n");
7709 fprintf (output_file, ") / %d];\n",
7710 automaton->min_issue_delay_table_compression_factor);
7711 fprintf (output_file, " %s = (%s >> (8 - (",
7712 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7713 output_translate_vect_name (output_file, automaton);
7715 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
7716 INTERNAL_INSN_CODE_NAME,
7717 automaton->min_issue_delay_table_compression_factor,
7718 8 / automaton->min_issue_delay_table_compression_factor,
7719 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7722 if (el == automata_list)
7723 fprintf (output_file, " %s = %s;\n",
7724 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7727 fprintf (output_file, " if (%s > %s)\n",
7728 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7729 fprintf (output_file, " %s = %s;\n",
7730 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7733 fprintf (output_file, " break;\n\n");
7736 /* Output function `internal_min_issue_delay'. */
7738 output_internal_min_issue_delay_func ()
7740 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7741 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
7742 fprintf (output_file,
7743 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7744 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7745 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
7746 CHIP_PARAMETER_NAME);
7747 fprintf (output_file, "{\n int %s;\n int %s;\n",
7748 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7749 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7750 output_insn_code_cases (output_automata_list_min_issue_delay_code);
7751 fprintf (output_file,
7752 "\n default:\n %s = -1;\n break;\n }\n",
7753 RESULT_VARIABLE_NAME);
7754 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
7755 fprintf (output_file, "}\n\n");
7758 /* The function outputs a code changing state after issue of insns
7759 which have reservations in given AUTOMATA_LIST. */
7761 output_automata_list_transition_code (automata_list)
7762 automata_list_el_t automata_list;
7764 automata_list_el_t el, next_el;
7766 fprintf (output_file, " {\n");
7767 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7768 for (el = automata_list;; el = next_el)
7770 next_el = el->next_automata_list_el;
7771 if (next_el == NULL)
7773 fprintf (output_file, " ");
7774 output_state_member_type (output_file, el->automaton);
7775 fprintf (output_file, " ");
7776 output_temp_chip_member_name (output_file, el->automaton);
7777 fprintf (output_file, ";\n");
7779 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7780 if (comb_vect_p (el->automaton->trans_table))
7782 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7783 output_trans_base_vect_name (output_file, el->automaton);
7784 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7785 output_chip_member_name (output_file, el->automaton);
7786 fprintf (output_file, "] + ");
7787 output_translate_vect_name (output_file, el->automaton);
7788 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7789 fprintf (output_file, " if (");
7790 output_trans_check_vect_name (output_file, el->automaton);
7791 fprintf (output_file, " [%s] != %s->",
7792 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7793 output_chip_member_name (output_file, el->automaton);
7794 fprintf (output_file, ")\n");
7795 fprintf (output_file, " return %s (%s, %s);\n",
7796 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7797 CHIP_PARAMETER_NAME);
7798 fprintf (output_file, " else\n");
7799 fprintf (output_file, " ");
7800 if (el->next_automata_list_el != NULL)
7801 output_temp_chip_member_name (output_file, el->automaton);
7804 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7805 output_chip_member_name (output_file, el->automaton);
7807 fprintf (output_file, " = ");
7808 output_trans_comb_vect_name (output_file, el->automaton);
7809 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7813 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7814 output_trans_full_vect_name (output_file, el->automaton);
7815 fprintf (output_file, " [");
7816 output_translate_vect_name (output_file, el->automaton);
7817 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7818 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7819 output_chip_member_name (output_file, el->automaton);
7820 fprintf (output_file, " * %d];\n",
7821 el->automaton->insn_equiv_classes_num);
7822 fprintf (output_file, " if (%s >= %d)\n",
7823 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7824 fprintf (output_file, " return %s (%s, %s);\n",
7825 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7826 CHIP_PARAMETER_NAME);
7827 fprintf (output_file, " else\n ");
7828 if (el->next_automata_list_el != NULL)
7829 output_temp_chip_member_name (output_file, el->automaton);
7832 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7833 output_chip_member_name (output_file, el->automaton);
7835 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7837 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7838 for (el = automata_list;; el = next_el)
7840 next_el = el->next_automata_list_el;
7841 if (next_el == NULL)
7843 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
7844 output_chip_member_name (output_file, el->automaton);
7845 fprintf (output_file, " = ");
7846 output_temp_chip_member_name (output_file, el->automaton);
7847 fprintf (output_file, ";\n");
7849 fprintf (output_file, " return -1;\n");
7850 fprintf (output_file, " }\n");
7853 /* Output function `internal_state_transition'. */
7855 output_internal_trans_func ()
7857 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7858 INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
7859 fprintf (output_file,
7860 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7861 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7862 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
7863 CHIP_NAME, CHIP_PARAMETER_NAME);
7864 fprintf (output_file, "{\n int %s;\n", TEMPORARY_VARIABLE_NAME);
7865 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7866 output_insn_code_cases (output_automata_list_transition_code);
7867 fprintf (output_file, "\n default:\n return -1;\n }\n");
7868 fprintf (output_file, "}\n\n");
7875 insn_code = dfa_insn_code (insn);
7876 if (insn_code > DFA__ADVANCE_CYCLE)
7880 insn_code = DFA__ADVANCE_CYCLE;
7882 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7883 code denotes CODE. */
7885 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
7886 const char *insn_name;
7887 const char *insn_code_name;
7890 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
7891 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
7892 DFA_INSN_CODE_FUNC_NAME, insn_name);
7893 fprintf (output_file, " if (%s > %s)\n return %d;\n",
7894 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
7895 fprintf (output_file, " }\n else\n %s = %s;\n\n",
7896 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
7900 /* The function outputs function `dfa_insn_code'. */
7902 output_dfa_insn_code_func ()
7904 fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
7905 fprintf (output_file, "static int %s PARAMS ((rtx));\n",
7906 DFA_INSN_CODE_FUNC_NAME);
7907 fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
7908 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
7909 fprintf (output_file, "{\n int %s;\n int %s;\n\n",
7910 INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
7911 fprintf (output_file, " if (INSN_UID (%s) >= %s)\n {\n",
7912 INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7913 fprintf (output_file, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
7914 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7915 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
7916 fprintf (output_file, " %s = xrealloc (%s, %s * sizeof (int));\n",
7917 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7918 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7919 fprintf (output_file,
7920 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
7921 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7922 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7923 TEMPORARY_VARIABLE_NAME);
7924 fprintf (output_file, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
7925 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7926 INSN_PARAMETER_NAME);
7927 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
7928 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
7929 fprintf (output_file, " %s [INSN_UID (%s)] = %s;\n",
7930 DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
7931 INTERNAL_INSN_CODE_NAME);
7932 fprintf (output_file, " }\n return %s;\n}\n\n",
7933 INTERNAL_INSN_CODE_NAME);
7936 /* The function outputs PHR interface function `state_transition'. */
7938 output_trans_func ()
7940 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7941 TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
7942 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
7943 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7944 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7945 INTERNAL_INSN_CODE_NAME, -1);
7946 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
7947 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
7950 /* The function outputs a code for evaluation of alternative states
7951 number for insns which have reservations in given AUTOMATA_LIST. */
7953 output_automata_list_state_alts_code (automata_list)
7954 automata_list_el_t automata_list;
7956 automata_list_el_t el;
7957 automaton_t automaton;
7959 fprintf (output_file, " {\n");
7960 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7961 if (comb_vect_p (el->automaton->state_alts_table))
7963 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
7966 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7968 automaton = el->automaton;
7969 if (comb_vect_p (automaton->state_alts_table))
7971 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7972 output_state_alts_base_vect_name (output_file, automaton);
7973 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7974 output_chip_member_name (output_file, automaton);
7975 fprintf (output_file, "] + ");
7976 output_translate_vect_name (output_file, automaton);
7977 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7978 fprintf (output_file, " if (");
7979 output_state_alts_check_vect_name (output_file, automaton);
7980 fprintf (output_file, " [%s] != %s->",
7981 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7982 output_chip_member_name (output_file, automaton);
7983 fprintf (output_file, ")\n");
7984 fprintf (output_file, " return 0;\n");
7985 fprintf (output_file, " else\n");
7986 fprintf (output_file,
7987 (el == automata_list
7988 ? " %s = " : " %s += "),
7989 RESULT_VARIABLE_NAME);
7990 output_state_alts_comb_vect_name (output_file, automaton);
7991 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7995 fprintf (output_file,
7996 (el == automata_list
7997 ? "\n %s = " : " %s += "),
7998 RESULT_VARIABLE_NAME);
7999 output_state_alts_full_vect_name (output_file, automaton);
8000 fprintf (output_file, " [");
8001 output_translate_vect_name (output_file, automaton);
8002 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8003 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8004 output_chip_member_name (output_file, automaton);
8005 fprintf (output_file, " * %d];\n",
8006 automaton->insn_equiv_classes_num);
8009 fprintf (output_file, " break;\n }\n\n");
8012 /* Output function `internal_state_alts'. */
8014 output_internal_state_alts_func ()
8016 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8017 INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
8018 fprintf (output_file,
8019 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8020 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8021 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8022 CHIP_PARAMETER_NAME);
8023 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8024 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8025 output_insn_code_cases (output_automata_list_state_alts_code);
8026 fprintf (output_file,
8027 "\n default:\n %s = 0;\n break;\n }\n",
8028 RESULT_VARIABLE_NAME);
8029 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8030 fprintf (output_file, "}\n\n");
8033 /* The function outputs PHR interface function `state_alts'. */
8035 output_state_alts_func ()
8037 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8038 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8039 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8040 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8041 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8042 INTERNAL_INSN_CODE_NAME, 0);
8043 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8044 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8047 /* Output function `min_issue_delay'. */
8049 output_min_issue_delay_func ()
8051 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8052 MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8053 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8054 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8055 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8056 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8057 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8058 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8059 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8060 fprintf (output_file, " }\n else\n %s = %s;\n",
8061 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8062 fprintf (output_file, "\n return %s (%s, %s);\n",
8063 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8065 fprintf (output_file, "}\n\n");
8068 /* Output function `internal_dead_lock'. */
8070 output_internal_dead_lock_func ()
8072 automaton_t automaton;
8074 fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
8075 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
8076 fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8077 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
8078 CHIP_PARAMETER_NAME);
8079 fprintf (output_file, "{\n");
8080 for (automaton = description->first_automaton;
8082 automaton = automaton->next_automaton)
8084 fprintf (output_file, " if (");
8085 output_dead_lock_vect_name (output_file, automaton);
8086 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8087 output_chip_member_name (output_file, automaton);
8088 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8090 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8093 /* The function outputs PHR interface function `state_dead_lock_p'. */
8095 output_dead_lock_func ()
8097 fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
8098 DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8099 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8100 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8103 /* Output function `internal_reset'. */
8105 output_internal_reset_func ()
8107 fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
8108 INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8109 fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8110 INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
8111 CHIP_NAME, CHIP_PARAMETER_NAME);
8112 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8113 CHIP_PARAMETER_NAME, CHIP_NAME);
8116 /* The function outputs PHR interface function `state_size'. */
8120 fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
8121 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8124 /* The function outputs PHR interface function `state_reset'. */
8126 output_reset_func ()
8128 fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
8129 RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8130 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8134 /* Output function `min_insn_conflict_delay'. */
8136 output_min_insn_conflict_delay_func ()
8138 fprintf (output_file,
8139 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8140 MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
8141 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8142 STATE_TYPE_NAME, STATE_NAME,
8143 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8144 fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
8145 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8146 INTERNAL_INSN2_CODE_NAME);
8147 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8148 INTERNAL_INSN_CODE_NAME, 0);
8149 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8150 INTERNAL_INSN2_CODE_NAME, 0);
8151 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8152 CHIP_NAME, STATE_NAME, CHIP_NAME);
8153 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8154 fprintf (output_file, " if (%s (%s, &%s) > 0)\n abort ();\n",
8155 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8156 fprintf (output_file, " return %s (%s, &%s);\n",
8157 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8159 fprintf (output_file, "}\n\n");
8162 /* Output function `internal_insn_latency'. */
8164 output_internal_insn_latency_func ()
8167 struct bypass_decl *bypass;
8170 fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8171 INTERNAL_INSN_LATENCY_FUNC_NAME);
8172 fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
8173 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8174 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8175 INSN2_PARAMETER_NAME);
8176 fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
8177 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8178 fprintf (output_file,
8179 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8180 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8181 fprintf (output_file, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8182 for (i = 0; i < description->decls_num; i++)
8184 decl = description->decls [i];
8185 if (decl->mode == dm_insn_reserv)
8187 fprintf (output_file, " case %d:\n",
8188 decl->decl.insn_reserv.insn_num);
8189 if (decl->decl.insn_reserv.bypass_list == NULL)
8190 fprintf (output_file, " return (%s != %s ? %d : 0);\n",
8191 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8192 decl->decl.insn_reserv.default_latency);
8195 fprintf (output_file, " switch (%s)\n {\n",
8196 INTERNAL_INSN2_CODE_NAME);
8197 for (bypass = decl->decl.insn_reserv.bypass_list;
8199 bypass = bypass->next)
8201 fprintf (output_file, " case %d:\n",
8202 bypass->in_insn_reserv->insn_num);
8203 if (bypass->bypass_guard_name == NULL)
8204 fprintf (output_file, " return %d;\n",
8207 fprintf (output_file,
8208 " return (%s (%s, %s) ? %d : %d);\n",
8209 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8210 INSN2_PARAMETER_NAME, bypass->latency,
8211 decl->decl.insn_reserv.default_latency);
8213 fprintf (output_file, " default:\n");
8214 fprintf (output_file,
8215 " return (%s != %s ? %d : 0);\n }\n",
8216 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8217 decl->decl.insn_reserv.default_latency);
8222 fprintf (output_file, " default:\n return 0;\n }\n}\n\n");
8225 /* The function outputs PHR interface function `insn_latency'. */
8227 output_insn_latency_func ()
8229 fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8230 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8231 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8232 fprintf (output_file, "{\n int %s, %s;\n",
8233 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8234 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8235 INTERNAL_INSN_CODE_NAME, 0);
8236 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8237 INTERNAL_INSN2_CODE_NAME, 0);
8238 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8239 INTERNAL_INSN_LATENCY_FUNC_NAME,
8240 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8241 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8244 /* The function outputs PHR interface function `print_reservation'. */
8246 output_print_reservation_func ()
8251 fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8252 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8253 INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8254 INSN_PARAMETER_NAME);
8255 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8256 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8257 fprintf (output_file, " %s = %s (%s);\n",
8258 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8259 INSN_PARAMETER_NAME);
8260 fprintf (output_file, " if (%s > %s)\n",
8261 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8262 fprintf (output_file, " {\n fprintf (%s, \"%s\");\n",
8263 FILE_PARAMETER_NAME, NOTHING_NAME);
8264 fprintf (output_file, " return;\n }\n");
8265 fprintf (output_file, " }\n else\n");
8266 fprintf (output_file,
8267 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8268 FILE_PARAMETER_NAME, NOTHING_NAME);
8269 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8270 for (i = 0; i < description->decls_num; i++)
8272 decl = description->decls [i];
8273 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8275 fprintf (output_file,
8276 " case %d:\n", decl->decl.insn_reserv.insn_num);
8277 fprintf (output_file,
8278 " fprintf (%s, \"%s\");\n break;\n",
8279 FILE_PARAMETER_NAME,
8280 regexp_representation (decl->decl.insn_reserv.regexp));
8281 finish_regexp_representation ();
8284 fprintf (output_file, " default:\n fprintf (%s, \"%s\");\n }\n",
8285 FILE_PARAMETER_NAME, NOTHING_NAME);
8286 fprintf (output_file, "}\n\n");
8289 /* The following function is used to sort unit declaration by their
8292 units_cmp (unit1, unit2)
8293 const void *unit1, *unit2;
8295 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8296 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8298 return strcmp (u1->name, u2->name);
8301 /* The following macro value is name of struct containing unit name
8303 #define NAME_CODE_STRUCT_NAME "name_code"
8305 /* The following macro value is name of table of struct name_code. */
8306 #define NAME_CODE_TABLE_NAME "name_code_table"
8308 /* The following macro values are member names for struct name_code. */
8309 #define NAME_MEMBER_NAME "name"
8310 #define CODE_MEMBER_NAME "code"
8312 /* The following macro values are local variable names for function
8313 `get_cpu_unit_code'. */
8314 #define CMP_VARIABLE_NAME "cmp"
8315 #define LOW_VARIABLE_NAME "l"
8316 #define MIDDLE_VARIABLE_NAME "m"
8317 #define HIGH_VARIABLE_NAME "h"
8319 /* The following function outputs function to obtain internal cpu unit
8320 code by the cpu unit name. */
8322 output_get_cpu_unit_code_func ()
8327 fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8328 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8329 CPU_UNIT_NAME_PARAMETER_NAME);
8330 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8331 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8332 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8333 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8334 fprintf (output_file, " static struct %s %s [] =\n {\n",
8335 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8336 units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
8337 * description->units_num);
8338 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8339 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8340 for (i = 0; i < description->units_num; i++)
8341 if (units [i]->query_p)
8342 fprintf (output_file, " {\"%s\", %d},\n",
8343 units[i]->name, units[i]->query_num);
8344 fprintf (output_file, " };\n\n");
8345 fprintf (output_file, " /* The following is binary search: */\n");
8346 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8347 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8348 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8349 fprintf (output_file, " while (%s <= %s)\n {\n",
8350 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8351 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8352 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8353 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8354 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8355 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8356 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8357 fprintf (output_file, " %s = %s - 1;\n",
8358 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8359 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8360 fprintf (output_file, " %s = %s + 1;\n",
8361 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8362 fprintf (output_file, " else\n");
8363 fprintf (output_file, " return %s [%s].%s;\n }\n",
8364 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8365 fprintf (output_file, " return -1;\n}\n\n");
8369 /* The following function outputs function to check reservation of cpu
8370 unit (its internal code will be passed as the function argument) in
8373 output_cpu_unit_reservation_p ()
8375 automaton_t automaton;
8377 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8378 CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8379 CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8380 CPU_CODE_PARAMETER_NAME);
8381 fprintf (output_file, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8382 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8383 description->query_units_num);
8384 for (automaton = description->first_automaton;
8386 automaton = automaton->next_automaton)
8388 fprintf (output_file, " if ((");
8389 output_reserved_units_table_name (output_file, automaton);
8390 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8391 output_chip_member_name (output_file, automaton);
8392 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8393 (description->query_units_num + 7) / 8,
8394 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8395 fprintf (output_file, " return 1;\n");
8397 fprintf (output_file, " return 0;\n}\n\n");
8400 /* The function outputs PHR interface function `dfa_start'. */
8402 output_dfa_start_func ()
8404 fprintf (output_file,
8405 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8406 DFA_START_FUNC_NAME, I_VARIABLE_NAME,
8407 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8408 fprintf (output_file, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8409 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8410 fprintf (output_file,
8411 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8412 I_VARIABLE_NAME, I_VARIABLE_NAME,
8413 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8414 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8417 /* The function outputs PHR interface function `dfa_finish'. */
8419 output_dfa_finish_func ()
8421 fprintf (output_file, "void\n%s ()\n{\n free (%s);\n}\n\n",
8422 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8427 /* The page contains code for output description file (readable
8428 representation of original description and generated DFA(s). */
8430 /* The function outputs string representation of IR reservation. */
8432 output_regexp (regexp)
8435 fprintf (output_description_file, "%s", regexp_representation (regexp));
8436 finish_regexp_representation ();
8439 /* Output names of units in LIST separated by comma. */
8441 output_unit_set_el_list (list)
8446 for (el = list; el != NULL; el = el->next_unit_set_el)
8449 fprintf (output_description_file, ",");
8450 fprintf (output_description_file, "%s", el->unit_decl->name);
8454 /* The function outputs string representation of IR define_reservation
8455 and define_insn_reservation. */
8457 output_description ()
8462 for (i = 0; i < description->decls_num; i++)
8464 decl = description->decls [i];
8465 if (decl->mode == dm_unit)
8467 if (decl->decl.unit.excl_list != NULL)
8469 fprintf (output_description_file, "unit %s exlusion_set: ",
8470 decl->decl.unit.name);
8471 output_unit_set_el_list (decl->decl.unit.excl_list);
8472 fprintf (output_description_file, "\n");
8474 if (decl->decl.unit.presence_list != NULL)
8476 fprintf (output_description_file, "unit %s presence_set: ",
8477 decl->decl.unit.name);
8478 output_unit_set_el_list (decl->decl.unit.presence_list);
8479 fprintf (output_description_file, "\n");
8481 if (decl->decl.unit.absence_list != NULL)
8483 fprintf (output_description_file, "unit %s absence_set: ",
8484 decl->decl.unit.name);
8485 output_unit_set_el_list (decl->decl.unit.absence_list);
8486 fprintf (output_description_file, "\n");
8490 fprintf (output_description_file, "\n");
8491 for (i = 0; i < description->decls_num; i++)
8493 decl = description->decls [i];
8494 if (decl->mode == dm_reserv)
8496 fprintf (output_description_file, "reservation ");
8497 fprintf (output_description_file, decl->decl.reserv.name);
8498 fprintf (output_description_file, ": ");
8499 output_regexp (decl->decl.reserv.regexp);
8500 fprintf (output_description_file, "\n");
8502 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8504 fprintf (output_description_file, "insn reservation %s ",
8505 decl->decl.insn_reserv.name);
8506 print_rtl (output_description_file, decl->decl.insn_reserv.condexp);
8507 fprintf (output_description_file, ": ");
8508 output_regexp (decl->decl.insn_reserv.regexp);
8509 fprintf (output_description_file, "\n");
8511 else if (decl->mode == dm_bypass)
8512 fprintf (output_description_file, "bypass %d %s %s\n",
8513 decl->decl.bypass.latency, decl->decl.bypass.out_insn_name,
8514 decl->decl.bypass.in_insn_name);
8516 fprintf (output_description_file, "\n\f\n");
8519 /* The function outputs name of AUTOMATON. */
8521 output_automaton_name (f, automaton)
8523 automaton_t automaton;
8525 if (automaton->corresponding_automaton_decl == NULL)
8526 fprintf (f, "#%d", automaton->automaton_order_num);
8528 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8531 /* Maximal length of line for pretty printing into description
8533 #define MAX_LINE_LENGTH 70
8535 /* The function outputs units name belonging to AUTOMATON. */
8537 output_automaton_units (automaton)
8538 automaton_t automaton;
8542 int curr_line_length;
8543 int there_is_an_automaton_unit;
8546 fprintf (output_description_file, "\n Coresponding units:\n");
8547 fprintf (output_description_file, " ");
8548 curr_line_length = 4;
8549 there_is_an_automaton_unit = 0;
8550 for (i = 0; i < description->decls_num; i++)
8552 decl = description->decls [i];
8553 if (decl->mode == dm_unit
8554 && (decl->decl.unit.corresponding_automaton_num
8555 == automaton->automaton_order_num))
8557 there_is_an_automaton_unit = 1;
8558 name = decl->decl.unit.name;
8559 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8561 curr_line_length = strlen (name) + 4;
8562 fprintf (output_description_file, "\n ");
8566 curr_line_length += strlen (name) + 1;
8567 fprintf (output_description_file, " ");
8569 fprintf (output_description_file, name);
8572 if (!there_is_an_automaton_unit)
8573 fprintf (output_description_file, "<None>");
8574 fprintf (output_description_file, "\n\n");
8577 /* The following variable is used for forming array of all possible cpu unit
8578 reservations described by the current DFA state. */
8579 static vla_ptr_t state_reservs;
8581 /* The function forms `state_reservs' for STATE. */
8583 add_state_reservs (state)
8586 alt_state_t curr_alt_state;
8587 reserv_sets_t reservs;
8589 if (state->component_states != NULL)
8590 for (curr_alt_state = state->component_states;
8591 curr_alt_state != NULL;
8592 curr_alt_state = curr_alt_state->next_sorted_alt_state)
8593 add_state_reservs (curr_alt_state->state);
8596 reservs = state->reservs;
8597 VLA_PTR_ADD (state_reservs, reservs);
8601 /* The function outputs readable represenatation of all out arcs of
8604 output_state_arcs (state)
8610 int curr_line_length;
8612 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8615 if (!ainsn->first_insn_with_same_reservs)
8617 fprintf (output_description_file, " ");
8618 curr_line_length = 7;
8619 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8622 insn_name = ainsn->insn_reserv_decl->name;
8623 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8625 if (ainsn != arc->insn)
8627 fprintf (output_description_file, ",\n ");
8628 curr_line_length = strlen (insn_name) + 6;
8631 curr_line_length += strlen (insn_name);
8635 curr_line_length += strlen (insn_name);
8636 if (ainsn != arc->insn)
8638 curr_line_length += 2;
8639 fprintf (output_description_file, ", ");
8642 fprintf (output_description_file, insn_name);
8643 ainsn = ainsn->next_same_reservs_insn;
8645 while (ainsn != NULL);
8646 fprintf (output_description_file, " %d (%d)\n",
8647 arc->to_state->order_state_num, arc->state_alts);
8649 fprintf (output_description_file, "\n");
8652 /* The following function is used for sorting possible cpu unit
8653 reservation of a DFA state. */
8655 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
8656 const void *reservs_ptr_1;
8657 const void *reservs_ptr_2;
8659 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
8660 *(reserv_sets_t *) reservs_ptr_2);
8663 /* The following function is used for sorting possible cpu unit
8664 reservation of a DFA state. */
8666 remove_state_duplicate_reservs ()
8668 reserv_sets_t *reservs_ptr;
8669 reserv_sets_t *last_formed_reservs_ptr;
8671 last_formed_reservs_ptr = NULL;
8672 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8673 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8675 if (last_formed_reservs_ptr == NULL)
8676 last_formed_reservs_ptr = reservs_ptr;
8677 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
8679 ++last_formed_reservs_ptr;
8680 *last_formed_reservs_ptr = *reservs_ptr;
8682 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
8685 /* The following function output readable representation of DFA(s)
8686 state used for fast recognition of pipeline hazards. State is
8687 described by possible (current and scehduled) cpu unit
8690 output_state (state)
8693 reserv_sets_t *reservs_ptr;
8695 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
8696 fprintf (output_description_file, " State #%d", state->order_state_num);
8697 fprintf (output_description_file,
8698 state->new_cycle_p ? " (new cycle)\n" : "\n");
8699 add_state_reservs (state);
8700 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
8701 sizeof (reserv_sets_t), state_reservs_cmp);
8702 remove_state_duplicate_reservs ();
8703 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8704 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8707 fprintf (output_description_file, " ");
8708 output_reserv_sets (output_description_file, *reservs_ptr);
8709 fprintf (output_description_file, "\n");
8711 fprintf (output_description_file, "\n");
8712 output_state_arcs (state);
8713 VLA_PTR_DELETE (state_reservs);
8716 /* The following function output readable representation of
8717 DFAs used for fast recognition of pipeline hazards. */
8719 output_automaton_descriptions ()
8721 automaton_t automaton;
8723 for (automaton = description->first_automaton;
8725 automaton = automaton->next_automaton)
8727 fprintf (output_description_file, "\nAutomaton ");
8728 output_automaton_name (output_description_file, automaton);
8729 fprintf (output_description_file, "\n");
8730 output_automaton_units (automaton);
8731 pass_states (automaton, output_state);
8737 /* The page contains top level function for generation DFA(s) used for
8740 /* The function outputs statistics about work of different phases of
8743 output_statistics (f)
8746 automaton_t automaton;
8748 int transition_comb_vect_els = 0;
8749 int transition_full_vect_els = 0;
8750 int state_alts_comb_vect_els = 0;
8751 int state_alts_full_vect_els = 0;
8752 int min_issue_delay_vect_els = 0;
8755 for (automaton = description->first_automaton;
8757 automaton = automaton->next_automaton)
8759 fprintf (f, "\nAutomaton ");
8760 output_automaton_name (f, automaton);
8761 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
8762 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
8763 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
8764 automaton->DFA_states_num, automaton->DFA_arcs_num);
8765 if (!no_minimization_flag)
8766 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8767 automaton->minimal_DFA_states_num,
8768 automaton->minimal_DFA_arcs_num);
8769 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
8770 description->insns_num, automaton->insn_equiv_classes_num);
8773 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8774 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
8775 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
8776 (comb_vect_p (automaton->trans_table)
8777 ? "use comb vect" : "use simple vect"));
8779 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8780 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
8781 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
8782 (comb_vect_p (automaton->state_alts_table)
8783 ? "use comb vect" : "use simple vect"));
8785 (f, "%5ld min delay table els, compression factor %d\n",
8786 (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
8787 automaton->min_issue_delay_table_compression_factor);
8788 transition_comb_vect_els
8789 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
8790 transition_full_vect_els
8791 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
8792 state_alts_comb_vect_els
8793 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
8794 state_alts_full_vect_els
8795 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
8796 min_issue_delay_vect_els
8797 += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
8801 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
8802 allocated_states_num, allocated_arcs_num);
8803 fprintf (f, "%5d all allocated alternative states\n",
8804 allocated_alt_states_num);
8805 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
8806 transition_comb_vect_els, transition_full_vect_els);
8808 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
8809 state_alts_comb_vect_els, state_alts_full_vect_els);
8810 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
8811 fprintf (f, "%5d locked states num\n", locked_states_num);
8815 /* The function output times of work of different phases of DFA
8818 output_time_statistics (f)
8821 fprintf (f, "\n transformation: ");
8822 print_active_time (f, transform_time);
8823 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
8824 print_active_time (f, NDFA_time);
8827 fprintf (f, ", NDFA -> DFA: ");
8828 print_active_time (f, NDFA_to_DFA_time);
8830 fprintf (f, "\n DFA minimization: ");
8831 print_active_time (f, minimize_time);
8832 fprintf (f, ", making insn equivalence: ");
8833 print_active_time (f, equiv_time);
8834 fprintf (f, "\n all automaton generation: ");
8835 print_active_time (f, automaton_generation_time);
8836 fprintf (f, ", output: ");
8837 print_active_time (f, output_time);
8841 /* The function generates DFA (deterministic finate state automaton)
8842 for fast recognition of pipeline hazards. No errors during
8843 checking must be fixed before this function call. */
8847 automata_num = split_argument;
8848 if (description->units_num < automata_num)
8849 automata_num = description->units_num;
8852 initiate_automata_lists ();
8853 initiate_pass_states ();
8854 initiate_excl_sets ();
8855 initiate_presence_absence_sets ();
8856 automaton_generation_time = create_ticker ();
8858 ticker_off (&automaton_generation_time);
8863 /* The following function creates attribute which order number of insn
8864 in pipeline hazard description translator. */
8866 make_insn_alts_attr ()
8872 condexp = rtx_alloc (COND);
8873 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8874 XEXP (condexp, 1) = make_numeric_value (0);
8875 for (i = insn_num = 0; i < description->decls_num; i++)
8877 decl = description->decls [i];
8878 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8880 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8881 XVECEXP (condexp, 0, 2 * insn_num + 1)
8882 = make_numeric_value (decl->decl.insn_reserv.transformed_regexp
8883 ->regexp.oneof.regexps_num);
8887 if (description->insns_num != insn_num + 1)
8889 make_internal_attr (attr_printf (sizeof ("*")
8890 + strlen (INSN_ALTS_FUNC_NAME) + 1,
8891 "*%s", INSN_ALTS_FUNC_NAME),
8897 /* The following function creates attribute which is order number of
8898 insn in pipeline hazard description translator. */
8900 make_internal_dfa_insn_code_attr ()
8906 condexp = rtx_alloc (COND);
8907 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8908 XEXP (condexp, 1) = make_numeric_value (advance_cycle_insn_decl
8909 ->decl.insn_reserv.insn_num + 1);
8910 for (i = insn_num = 0; i < description->decls_num; i++)
8912 decl = description->decls [i];
8913 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8915 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8916 XVECEXP (condexp, 0, 2 * insn_num + 1)
8917 = make_numeric_value (decl->decl.insn_reserv.insn_num);
8921 if (description->insns_num != insn_num + 1)
8924 (attr_printf (sizeof ("*")
8925 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
8926 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
8932 /* The following function creates attribute which order number of insn
8933 in pipeline hazard description translator. */
8935 make_default_insn_latency_attr ()
8941 condexp = rtx_alloc (COND);
8942 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8943 XEXP (condexp, 1) = make_numeric_value (0);
8944 for (i = insn_num = 0; i < description->decls_num; i++)
8946 decl = description->decls [i];
8947 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8949 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8950 XVECEXP (condexp, 0, 2 * insn_num + 1)
8951 = make_numeric_value (decl->decl.insn_reserv.default_latency);
8955 if (description->insns_num != insn_num + 1)
8957 make_internal_attr (attr_printf (sizeof ("*")
8958 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
8959 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
8965 /* The following function creates attribute which returns 1 if given
8966 output insn has bypassing and 0 otherwise. */
8971 int bypass_insns_num = 0;
8975 for (i = 0; i < description->decls_num; i++)
8977 decl = description->decls [i];
8978 if (decl->mode == dm_insn_reserv
8979 && decl->decl.insn_reserv.condexp != NULL
8980 && decl->decl.insn_reserv.bypass_list != NULL)
8983 if (bypass_insns_num == 0)
8984 result_rtx = make_numeric_value (0);
8987 result_rtx = rtx_alloc (COND);
8988 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
8989 XEXP (result_rtx, 1) = make_numeric_value (0);
8991 for (i = bypass_insn = 0; i < description->decls_num; i++)
8993 decl = description->decls [i];
8994 if (decl->mode == dm_insn_reserv
8995 && decl->decl.insn_reserv.condexp != NULL
8996 && decl->decl.insn_reserv.bypass_list != NULL)
8998 XVECEXP (result_rtx, 0, 2 * bypass_insn)
8999 = decl->decl.insn_reserv.condexp;
9000 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9001 = make_numeric_value (1);
9006 make_internal_attr (attr_printf (sizeof ("*")
9007 + strlen (BYPASS_P_FUNC_NAME) + 1,
9008 "*%s", BYPASS_P_FUNC_NAME),
9014 /* This page mainly contains top level functions of pipeline hazards
9015 description translator. */
9017 /* The following macro value is suffix of name of description file of
9018 pipeline hazards description translator. */
9019 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9021 /* The function returns suffix of given file name. The returned
9022 string can not be changed. */
9024 file_name_suffix (file_name)
9025 const char *file_name;
9027 const char *last_period;
9029 for (last_period = NULL; *file_name != '\0'; file_name++)
9030 if (*file_name == '.')
9031 last_period = file_name;
9032 return (last_period == NULL ? file_name : last_period);
9035 /* The function returns base name of given file name, i.e. pointer to
9036 first char after last `/' (or `\' for WIN32) in given file name,
9037 given file name itself if the directory name is absent. The
9038 returned string can not be changed. */
9040 base_file_name (file_name)
9041 const char *file_name;
9043 int directory_name_length;
9045 directory_name_length = strlen (file_name);
9047 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9048 && file_name[directory_name_length] != '\\')
9050 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9052 directory_name_length--;
9053 return file_name + directory_name_length + 1;
9056 /* The following is top level function to initialize the work of
9057 pipeline hazards description translator. */
9059 initiate_automaton_gen (argc, argv)
9063 const char *base_name;
9067 split_argument = 0; /* default value */
9068 no_minimization_flag = 0;
9072 for (i = 2; i < argc; i++)
9073 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9074 no_minimization_flag = 1;
9075 else if (strcmp (argv [i], "-time") == 0)
9077 else if (strcmp (argv [i], "-v") == 0)
9079 else if (strcmp (argv [i], W_OPTION) == 0)
9081 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9083 else if (strcmp (argv [i], "-split") == 0)
9086 fatal ("-split has no argument.");
9087 fatal ("option `-split' has not been implemented yet\n");
9088 /* split_argument = atoi (argument_vect [i + 1]); */
9090 VLA_PTR_CREATE (decls, 150, "decls");
9091 /* Initialize IR storage. */
9092 obstack_init (&irp);
9093 initiate_automaton_decl_table ();
9094 initiate_insn_decl_table ();
9095 initiate_decl_table ();
9096 output_file = stdout;
9097 output_description_file = NULL;
9098 base_name = base_file_name (argv[1]);
9099 obstack_grow (&irp, base_name,
9100 strlen (base_name) - strlen (file_name_suffix (base_name)));
9101 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9102 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9103 obstack_1grow (&irp, '\0');
9104 output_description_file_name = obstack_base (&irp);
9105 obstack_finish (&irp);
9108 /* The following function checks existence at least one arc marked by
9111 check_automata_insn_issues ()
9113 automaton_t automaton;
9114 ainsn_t ainsn, reserv_ainsn;
9116 for (automaton = description->first_automaton;
9118 automaton = automaton->next_automaton)
9120 for (ainsn = automaton->ainsn_list;
9122 ainsn = ainsn->next_ainsn)
9123 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9125 for (reserv_ainsn = ainsn;
9126 reserv_ainsn != NULL;
9127 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9128 if (automaton->corresponding_automaton_decl != NULL)
9131 error ("Automaton `%s': Insn `%s' will never be issued",
9132 automaton->corresponding_automaton_decl->name,
9133 reserv_ainsn->insn_reserv_decl->name);
9136 ("Automaton `%s': Insn `%s' will never be issued",
9137 automaton->corresponding_automaton_decl->name,
9138 reserv_ainsn->insn_reserv_decl->name);
9143 error ("Insn `%s' will never be issued",
9144 reserv_ainsn->insn_reserv_decl->name);
9146 warning ("Insn `%s' will never be issued",
9147 reserv_ainsn->insn_reserv_decl->name);
9153 /* The following vla is used for storing pointers to all achieved
9155 static vla_ptr_t automaton_states;
9157 /* This function is called by function pass_states to add an achieved
9160 add_automaton_state (state)
9163 VLA_PTR_ADD (automaton_states, state);
9166 /* The following function forms list of important automata (whose
9167 states may be changed after the insn issue) for each insn. */
9169 form_important_insn_automata_lists ()
9171 automaton_t automaton;
9178 VLA_PTR_CREATE (automaton_states, 1500,
9179 "automaton states for forming important insn automata sets");
9180 /* Mark important ainsns. */
9181 for (automaton = description->first_automaton;
9183 automaton = automaton->next_automaton)
9185 VLA_PTR_NULLIFY (automaton_states);
9186 pass_states (automaton, add_automaton_state);
9187 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9188 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9191 for (arc = first_out_arc (*state_ptr);
9193 arc = next_out_arc (arc))
9194 if (arc->to_state != *state_ptr)
9196 if (!arc->insn->first_insn_with_same_reservs)
9198 for (ainsn = arc->insn;
9200 ainsn = ainsn->next_same_reservs_insn)
9201 ainsn->important_p = TRUE;
9205 VLA_PTR_DELETE (automaton_states);
9206 /* Create automata sets for the insns. */
9207 for (i = 0; i < description->decls_num; i++)
9209 decl = description->decls [i];
9210 if (decl->mode == dm_insn_reserv)
9212 automata_list_start ();
9213 for (automaton = description->first_automaton;
9215 automaton = automaton->next_automaton)
9216 for (ainsn = automaton->ainsn_list;
9218 ainsn = ainsn->next_ainsn)
9219 if (ainsn->important_p
9220 && ainsn->insn_reserv_decl == &decl->decl.insn_reserv)
9222 automata_list_add (automaton);
9225 decl->decl.insn_reserv.important_automata_list
9226 = automata_list_finish ();
9232 /* The following is top level function to generate automat(a,on) for
9233 fast recognition of pipeline hazards. */
9239 description = create_node (sizeof (struct description)
9240 /* One entry for cycle advancing insn. */
9241 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9242 description->decls_num = VLA_PTR_LENGTH (decls);
9243 description->query_units_num = 0;
9244 for (i = 0; i < description->decls_num; i++)
9246 description->decls [i] = VLA_PTR (decls, i);
9247 if (description->decls [i]->mode == dm_unit
9248 && description->decls [i]->decl.unit.query_p)
9249 description->decls [i]->decl.unit.query_num
9250 = description->query_units_num++;
9252 all_time = create_ticker ();
9253 check_time = create_ticker ();
9254 fprintf (stderr, "Check description...");
9256 check_all_description ();
9257 fprintf (stderr, "done\n");
9258 ticker_off (&check_time);
9259 generation_time = create_ticker ();
9262 transform_insn_regexps ();
9263 check_unit_distributions_to_automata ();
9268 check_automata_insn_issues ();
9272 form_important_insn_automata_lists ();
9273 fprintf (stderr, "Generation of attributes...");
9275 make_internal_dfa_insn_code_attr ();
9276 make_insn_alts_attr ();
9277 make_default_insn_latency_attr ();
9278 make_bypass_attr ();
9279 fprintf (stderr, "done\n");
9281 ticker_off (&generation_time);
9282 ticker_off (&all_time);
9283 fprintf (stderr, "All other genattrtab stuff...");
9287 /* The following is top level function to output PHR and to finish
9288 work with pipeline description translator. */
9292 fprintf (stderr, "done\n");
9294 fatal ("Errors in DFA description");
9295 ticker_on (&all_time);
9296 output_time = create_ticker ();
9297 fprintf (stderr, "Forming and outputing automata tables...");
9299 output_dfa_max_issue_rate ();
9301 fprintf (stderr, "done\n");
9302 fprintf (stderr, "Output functions to work with automata...");
9304 output_chip_definitions ();
9305 output_max_insn_queue_index_def ();
9306 output_internal_min_issue_delay_func ();
9307 output_internal_trans_func ();
9308 /* Cache of insn dfa codes: */
9309 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9310 fprintf (output_file, "\nstatic int %s;\n\n",
9311 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9312 output_dfa_insn_code_func ();
9313 output_trans_func ();
9314 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9315 output_internal_state_alts_func ();
9316 output_state_alts_func ();
9317 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9318 AUTOMATON_STATE_ALTS_MACRO_NAME);
9319 output_min_issue_delay_func ();
9320 output_internal_dead_lock_func ();
9321 output_dead_lock_func ();
9322 output_size_func ();
9323 output_internal_reset_func ();
9324 output_reset_func ();
9325 output_min_insn_conflict_delay_func ();
9326 output_internal_insn_latency_func ();
9327 output_insn_latency_func ();
9328 output_print_reservation_func ();
9329 if (no_minimization_flag)
9331 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9332 output_get_cpu_unit_code_func ();
9333 output_cpu_unit_reservation_p ();
9334 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9335 CPU_UNITS_QUERY_MACRO_NAME);
9337 output_dfa_start_func ();
9338 output_dfa_finish_func ();
9339 fprintf (stderr, "done\n");
9342 output_description_file = fopen (output_description_file_name, "w");
9343 if (output_description_file == NULL)
9345 perror (output_description_file_name);
9346 exit (FATAL_EXIT_CODE);
9348 fprintf (stderr, "Output automata description...");
9350 output_description ();
9351 output_automaton_descriptions ();
9352 fprintf (stderr, "done\n");
9353 output_statistics (output_description_file);
9355 output_statistics (stderr);
9356 ticker_off (&output_time);
9357 output_time_statistics (stderr);
9360 finish_automata_lists ();
9363 fprintf (stderr, "Summary:\n");
9364 fprintf (stderr, " check time ");
9365 print_active_time (stderr, check_time);
9366 fprintf (stderr, ", generation time ");
9367 print_active_time (stderr, generation_time);
9368 fprintf (stderr, ", all time ");
9369 print_active_time (stderr, all_time);
9370 fprintf (stderr, "\n");
9372 /* Finish all work. */
9373 if (output_description_file != NULL)
9375 fflush (output_description_file);
9376 if (ferror (stdout) != 0)
9377 fatal ("Error in writing DFA description file %s",
9378 output_description_file_name);
9379 fclose (output_description_file);
9381 finish_automaton_decl_table ();
9382 finish_insn_decl_table ();
9383 finish_decl_table ();
9384 obstack_free (&irp, NULL);
9385 if (have_error && output_description_file != NULL)
9386 remove (output_description_file_name);