1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001 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 decl *decl_t;
199 typedef struct regexp *regexp_t;
200 typedef struct unit_set_el *unit_set_el_t;
201 typedef struct alt_state *alt_state_t;
202 typedef struct state *state_t;
203 typedef struct arc *arc_t;
204 typedef struct ainsn *ainsn_t;
205 typedef struct automaton *automaton_t;
206 typedef struct automata_list_el *automata_list_el_t;
207 typedef struct state_ainsn_table *state_ainsn_table_t;
210 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
211 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
212 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
213 initiate_automaton_gen, expand_automata, write_automata are
214 described on the file top because the functions are called from
217 static void *create_node PARAMS ((size_t));
218 static void *copy_node PARAMS ((void *, size_t));
219 static char *check_name PARAMS ((char *, pos_t));
220 static char *next_sep_el PARAMS ((char **, int, int));
221 static int n_sep_els PARAMS ((char *, int, int));
222 static char **get_str_vect PARAMS ((char *, int *, int, int));
223 static regexp_t gen_regexp_el PARAMS ((char *));
224 static regexp_t gen_regexp_repeat PARAMS ((char *));
225 static regexp_t gen_regexp_allof PARAMS ((char *));
226 static regexp_t gen_regexp_oneof PARAMS ((char *));
227 static regexp_t gen_regexp_sequence PARAMS ((char *));
228 static regexp_t gen_regexp PARAMS ((char *));
230 static unsigned string_hash PARAMS ((const char *));
231 static unsigned automaton_decl_hash PARAMS ((const void *));
232 static int automaton_decl_eq_p PARAMS ((const void *,
234 static decl_t insert_automaton_decl PARAMS ((decl_t));
235 static decl_t find_automaton_decl PARAMS ((char *));
236 static void initiate_automaton_decl_table PARAMS ((void));
237 static void finish_automaton_decl_table PARAMS ((void));
239 static unsigned insn_decl_hash PARAMS ((const void *));
240 static int insn_decl_eq_p PARAMS ((const void *,
242 static decl_t insert_insn_decl PARAMS ((decl_t));
243 static decl_t find_insn_decl PARAMS ((char *));
244 static void initiate_insn_decl_table PARAMS ((void));
245 static void finish_insn_decl_table PARAMS ((void));
247 static unsigned decl_hash PARAMS ((const void *));
248 static int decl_eq_p PARAMS ((const void *,
250 static decl_t insert_decl PARAMS ((decl_t));
251 static decl_t find_decl PARAMS ((char *));
252 static void initiate_decl_table PARAMS ((void));
253 static void finish_decl_table PARAMS ((void));
255 static unit_set_el_t process_excls PARAMS ((char **, int, pos_t));
256 static void add_excls PARAMS ((unit_set_el_t, unit_set_el_t,
258 static unit_set_el_t process_presence_absence
259 PARAMS ((char **, int, pos_t, int));
260 static void add_presence_absence PARAMS ((unit_set_el_t, unit_set_el_t,
262 static void process_decls PARAMS ((void));
263 static struct bypass_decl *find_bypass PARAMS ((struct bypass_decl *,
264 struct insn_reserv_decl *));
265 static void check_automaton_usage PARAMS ((void));
266 static regexp_t process_regexp PARAMS ((regexp_t));
267 static void process_regexp_decls PARAMS ((void));
268 static void check_usage PARAMS ((void));
269 static int loop_in_regexp PARAMS ((regexp_t, decl_t));
270 static void check_loops_in_regexps PARAMS ((void));
271 static int process_regexp_cycles PARAMS ((regexp_t, int));
272 static void evaluate_max_reserv_cycles PARAMS ((void));
273 static void check_all_description PARAMS ((void));
275 static ticker_t create_ticker PARAMS ((void));
276 static void ticker_off PARAMS ((ticker_t *));
277 static void ticker_on PARAMS ((ticker_t *));
278 static int active_time PARAMS ((ticker_t));
279 static void print_active_time PARAMS ((FILE *, ticker_t));
281 static void add_advance_cycle_insn_decl PARAMS ((void));
283 static alt_state_t get_free_alt_state PARAMS ((void));
284 static void free_alt_state PARAMS ((alt_state_t));
285 static void free_alt_states PARAMS ((alt_state_t));
286 static int alt_state_cmp PARAMS ((const void *alt_state_ptr_1,
287 const void *alt_state_ptr_2));
288 static alt_state_t uniq_sort_alt_states PARAMS ((alt_state_t));
289 static int alt_states_eq PARAMS ((alt_state_t, alt_state_t));
290 static void initiate_alt_states PARAMS ((void));
291 static void finish_alt_states PARAMS ((void));
293 static reserv_sets_t alloc_empty_reserv_sets PARAMS ((void));
294 static unsigned reserv_sets_hash_value PARAMS ((reserv_sets_t));
295 static int reserv_sets_cmp PARAMS ((reserv_sets_t, reserv_sets_t));
296 static int reserv_sets_eq PARAMS ((reserv_sets_t, reserv_sets_t));
297 static void set_unit_reserv PARAMS ((reserv_sets_t, int, int));
298 static int test_unit_reserv PARAMS ((reserv_sets_t, int, int));
299 static int it_is_empty_reserv_sets PARAMS ((reserv_sets_t))
301 static int reserv_sets_are_intersected PARAMS ((reserv_sets_t, reserv_sets_t));
302 static void reserv_sets_shift PARAMS ((reserv_sets_t, reserv_sets_t));
303 static void reserv_sets_or PARAMS ((reserv_sets_t, reserv_sets_t,
305 static void reserv_sets_and PARAMS ((reserv_sets_t, reserv_sets_t,
308 static void output_cycle_reservs PARAMS ((FILE *, reserv_sets_t,
310 static void output_reserv_sets PARAMS ((FILE *, reserv_sets_t));
311 static state_t get_free_state PARAMS ((int, automaton_t));
312 static void free_state PARAMS ((state_t));
313 static unsigned state_hash PARAMS ((const void *));
314 static int state_eq_p PARAMS ((const void *, const void *));
315 static state_t insert_state PARAMS ((state_t));
316 static void set_state_reserv PARAMS ((state_t, int, int));
317 static int intersected_state_reservs_p PARAMS ((state_t, state_t));
318 static state_t states_union PARAMS ((state_t, state_t));
319 static state_t state_shift PARAMS ((state_t));
320 static void initiate_states PARAMS ((void));
321 static void finish_states PARAMS ((void));
323 static void free_arc PARAMS ((arc_t));
324 static void remove_arc PARAMS ((state_t, arc_t));
325 static arc_t find_arc PARAMS ((state_t, state_t, ainsn_t));
326 static arc_t add_arc PARAMS ((state_t, state_t, ainsn_t, int));
327 static arc_t first_out_arc PARAMS ((state_t));
328 static arc_t next_out_arc PARAMS ((arc_t));
329 static void initiate_arcs PARAMS ((void));
330 static void finish_arcs PARAMS ((void));
332 static automata_list_el_t get_free_automata_list_el PARAMS ((void));
333 static void free_automata_list_el PARAMS ((automata_list_el_t));
334 static void free_automata_list PARAMS ((automata_list_el_t));
335 static unsigned automata_list_hash PARAMS ((const void *));
336 static int automata_list_eq_p PARAMS ((const void *, const void *));
337 static void initiate_automata_lists PARAMS ((void));
338 static void automata_list_start PARAMS ((void));
339 static void automata_list_add PARAMS ((automaton_t));
340 static automata_list_el_t automata_list_finish PARAMS ((void));
341 static void finish_automata_lists PARAMS ((void));
343 static void initiate_excl_sets PARAMS ((void));
344 static reserv_sets_t get_excl_set PARAMS ((reserv_sets_t));
346 static void initiate_presence_absence_sets PARAMS ((void));
347 static reserv_sets_t get_presence_absence_set PARAMS ((reserv_sets_t, int));
349 static regexp_t copy_insn_regexp PARAMS ((regexp_t));
350 static regexp_t transform_1 PARAMS ((regexp_t));
351 static regexp_t transform_2 PARAMS ((regexp_t));
352 static regexp_t transform_3 PARAMS ((regexp_t));
353 static regexp_t regexp_transform_func
354 PARAMS ((regexp_t, regexp_t (*) (regexp_t)));
355 static regexp_t transform_regexp PARAMS ((regexp_t));
356 static void transform_insn_regexps PARAMS ((void));
358 static int process_seq_for_forming_states PARAMS ((regexp_t, automaton_t,
360 static void finish_forming_alt_state PARAMS ((alt_state_t,
362 static void process_alts_for_forming_states PARAMS ((regexp_t,
364 static void create_alt_states PARAMS ((automaton_t));
366 static void form_ainsn_with_same_reservs PARAMS ((automaton_t));
368 static void make_automaton PARAMS ((automaton_t));
369 static void form_arcs_marked_by_insn PARAMS ((state_t));
370 static void create_composed_state PARAMS ((state_t, arc_t, vla_ptr_t *));
371 static void NDFA_to_DFA PARAMS ((automaton_t));
372 static void pass_state_graph PARAMS ((state_t, void (*) (state_t)));
373 static void pass_states PARAMS ((automaton_t,
374 void (*) (state_t)));
375 static void initiate_pass_states PARAMS ((void));
376 static void add_achieved_state PARAMS ((state_t));
377 static int set_out_arc_insns_equiv_num PARAMS ((state_t, int));
378 static void clear_arc_insns_equiv_num PARAMS ((state_t));
379 static void copy_equiv_class PARAMS ((vla_ptr_t *to,
380 const vla_ptr_t *from));
381 static int state_is_differed PARAMS ((state_t, int, int));
382 static state_t init_equiv_class PARAMS ((state_t *states, int));
383 static int partition_equiv_class PARAMS ((state_t *, int,
384 vla_ptr_t *, int *));
385 static void evaluate_equiv_classes PARAMS ((automaton_t, vla_ptr_t *));
386 static void merge_states PARAMS ((automaton_t, vla_ptr_t *));
387 static void set_new_cycle_flags PARAMS ((state_t));
388 static void minimize_DFA PARAMS ((automaton_t));
389 static void incr_states_and_arcs_nums PARAMS ((state_t));
390 static void count_states_and_arcs PARAMS ((automaton_t, int *, int *));
391 static void build_automaton PARAMS ((automaton_t));
393 static void set_order_state_num PARAMS ((state_t));
394 static void enumerate_states PARAMS ((automaton_t));
396 static ainsn_t insert_ainsn_into_equiv_class PARAMS ((ainsn_t, ainsn_t));
397 static void delete_ainsn_from_equiv_class PARAMS ((ainsn_t));
398 static void process_insn_equiv_class PARAMS ((ainsn_t, arc_t *));
399 static void process_state_for_insn_equiv_partition PARAMS ((state_t));
400 static void set_insn_equiv_classes PARAMS ((automaton_t));
402 static double estimate_one_automaton_bound PARAMS ((void));
403 static int compare_max_occ_cycle_nums PARAMS ((const void *,
405 static void units_to_automata_heuristic_distr PARAMS ((void));
406 static ainsn_t create_ainsns PARAMS ((void));
407 static void units_to_automata_distr PARAMS ((void));
408 static void create_automata PARAMS ((void));
410 static void form_regexp PARAMS ((regexp_t));
411 static const char *regexp_representation PARAMS ((regexp_t));
412 static void finish_regexp_representation PARAMS ((void));
414 static void output_range_type PARAMS ((FILE *, long int, long int));
415 static int longest_path_length PARAMS ((state_t));
416 static void process_state_longest_path_length PARAMS ((state_t));
417 static void output_dfa_max_issue_rate PARAMS ((void));
418 static void output_vect PARAMS ((vect_el_t *, int));
419 static void output_chip_member_name PARAMS ((FILE *, automaton_t));
420 static void output_temp_chip_member_name PARAMS ((FILE *, automaton_t));
421 static void output_translate_vect_name PARAMS ((FILE *, automaton_t));
422 static void output_trans_full_vect_name PARAMS ((FILE *, automaton_t));
423 static void output_trans_comb_vect_name PARAMS ((FILE *, automaton_t));
424 static void output_trans_check_vect_name PARAMS ((FILE *, automaton_t));
425 static void output_trans_base_vect_name PARAMS ((FILE *, automaton_t));
426 static void output_state_alts_full_vect_name PARAMS ((FILE *, automaton_t));
427 static void output_state_alts_comb_vect_name PARAMS ((FILE *, automaton_t));
428 static void output_state_alts_check_vect_name PARAMS ((FILE *, automaton_t));
429 static void output_state_alts_base_vect_name PARAMS ((FILE *, automaton_t));
430 static void output_min_issue_delay_vect_name PARAMS ((FILE *, automaton_t));
431 static void output_dead_lock_vect_name PARAMS ((FILE *, automaton_t));
432 static void output_reserved_units_table_name PARAMS ((FILE *, automaton_t));
433 static void output_state_member_type PARAMS ((FILE *, automaton_t));
434 static void output_chip_definitions PARAMS ((void));
435 static void output_translate_vect PARAMS ((automaton_t));
436 static int comb_vect_p PARAMS ((state_ainsn_table_t));
437 static state_ainsn_table_t create_state_ainsn_table PARAMS ((automaton_t));
438 static void output_state_ainsn_table
439 PARAMS ((state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
440 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
441 void (*) (FILE *, automaton_t)));
442 static void add_vect PARAMS ((state_ainsn_table_t,
443 int, vect_el_t *, int));
444 static int out_state_arcs_num PARAMS ((state_t));
445 static int compare_transition_els_num PARAMS ((const void *, const void *));
446 static void add_vect_el PARAMS ((vla_hwint_t *,
448 static void add_states_vect_el PARAMS ((state_t));
449 static void output_trans_table PARAMS ((automaton_t));
450 static void output_state_alts_table PARAMS ((automaton_t));
451 static void min_issue_delay_pass_states PARAMS ((state_t, ainsn_t));
452 static int min_issue_delay PARAMS ((state_t, ainsn_t));
453 static void initiate_min_issue_delay_pass_states PARAMS ((void));
454 static void output_min_issue_delay_table PARAMS ((automaton_t));
455 static void output_dead_lock_vect PARAMS ((automaton_t));
456 static void output_reserved_units_table PARAMS ((automaton_t));
457 static void output_tables PARAMS ((void));
458 static void output_max_insn_queue_index_def PARAMS ((void));
459 static void output_insn_code_cases PARAMS ((void (*) (automata_list_el_t)));
460 static void output_automata_list_min_issue_delay_code PARAMS ((automata_list_el_t));
461 static void output_internal_min_issue_delay_func PARAMS ((void));
462 static void output_automata_list_transition_code PARAMS ((automata_list_el_t));
463 static void output_internal_trans_func PARAMS ((void));
464 static void output_internal_insn_code_evaluation PARAMS ((const char *,
466 static void output_dfa_insn_code_func PARAMS ((void));
467 static void output_trans_func PARAMS ((void));
468 static void output_automata_list_state_alts_code PARAMS ((automata_list_el_t));
469 static void output_internal_state_alts_func PARAMS ((void));
470 static void output_state_alts_func PARAMS ((void));
471 static void output_min_issue_delay_func PARAMS ((void));
472 static void output_internal_dead_lock_func PARAMS ((void));
473 static void output_dead_lock_func PARAMS ((void));
474 static void output_internal_reset_func PARAMS ((void));
475 static void output_size_func PARAMS ((void));
476 static void output_reset_func PARAMS ((void));
477 static void output_min_insn_conflict_delay_func PARAMS ((void));
478 static void output_internal_insn_latency_func PARAMS ((void));
479 static void output_insn_latency_func PARAMS ((void));
480 static void output_print_reservation_func PARAMS ((void));
481 static int units_cmp PARAMS ((const void *,
483 static void output_get_cpu_unit_code_func PARAMS ((void));
484 static void output_cpu_unit_reservation_p PARAMS ((void));
485 static void output_dfa_start_func PARAMS ((void));
486 static void output_dfa_finish_func PARAMS ((void));
488 static void output_regexp PARAMS ((regexp_t ));
489 static void output_unit_set_el_list PARAMS ((unit_set_el_t));
490 static void output_description PARAMS ((void));
491 static void output_automaton_name PARAMS ((FILE *, automaton_t));
492 static void output_automaton_units PARAMS ((automaton_t));
493 static void add_state_reservs PARAMS ((state_t));
494 static void output_state_arcs PARAMS ((state_t));
495 static int state_reservs_cmp PARAMS ((const void *,
497 static void remove_state_duplicate_reservs PARAMS ((void));
498 static void output_state PARAMS ((state_t));
499 static void output_automaton_descriptions PARAMS ((void));
500 static void output_statistics PARAMS ((FILE *));
501 static void output_time_statistics PARAMS ((FILE *));
502 static void generate PARAMS ((void));
504 static void make_insn_alts_attr PARAMS ((void));
505 static void make_internal_dfa_insn_code_attr PARAMS ((void));
506 static void make_default_insn_latency_attr PARAMS ((void));
507 static void make_bypass_attr PARAMS ((void));
508 static const char *file_name_suffix PARAMS ((const char *));
509 static const char *base_file_name PARAMS ((const char *));
510 static void check_automata PARAMS ((void));
511 static void add_automaton_state PARAMS ((state_t));
512 static void form_important_insn_automata_lists PARAMS ((void));
514 /* Undefined position. */
515 static pos_t no_pos = 0;
517 /* All IR is stored in the following obstack. */
518 static struct obstack irp;
522 /* This page contains code for work with variable length array (vla)
523 of pointers. We could be use only varray. But we add new lay
524 because we add elements very frequently and this could stress OS
525 allocator when varray is used only. */
527 /* Start work with vla. */
528 #define VLA_PTR_CREATE(vla, allocated_length, name) \
531 vla_ptr_t *vla_ptr = &(vla); \
533 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
534 vla_ptr->length = 0; \
538 /* Finish work with the vla. */
539 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
541 /* Return start address of the vla. */
542 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
544 /* Address of the last element of the vla. Do not use side effects in
545 the macro argument. */
546 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
548 /* Nullify the vla. */
549 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
551 /* Shorten the vla on given number bytes. */
552 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
554 /* Expand the vla on N elements. The values of new elements are
556 #define VLA_PTR_EXPAND(vla, n) \
558 vla_ptr_t *expand_vla_ptr = &(vla); \
559 size_t new_length = (n) + expand_vla_ptr->length; \
561 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
562 VARRAY_GROW (expand_vla_ptr->varray, \
563 (new_length - expand_vla_ptr->length < 128 \
564 ? expand_vla_ptr->length + 128 : new_length)); \
565 expand_vla_ptr->length = new_length; \
568 /* Add element to the end of the vla. */
569 #define VLA_PTR_ADD(vla, ptr) \
571 vla_ptr_t *vla_ptr = &(vla); \
573 VLA_PTR_EXPAND (*vla_ptr, 1); \
574 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
577 /* Length of the vla in elements. */
578 #define VLA_PTR_LENGTH(vla) ((vla).length)
580 /* N-th element of the vla. */
581 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
584 /* The following macros are analogous to the previous ones but for
585 VLAs of HOST WIDE INTs. */
587 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
589 vla_hwint_t *vla_ptr = &(vla); \
591 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
592 vla_ptr->length = 0; \
595 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
597 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
599 /* Do not use side effects in the macro argument. */
600 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
603 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
605 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
607 #define VLA_HWINT_EXPAND(vla, n) \
609 vla_hwint_t *expand_vla_ptr = &(vla); \
610 size_t new_length = (n) + expand_vla_ptr->length; \
612 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
613 VARRAY_GROW (expand_vla_ptr->varray, \
614 (new_length - expand_vla_ptr->length < 128 \
615 ? expand_vla_ptr->length + 128 : new_length)); \
616 expand_vla_ptr->length = new_length; \
619 #define VLA_HWINT_ADD(vla, ptr) \
621 vla_hwint_t *vla_ptr = &(vla); \
623 VLA_HWINT_EXPAND (*vla_ptr, 1); \
624 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
627 #define VLA_HWINT_LENGTH(vla) ((vla).length)
629 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
633 /* Options with the following names can be set up in automata_option
634 construction. Because the strings occur more one time we use the
637 #define NO_MINIMIZATION_OPTION "-no-minimization"
639 #define W_OPTION "-w"
641 #define NDFA_OPTION "-ndfa"
643 /* The following flags are set up by function `initiate_automaton_gen'. */
645 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
646 static int ndfa_flag;
648 /* Do not make minimization of DFA (`-no-minimization'). */
649 static int no_minimization_flag;
651 /* Value of this variable is number of automata being generated. The
652 actual number of automata may be less this value if there is not
653 sufficient number of units. This value is defined by argument of
654 option `-split' or by constructions automaton if the value is zero
655 (it is default value of the argument). */
656 static int split_argument;
658 /* Flag of output time statistics (`-time'). */
659 static int time_flag;
661 /* Flag of creation of description file which contains description of
662 result automaton and statistics information (`-v'). */
665 /* Flag of generating warning instead of error for non-critical errors
670 /* Output file for pipeline hazard recognizer (PHR) being generated.
671 The value is NULL if the file is not defined. */
672 static FILE *output_file;
674 /* Description file of PHR. The value is NULL if the file is not
676 static FILE *output_description_file;
678 /* PHR description file name. */
679 static char *output_description_file_name;
681 /* Value of the following variable is node representing description
682 being processed. This is start point of IR. */
683 static struct description *description;
687 /* This page contains description of IR structure (nodes). */
701 /* This describes define_cpu_unit and define_query_cpu_unit (see file
706 /* NULL if the automaton name is absent. */
707 char *automaton_name;
708 /* If the following value is not zero, the cpu unit reservation is
709 described in define_query_cpu_unit. */
712 /* The following fields are defined by checker. */
714 /* The following field value is nonzero if the unit is used in an
717 /* The following field value is order number (0, 1, ...) of given
720 /* The following field value is corresponding declaration of
721 automaton which was given in description. If the field value is
722 NULL then automaton in the unit declaration was absent. */
723 struct automaton_decl *automaton_decl;
724 /* The following field value is maximal cycle number (1, ...) on
725 which given unit occurs in insns. Zero value means that given
726 unit is not used in insns. */
727 int max_occ_cycle_num;
728 /* The following list contains units which conflict with given
730 unit_set_el_t excl_list;
731 /* The following list contains units which are required to
732 reservation of given unit. */
733 unit_set_el_t presence_list;
734 /* The following list contains units which should be not present in
735 reservation for given unit. */
736 unit_set_el_t absence_list;
737 /* The following is used only when `query_p' has nonzero value.
738 This is query number for the unit. */
741 /* The following fields are defined by automaton generator. */
743 /* The following field value is number of the automaton to which
744 given unit belongs. */
745 int corresponding_automaton_num;
748 /* This describes define_bypass (see file rtl.def). */
754 char *bypass_guard_name;
756 /* The following fields are defined by checker. */
758 /* output and input insns of given bypass. */
759 struct insn_reserv_decl *out_insn_reserv;
760 struct insn_reserv_decl *in_insn_reserv;
761 /* The next bypass for given output insn. */
762 struct bypass_decl *next;
765 /* This describes define_automaton (see file rtl.def). */
766 struct automaton_decl
770 /* The following fields are defined by automaton generator. */
772 /* The following field value is nonzero if the automaton is used in
773 an regexp definition. */
774 char automaton_is_used;
776 /* The following fields are defined by checker. */
778 /* The following field value is the corresponding automaton. This
779 field is not NULL only if the automaton is present in unit
780 declarations and the automatic partition on automata is not
782 automaton_t corresponding_automaton;
785 /* This describes unit relations: exclusion_set, presence_set, or
786 absence_set (see file rtl.def). */
790 int first_list_length;
794 /* This describes define_reservation (see file rtl.def). */
800 /* The following fields are defined by checker. */
802 /* The following field value is nonzero if the unit is used in an
805 /* The following field is used to check up cycle in expression
810 /* This describes define_insn_reservartion (see file rtl.def). */
811 struct insn_reserv_decl
818 /* The following fields are defined by checker. */
820 /* The following field value is order number (0, 1, ...) of given
823 /* The following field value is list of bypasses in which given insn
825 struct bypass_decl *bypass_list;
827 /* The following fields are defined by automaton generator. */
829 /* The following field is the insn regexp transformed that
830 the regexp has not optional regexp, repetition regexp, and an
831 reservation name (i.e. reservation identifiers are changed by the
832 corresponding regexp) and all alternations are the topest level
833 of the regexp. The value can be NULL only if it is special
834 insn `cycle advancing'. */
835 regexp_t transformed_regexp;
836 /* The following field value is list of arcs marked given
837 insn. The field is used in transfromation NDFA -> DFA. */
838 arc_t arcs_marked_by_insn;
839 /* The two following fields are used during minimization of a finite state
841 /* The field value is number of equivalence class of state into
842 which arc marked by given insn enters from a state (fixed during
843 an automaton minimization). */
845 /* The field value is state_alts of arc leaving a state (fixed
846 during an automaton minimization) and marked by given insn
849 /* The following member value is the list to automata which can be
850 changed by the insn issue. */
851 automata_list_el_t important_automata_list;
852 /* The following member is used to process insn once for output. */
856 /* This contains a declaration mentioned above. */
859 /* What node in the union? */
864 struct unit_decl unit;
865 struct bypass_decl bypass;
866 struct automaton_decl automaton;
867 struct unit_rel_decl excl;
868 struct unit_rel_decl presence;
869 struct unit_rel_decl absence;
870 struct reserv_decl reserv;
871 struct insn_reserv_decl insn_reserv;
875 /* The following structures represent parsed reservation strings. */
887 /* Cpu unit in reservation. */
891 struct unit_decl *unit_decl;
894 /* Define_reservation in a reservation. */
898 struct reserv_decl *reserv_decl;
901 /* Absence of reservation (represented by string `nothing'). */
902 struct nothing_regexp
904 /* This used to be empty but ISO C doesn't allow that. */
908 /* Representation of reservations separated by ',' (see file
910 struct sequence_regexp
913 regexp_t regexps [1];
916 /* Representation of construction `repeat' (see file rtl.def). */
923 /* Representation of reservations separated by '+' (see file
928 regexp_t regexps [1];
931 /* Representation of reservations separated by '|' (see file
936 regexp_t regexps [1];
939 /* Representation of a reservation string. */
942 /* What node in the union? */
943 enum regexp_mode mode;
947 struct unit_regexp unit;
948 struct reserv_regexp reserv;
949 struct nothing_regexp nothing;
950 struct sequence_regexp sequence;
951 struct repeat_regexp repeat;
952 struct allof_regexp allof;
953 struct oneof_regexp oneof;
957 /* Reperesents description of pipeline hazard description based on
963 /* The following fields are defined by checker. */
965 /* The following fields values are correspondingly number of all
966 units, query units, and insns in the description. */
970 /* The following field value is max length (in cycles) of
971 reservations of insns. The field value is defined only for
973 int max_insn_reserv_cycles;
975 /* The following fields are defined by automaton generator. */
977 /* The following field value is the first automaton. */
978 automaton_t first_automaton;
980 /* The following field is created by pipeline hazard parser and
981 contains all declarations. We allocate additional entry for
982 special insn "cycle advancing" which is added by the automaton
989 /* The following nodes are created in automaton checker. */
991 /* The following nodes represent exclusion, presence, absence set for
992 cpu units. Each element are accessed through only one excl_list,
993 presence_list, absence_list. */
996 struct unit_decl *unit_decl;
997 unit_set_el_t next_unit_set_el;
1002 /* The following nodes are created in automaton generator. */
1004 /* The following node type describes state automaton. The state may
1005 be deterministic or non-deterministic. Non-deterministic state has
1006 several component states which represent alternative cpu units
1007 reservations. The state also is used for describing a
1008 deterministic reservation of automaton insn. */
1011 /* The following member value is nonzero if there is a transition by
1014 /* The following field is list of processor unit reservations on
1016 reserv_sets_t reservs;
1017 /* The following field is unique number of given state between other
1020 /* The following field value is automaton to which given state
1022 automaton_t automaton;
1023 /* The following field value is the first arc output from given
1025 arc_t first_out_arc;
1026 /* The following field is used to form NDFA. */
1027 char it_was_placed_in_stack_for_NDFA_forming;
1028 /* The following field is used to form DFA. */
1029 char it_was_placed_in_stack_for_DFA_forming;
1030 /* The following field is used to transform NDFA to DFA. The field
1031 value is not NULL if the state is a compound state. In this case
1032 the value of field `unit_sets_list' is NULL. All states in the
1033 list are in the hash table. The list is formed through field
1034 `next_sorted_alt_state'. */
1035 alt_state_t component_states;
1036 /* The following field is used for passing graph of states. */
1038 /* The list of states belonging to one equivalence class is formed
1039 with the aid of the following field. */
1040 state_t next_equiv_class_state;
1041 /* The two following fields are used during minimization of a finite
1043 int equiv_class_num_1, equiv_class_num_2;
1044 /* The following field is used during minimization of a finite state
1045 automaton. The field value is state corresponding to equivalence
1046 class to which given state belongs. */
1047 state_t equiv_class_state;
1048 /* The following field value is the order number of given state.
1049 The states in final DFA is enumerated with the aid of the
1051 int order_state_num;
1052 /* This member is used for passing states for searching minimal
1055 /* The following member is used to evaluate min issue delay of insn
1057 int min_insn_issue_delay;
1058 /* The following member is used to evaluate max issue rate of the
1059 processor. The value of the member is maximal length of the path
1060 from given state no containing arcs marked by special insn `cycle
1062 int longest_path_length;
1065 /* The following macro is an initial value of member
1066 `longest_path_length' of a state. */
1067 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1069 /* Automaton arc. */
1072 /* The following field refers for the state into which given arc
1075 /* The following field describes that the insn issue (with cycle
1076 advancing for special insn `cycle advancing' and without cycle
1077 advancing for others) makes transition from given state to
1078 another given state. */
1080 /* The following field value is the next arc output from the same
1083 /* List of arcs marked given insn is formed with the following
1084 field. The field is used in transfromation NDFA -> DFA. */
1085 arc_t next_arc_marked_by_insn;
1086 /* The following field is defined if NDFA_FLAG is zero. The member
1087 value is number of alternative reservations which can be used for
1088 transition for given state by given insn. */
1092 /* The following node type describes a deterministic alternative in
1093 non-deterministic state which characterizes cpu unit reservations
1094 of automaton insn or which is part of NDFA. */
1097 /* The following field is a determinist state which characterizes
1098 unit reservations of the instruction. */
1100 /* The following field refers to the next state which characterizes
1101 unit reservations of the instruction. */
1102 alt_state_t next_alt_state;
1103 /* The following field refers to the next state in sorted list. */
1104 alt_state_t next_sorted_alt_state;
1107 /* The following node type describes insn of automaton. They are
1108 labels of FA arcs. */
1111 /* The following field value is the corresponding insn declaration
1113 struct insn_reserv_decl *insn_reserv_decl;
1114 /* The following field value is the next insn declaration for an
1117 /* The following field is states which characterize automaton unit
1118 reservations of the instruction. The value can be NULL only if it
1119 is special insn `cycle advancing'. */
1120 alt_state_t alt_states;
1121 /* The following field is sorted list of states which characterize
1122 automaton unit reservations of the instruction. The value can be
1123 NULL only if it is special insn `cycle advancing'. */
1124 alt_state_t sorted_alt_states;
1125 /* The following field refers the next automaton insn with
1126 the same reservations. */
1127 ainsn_t next_same_reservs_insn;
1128 /* The following field is flag of the first automaton insn with the
1129 same reservations in the declaration list. Only arcs marked such
1130 insn is present in the automaton. This significantly decreases
1131 memory requirements especially when several automata are
1133 char first_insn_with_same_reservs;
1134 /* The following member has nonzero value if there is arc from state of
1135 the automaton marked by the ainsn. */
1137 /* Cyclic list of insns of a equivalence class is formed with the
1138 aid of the following field. */
1139 ainsn_t next_equiv_class_insn;
1140 /* The following field value is nonzero if the insn declaration is
1141 the first insn declaration with given equivalence number. */
1142 char first_ainsn_with_given_equialence_num;
1143 /* The following field is number of class of equivalence of insns.
1144 It is necessary because many insns may be equivalent with the
1145 point of view of pipeline hazards. */
1146 int insn_equiv_class_num;
1147 /* The following member value is TRUE if there is an arc in the
1148 automaton marked by the insn into another state. In other
1149 words, the insn can change the state of the automaton. */
1153 /* The folowing describes an automaton for PHR. */
1156 /* The following field value is the list of insn declarations for
1159 /* The following field value is the corresponding automaton
1160 declaration. This field is not NULL only if the automatic
1161 partition on automata is not used. */
1162 struct automaton_decl *corresponding_automaton_decl;
1163 /* The following field value is the next automaton. */
1164 automaton_t next_automaton;
1165 /* The following field is start state of FA. There are not unit
1166 reservations in the state. */
1167 state_t start_state;
1168 /* The following field value is number of equivalence classes of
1169 insns (see field `insn_equiv_class_num' in
1170 `insn_reserv_decl'). */
1171 int insn_equiv_classes_num;
1172 /* The following field value is number of states of final DFA. */
1173 int achieved_states_num;
1174 /* The following field value is the order number (0, 1, ...) of
1176 int automaton_order_num;
1177 /* The following fields contain statistics information about
1178 building automaton. */
1179 int NDFA_states_num, DFA_states_num;
1180 /* The following field value is defined only if minimization of DFA
1182 int minimal_DFA_states_num;
1183 int NDFA_arcs_num, DFA_arcs_num;
1184 /* The following field value is defined only if minimization of DFA
1186 int minimal_DFA_arcs_num;
1187 /* The following two members refer for two table state x ainsn ->
1189 state_ainsn_table_t trans_table;
1190 state_ainsn_table_t state_alts_table;
1191 /* The following member value is maximal value of min issue delay
1192 for insns of the automaton. */
1194 /* Usually min issue delay is small and we can place several (2, 4,
1195 8) elements in one vector element. So the compression factor can
1196 be 1 (no compression), 2, 4, 8. */
1197 int min_issue_delay_table_compression_factor;
1200 /* The following is the element of the list of automata. */
1201 struct automata_list_el
1203 /* The automaton itself. */
1204 automaton_t automaton;
1205 /* The next automata set element. */
1206 automata_list_el_t next_automata_list_el;
1209 /* The following structure describes a table state X ainsn -> int(>= 0). */
1210 struct state_ainsn_table
1212 /* Automaton to which given table belongs. */
1213 automaton_t automaton;
1214 /* The following tree vectors for comb vector implementation of the
1216 vla_hwint_t comb_vect;
1217 vla_hwint_t check_vect;
1218 vla_hwint_t base_vect;
1219 /* This is simple implementation of the table. */
1220 vla_hwint_t full_vect;
1221 /* Minimal and maximal values of the previous vectors. */
1222 int min_comb_vect_el_value, max_comb_vect_el_value;
1223 int min_base_vect_el_value, max_base_vect_el_value;
1226 /* Create IR structure (node). */
1233 obstack_blank (&irp, size);
1234 result = obstack_base (&irp);
1235 obstack_finish (&irp);
1236 /* Default values of members are NULL and zero. */
1237 memset (result, 0, size);
1241 /* Copy IR structure (node). */
1243 copy_node (from, size)
1248 result = create_node (size);
1249 memcpy (result, from, size);
1253 /* The function checks that NAME does not contain quotes (`"'). */
1255 check_name (name, pos)
1257 pos_t pos ATTRIBUTE_UNUSED;
1261 for (str = name; *str != '\0'; str++)
1263 error ("Name `%s' contains quotes", name);
1267 /* Pointers top all declartions during IR generation are stored in the
1269 static vla_ptr_t decls;
1271 /* Given a pointer to a (char *) and a separator, return a alloc'ed
1272 string containing the next separated element, taking parentheses
1273 into account if PAR_FLAG has nonzero value. Advance the pointer to
1274 after the string scanned, or the end-of-string. Return NULL if at
1277 next_sep_el (pstr, sep, par_flag)
1287 /* Remove leading whitespaces. */
1288 while (isspace ((int) **pstr))
1295 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1297 if (par_flag && *p == '(')
1299 else if (par_flag && *p == ')')
1301 else if (pars_num == 0 && *p == sep)
1303 if (pars_num == 0 && isspace ((int) *p))
1307 for (; n_spaces != 0; n_spaces--)
1308 obstack_1grow (&irp, p [-n_spaces]);
1309 obstack_1grow (&irp, *p);
1312 obstack_1grow (&irp, '\0');
1313 out_str = obstack_base (&irp);
1314 obstack_finish (&irp);
1323 /* Given a string and a separator, return the number of separated
1324 elements in it, taking parentheses into account if PAR_FLAG has
1325 nonzero value. Return 0 for the null string, -1 if parantheses is
1328 n_sep_els (s, sep, par_flag)
1339 for (pars_num = 0, n = 1; *s; s++)
1340 if (par_flag && *s == '(')
1342 else if (par_flag && *s == ')')
1344 else if (pars_num == 0 && *s == sep)
1347 return (pars_num != 0 ? -1 : n);
1350 /* Given a string and a separator, return vector of strings which are
1351 elements in the string and number of elements through els_num.
1352 Take parentheses into account if PAR_FLAG has nonzero value.
1353 Return 0 for the null string, -1 if parantheses are not balanced. */
1355 get_str_vect (str, els_num, sep, par_flag)
1365 *els_num = n_sep_els (str, sep, par_flag);
1368 obstack_blank (&irp, sizeof (char *) * (*els_num));
1369 vect = (char **) obstack_base (&irp);
1370 obstack_finish (&irp);
1372 for (i = 0; i < *els_num; i++)
1373 vect [i] = next_sep_el (pstr, sep, par_flag);
1374 if (next_sep_el (pstr, sep, par_flag) != NULL)
1379 /* Process a DEFINE_CPU_UNIT.
1381 This gives information about a unit contained in CPU. We fill a
1382 struct unit_decl with information used later by `expand_automata'. */
1388 char **str_cpu_units;
1392 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1393 if (str_cpu_units == NULL)
1394 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1395 for (i = 0; i < vect_length; i++)
1397 decl = create_node (sizeof (struct decl));
1398 decl->mode = dm_unit;
1400 decl->decl.unit.name = check_name (str_cpu_units [i], decl->pos);
1401 decl->decl.unit.automaton_name = (char *) XSTR (def, 1);
1402 decl->decl.unit.query_p = 0;
1403 VLA_PTR_ADD (decls, decl);
1408 /* Process a DEFINE_QUERY_CPU_UNIT.
1410 This gives information about a unit contained in CPU. We fill a
1411 struct unit_decl with information used later by `expand_automata'. */
1413 gen_query_cpu_unit (def)
1417 char **str_cpu_units;
1421 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1422 if (str_cpu_units == NULL)
1423 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1424 for (i = 0; i < vect_length; i++)
1426 decl = create_node (sizeof (struct decl));
1427 decl->mode = dm_unit;
1429 decl->decl.unit.name = check_name (str_cpu_units [i], decl->pos);
1430 decl->decl.unit.automaton_name = (char *) XSTR (def, 1);
1431 decl->decl.unit.query_p = 1;
1432 VLA_PTR_ADD (decls, decl);
1437 /* Process a DEFINE_BYPASS.
1439 This gives information about a unit contained in the CPU. We fill
1440 in a struct bypass_decl with information used later by
1441 `expand_automata'. */
1453 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', 0);
1454 if (out_insns == NULL)
1455 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1456 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', 0);
1457 if (in_insns == NULL)
1458 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1459 for (i = 0; i < out_length; i++)
1460 for (j = 0; j < in_length; j++)
1462 decl = create_node (sizeof (struct decl));
1463 decl->mode = dm_bypass;
1465 decl->decl.bypass.latency = XINT (def, 0);
1466 decl->decl.bypass.out_insn_name = out_insns [i];
1467 decl->decl.bypass.in_insn_name = in_insns [j];
1468 decl->decl.bypass.bypass_guard_name = (char *) XSTR (def, 3);
1469 VLA_PTR_ADD (decls, decl);
1474 /* Process a EXCLUSION_SET.
1476 This gives information about a cpu unit conflicts. We fill a
1477 struct unit_rel_decl (excl) with information used later by
1478 `expand_automata'. */
1484 char **first_str_cpu_units;
1485 char **second_str_cpu_units;
1486 int first_vect_length;
1491 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1492 if (first_str_cpu_units == NULL)
1493 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1494 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1496 if (second_str_cpu_units == NULL)
1497 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1498 length += first_vect_length;
1499 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1500 decl->mode = dm_excl;
1502 decl->decl.excl.names_num = length;
1503 decl->decl.excl.first_list_length = first_vect_length;
1504 for (i = 0; i < length; i++)
1505 if (i < first_vect_length)
1506 decl->decl.excl.names [i] = first_str_cpu_units [i];
1508 decl->decl.excl.names [i] = second_str_cpu_units [i - first_vect_length];
1509 VLA_PTR_ADD (decls, decl);
1513 /* Process a PRESENCE_SET.
1515 This gives information about a cpu unit reservation requirements.
1516 We fill a struct unit_rel_decl (presence) with information used
1517 later by `expand_automata'. */
1519 gen_presence_set (def)
1523 char **first_str_cpu_units;
1524 char **second_str_cpu_units;
1525 int first_vect_length;
1530 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1531 if (first_str_cpu_units == NULL)
1532 fatal ("invalid first string `%s' in presence_set", XSTR (def, 0));
1533 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1535 if (second_str_cpu_units == NULL)
1536 fatal ("invalid second string `%s' in presence_set", XSTR (def, 1));
1537 length += first_vect_length;
1538 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1539 decl->mode = dm_presence;
1541 decl->decl.presence.names_num = length;
1542 decl->decl.presence.first_list_length = first_vect_length;
1543 for (i = 0; i < length; i++)
1544 if (i < first_vect_length)
1545 decl->decl.presence.names [i] = first_str_cpu_units [i];
1547 decl->decl.presence.names [i]
1548 = second_str_cpu_units [i - first_vect_length];
1549 VLA_PTR_ADD (decls, decl);
1553 /* Process a ABSENCE_SET.
1555 This gives information about a cpu unit reservation requirements.
1556 We fill a struct unit_rel_decl (absence) with information used
1557 later by `expand_automata'. */
1559 gen_absence_set (def)
1563 char **first_str_cpu_units;
1564 char **second_str_cpu_units;
1565 int first_vect_length;
1570 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
1571 if (first_str_cpu_units == NULL)
1572 fatal ("invalid first string `%s' in absence_set", XSTR (def, 0));
1573 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1575 if (second_str_cpu_units == NULL)
1576 fatal ("invalid second string `%s' in absence_set", XSTR (def, 1));
1577 length += first_vect_length;
1578 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1579 decl->mode = dm_absence;
1581 decl->decl.absence.names_num = length;
1582 decl->decl.absence.first_list_length = first_vect_length;
1583 for (i = 0; i < length; i++)
1584 if (i < first_vect_length)
1585 decl->decl.absence.names [i] = first_str_cpu_units [i];
1587 decl->decl.absence.names [i]
1588 = second_str_cpu_units [i - first_vect_length];
1589 VLA_PTR_ADD (decls, decl);
1593 /* Process a DEFINE_AUTOMATON.
1595 This gives information about a finite state automaton used for
1596 recognizing pipeline hazards. We fill a struct automaton_decl
1597 with information used later by `expand_automata'. */
1603 char **str_automata;
1607 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
1608 if (str_automata == NULL)
1609 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1610 for (i = 0; i < vect_length; i++)
1612 decl = create_node (sizeof (struct decl));
1613 decl->mode = dm_automaton;
1615 decl->decl.automaton.name = check_name (str_automata [i], decl->pos);
1616 VLA_PTR_ADD (decls, decl);
1621 /* Process a AUTOMATA_OPTION.
1623 This gives information how to generate finite state automaton used
1624 for recognizing pipeline hazards. */
1626 gen_automata_option (def)
1629 if (strcmp ((char *) XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1630 no_minimization_flag = 1;
1631 else if (strcmp ((char *) XSTR (def, 0), W_OPTION + 1) == 0)
1633 else if (strcmp ((char *) XSTR (def, 0), NDFA_OPTION + 1) == 0)
1636 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1639 /* Name in reservation to denote absence reservation. */
1640 #define NOTHING_NAME "nothing"
1642 /* The following string contains original reservation string being
1644 static char *reserv_str;
1646 /* Parse an element in STR. */
1657 if (str [len - 1] != ')')
1658 fatal ("garbage after ) in reservation `%s'", reserv_str);
1659 str [len - 1] = '\0';
1660 regexp = gen_regexp_sequence (str + 1);
1662 else if (strcmp (str, NOTHING_NAME) == 0)
1664 regexp = create_node (sizeof (struct decl));
1665 regexp->mode = rm_nothing;
1669 regexp = create_node (sizeof (struct decl));
1670 regexp->mode = rm_unit;
1671 regexp->regexp.unit.name = str;
1676 /* Parse construction `repeat' in STR. */
1678 gen_regexp_repeat (str)
1687 repeat_vect = get_str_vect (str, &els_num, '*', 1);
1688 if (repeat_vect == NULL)
1689 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1692 regexp = gen_regexp_el (repeat_vect [0]);
1693 for (i = 1; i < els_num; i++)
1695 repeat = create_node (sizeof (struct regexp));
1696 repeat->mode = rm_repeat;
1697 repeat->regexp.repeat.regexp = regexp;
1698 repeat->regexp.repeat.repeat_num = atoi (repeat_vect [i]);
1699 if (repeat->regexp.repeat.repeat_num <= 1)
1700 fatal ("repetition `%s' <= 1 in reservation `%s'",
1707 return gen_regexp_el (str);
1710 /* Parse reservation STR which possibly contains separator '+'. */
1712 gen_regexp_allof (str)
1720 allof_vect = get_str_vect (str, &els_num, '+', 1);
1721 if (allof_vect == NULL)
1722 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1725 allof = create_node (sizeof (struct regexp)
1726 + sizeof (regexp_t) * (els_num - 1));
1727 allof->mode = rm_allof;
1728 allof->regexp.allof.regexps_num = els_num;
1729 for (i = 0; i < els_num; i++)
1730 allof->regexp.allof.regexps [i] = gen_regexp_repeat (allof_vect [i]);
1734 return gen_regexp_repeat (str);
1737 /* Parse reservation STR which possibly contains separator '|'. */
1739 gen_regexp_oneof (str)
1747 oneof_vect = get_str_vect (str, &els_num, '|', 1);
1748 if (oneof_vect == NULL)
1749 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1752 oneof = create_node (sizeof (struct regexp)
1753 + sizeof (regexp_t) * (els_num - 1));
1754 oneof->mode = rm_oneof;
1755 oneof->regexp.oneof.regexps_num = els_num;
1756 for (i = 0; i < els_num; i++)
1757 oneof->regexp.oneof.regexps [i] = gen_regexp_allof (oneof_vect [i]);
1761 return gen_regexp_allof (str);
1764 /* Parse reservation STR which possibly contains separator ','. */
1766 gen_regexp_sequence (str)
1770 char **sequence_vect;
1774 sequence_vect = get_str_vect (str, &els_num, ',', 1);
1777 sequence = create_node (sizeof (struct regexp)
1778 + sizeof (regexp_t) * (els_num - 1));
1779 sequence->mode = rm_sequence;
1780 sequence->regexp.sequence.regexps_num = els_num;
1781 for (i = 0; i < els_num; i++)
1782 sequence->regexp.sequence.regexps [i]
1783 = gen_regexp_oneof (sequence_vect [i]);
1787 return gen_regexp_oneof (str);
1790 /* Parse construction reservation STR. */
1796 return gen_regexp_sequence (str);;
1799 /* Process a DEFINE_RESERVATION.
1801 This gives information about a reservation of cpu units. We fill
1802 in a struct reserv_decl with information used later by
1803 `expand_automata'. */
1810 decl = create_node (sizeof (struct decl));
1811 decl->mode = dm_reserv;
1813 decl->decl.reserv.name = check_name ((char *) XSTR (def, 0), decl->pos);
1814 decl->decl.reserv.regexp = gen_regexp ((char *) XSTR (def, 1));
1815 VLA_PTR_ADD (decls, decl);
1819 /* Process a DEFINE_INSN_RESERVATION.
1821 This gives information about the reservation of cpu units by an
1822 insn. We fill a struct insn_reserv_decl with information used
1823 later by `expand_automata'. */
1825 gen_insn_reserv (def)
1830 decl = create_node (sizeof (struct decl));
1831 decl->mode = dm_insn_reserv;
1833 decl->decl.insn_reserv.name = check_name ((char *) XSTR (def, 0), decl->pos);
1834 decl->decl.insn_reserv.default_latency = XINT (def, 1);
1835 decl->decl.insn_reserv.condexp = XEXP (def, 2);
1836 decl->decl.insn_reserv.regexp = gen_regexp ((char *) XSTR (def, 3));
1837 VLA_PTR_ADD (decls, decl);
1843 /* The function evaluates hash value (0..UINT_MAX) of string. */
1845 string_hash (string)
1850 for (result = i = 0;*string++ != '\0'; i++)
1851 result += ((unsigned char) *string << (i % CHAR_BIT));
1857 /* This page contains abstract data `table of automaton declarations'.
1858 Elements of the table is nodes representing automaton declarations.
1859 Key of the table elements is name of given automaton. Rememeber
1860 that automaton names have own space. */
1862 /* The function evaluates hash value of a automaton declaration. The
1863 function is used by abstract data `hashtab'. The function returns
1864 hash value (0..UINT_MAX) of given automaton declaration. */
1866 automaton_decl_hash (automaton_decl)
1867 const void *automaton_decl;
1869 const decl_t decl = (decl_t) automaton_decl;
1871 if (decl->mode == dm_automaton && decl->decl.automaton.name == NULL)
1873 return string_hash (decl->decl.automaton.name);
1876 /* The function tests automaton declarations on equality of their
1877 keys. The function is used by abstract data `hashtab'. The
1878 function returns 1 if the declarations have the same key, 0
1881 automaton_decl_eq_p (automaton_decl_1, automaton_decl_2)
1882 const void* automaton_decl_1;
1883 const void* automaton_decl_2;
1885 const decl_t decl1 = (decl_t) automaton_decl_1;
1886 const decl_t decl2 = (decl_t) automaton_decl_2;
1888 if (decl1->mode != dm_automaton || decl1->decl.automaton.name == NULL
1889 || decl2->mode != dm_automaton || decl2->decl.automaton.name == NULL)
1891 return strcmp (decl1->decl.automaton.name, decl2->decl.automaton.name) == 0;
1894 /* The automaton declaration table itself is represented by the
1895 following variable. */
1896 static htab_t automaton_decl_table;
1898 /* The function inserts automaton declaration into the table. The
1899 function does nothing if an automaton declaration with the same key
1900 exists already in the table. The function returns automaton
1901 declaration node in the table with the same key as given automaton
1902 declaration node. */
1904 insert_automaton_decl (automaton_decl)
1905 decl_t automaton_decl;
1909 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
1910 if (*entry_ptr == NULL)
1911 *entry_ptr = (void *) automaton_decl;
1912 return (decl_t) *entry_ptr;
1915 /* The following variable value is node representing automaton
1916 declaration. The node used for searching automaton declaration
1918 static struct decl work_automaton_decl;
1920 /* The function searches for automaton declaration in the table with
1921 the same key as node representing name of the automaton
1922 declaration. The function returns node found in the table, NULL if
1923 such node does not exist in the table. */
1925 find_automaton_decl (name)
1930 work_automaton_decl.decl.automaton.name = name;
1931 entry = htab_find (automaton_decl_table, &work_automaton_decl);
1932 return (decl_t) entry;
1935 /* The function creates empty automaton declaration table and node
1936 representing automaton declaration and used for searching automaton
1937 declaration with given name. The function must be called only once
1938 before any work with the automaton declaration table. */
1940 initiate_automaton_decl_table ()
1942 work_automaton_decl.mode = dm_automaton;
1943 automaton_decl_table = htab_create (10, automaton_decl_hash,
1944 automaton_decl_eq_p, (htab_del) 0);
1947 /* The function deletes the automaton declaration table. Only call of
1948 function `initiate_automaton_decl_table' is possible immediately
1949 after this function call. */
1951 finish_automaton_decl_table ()
1953 htab_delete (automaton_decl_table);
1958 /* This page contains abstract data `table of insn declarations'.
1959 Elements of the table is nodes representing insn declarations. Key
1960 of the table elements is name of given insn (in corresponding
1961 define_insn_reservation). Rememeber that insn names have own
1964 /* The function evaluates hash value of a insn declaration. The
1965 function is used by abstract data `hashtab'. The function returns
1966 hash value (0..UINT_MAX) of given insn declaration. */
1968 insn_decl_hash (insn_decl)
1969 const void *insn_decl;
1971 const decl_t decl = (decl_t) insn_decl;
1973 if (decl->mode != dm_insn_reserv || decl->decl.insn_reserv.name == NULL)
1975 return string_hash (decl->decl.insn_reserv.name);
1978 /* The function tests insn declarations on equality of their keys.
1979 The function is used by abstract data `hashtab'. The function
1980 returns 1 if declarations have the same key, 0 otherwise. */
1982 insn_decl_eq_p (insn_decl_1, insn_decl_2)
1983 const void *insn_decl_1;
1984 const void *insn_decl_2;
1986 const decl_t decl1 = (decl_t) insn_decl_1;
1987 const decl_t decl2 = (decl_t) insn_decl_2;
1989 if (decl1->mode != dm_insn_reserv || decl1->decl.insn_reserv.name == NULL
1990 || decl2->mode != dm_insn_reserv || decl2->decl.insn_reserv.name == NULL)
1992 return strcmp (decl1->decl.insn_reserv.name,
1993 decl2->decl.insn_reserv.name) == 0;
1996 /* The insn declaration table itself is represented by the following
1997 variable. The table does not contain insn reservation
1999 static htab_t insn_decl_table;
2001 /* The function inserts insn declaration into the table. The function
2002 does nothing if an insn declaration with the same key exists
2003 already in the table. The function returns insn declaration node
2004 in the table with the same key as given insn declaration node. */
2006 insert_insn_decl (insn_decl)
2011 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2012 if (*entry_ptr == NULL)
2013 *entry_ptr = (void *) insn_decl;
2014 return (decl_t) *entry_ptr;
2017 /* The following variable value is node representing insn reservation
2018 declaration. The node used for searching insn reservation
2019 declaration with given name. */
2020 static struct decl work_insn_decl;
2022 /* The function searches for insn reservation declaration in the table
2023 with the same key as node representing name of the insn reservation
2024 declaration. The function returns node found in the table, NULL if
2025 such node does not exist in the table. */
2027 find_insn_decl (name)
2032 work_insn_decl.decl.insn_reserv.name = name;
2033 entry = htab_find (insn_decl_table, &work_insn_decl);
2034 return (decl_t) entry;
2037 /* The function creates empty insn declaration table and node
2038 representing insn declaration and used for searching insn
2039 declaration with given name. The function must be called only once
2040 before any work with the insn declaration table. */
2042 initiate_insn_decl_table ()
2044 work_insn_decl.mode = dm_insn_reserv;
2045 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2049 /* The function deletes the insn declaration table. Only call of
2050 function `initiate_insn_decl_table' is possible immediately after
2051 this function call. */
2053 finish_insn_decl_table ()
2055 htab_delete (insn_decl_table);
2060 /* This page contains abstract data `table of declarations'. Elements
2061 of the table is nodes representing declarations (of units and
2062 reservations). Key of the table elements is names of given
2065 /* The function evaluates hash value of a declaration. The function
2066 is used by abstract data `hashtab'. The function returns hash
2067 value (0..UINT_MAX) of given declaration. */
2072 const decl_t d = (const decl_t) decl;
2074 if ((d->mode != dm_unit || d->decl.unit.name == NULL)
2075 && (d->mode != dm_reserv || d->decl.reserv.name == NULL))
2077 return string_hash (d->mode == dm_unit
2078 ? d->decl.unit.name : d->decl.reserv.name);
2081 /* The function tests declarations on equality of their keys. The
2082 function is used by abstract data `hashtab'. The function
2083 returns 1 if the declarations have the same key, 0 otherwise. */
2085 decl_eq_p (decl_1, decl_2)
2089 const decl_t d1 = (const decl_t) decl_1;
2090 const decl_t d2 = (const decl_t) decl_2;
2092 if (((d1->mode != dm_unit || d1->decl.unit.name == NULL)
2093 && (d1->mode != dm_reserv || d1->decl.reserv.name == NULL))
2094 || ((d2->mode != dm_unit || d2->decl.unit.name == NULL)
2095 && (d2->mode != dm_reserv || d2->decl.reserv.name == NULL)))
2097 return strcmp ((d1->mode == dm_unit
2098 ? d1->decl.unit.name : d1->decl.reserv.name),
2099 (d2->mode == dm_unit
2100 ? d2->decl.unit.name : d2->decl.reserv.name)) == 0;
2103 /* The declaration table itself is represented by the following
2105 static htab_t decl_table;
2107 /* The function inserts declaration into the table. The function does
2108 nothing if a declaration with the same key exists already in the
2109 table. The function returns declaration node in the table with the
2110 same key as given declaration node. */
2118 entry_ptr = htab_find_slot (decl_table, decl, 1);
2119 if (*entry_ptr == NULL)
2120 *entry_ptr = (void *) decl;
2121 return (decl_t) *entry_ptr;
2124 /* The following variable value is node representing declaration. The
2125 node used for searching declaration with given name. */
2126 static struct decl work_decl;
2128 /* The function searches for declaration in the table with the same
2129 key as node representing name of the declaration. The function
2130 returns node found in the table, NULL if such node does not exist
2138 work_decl.decl.unit.name = name;
2139 entry = htab_find (decl_table, &work_decl);
2140 return (decl_t) entry;
2143 /* The function creates empty declaration table and node representing
2144 declaration and used for searching declaration with given name.
2145 The function must be called only once before any work with the
2146 declaration table. */
2148 initiate_decl_table ()
2150 work_decl.mode = dm_unit;
2151 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2154 /* The function deletes the declaration table. Only call of function
2155 `initiate_declaration_table' is possible immediately after this
2158 finish_decl_table ()
2160 htab_delete (decl_table);
2165 /* This page contains checker of pipeline hazard description. */
2167 /* Checking NAMES in an exclusion clause vector and returning formed
2168 unit_set_el_list. */
2169 static unit_set_el_t
2170 process_excls (names, num, excl_pos)
2173 pos_t excl_pos ATTRIBUTE_UNUSED;
2175 unit_set_el_t el_list;
2176 unit_set_el_t last_el;
2177 unit_set_el_t new_el;
2178 decl_t decl_in_table;
2183 for (i = 0; i < num; i++)
2185 decl_in_table = find_decl (names [i]);
2186 if (decl_in_table == NULL)
2187 error ("unit `%s' in exclusion is not declared", names [i]);
2188 else if (decl_in_table->mode != dm_unit)
2189 error ("`%s' in exclusion is not unit", names [i]);
2192 new_el = create_node (sizeof (struct unit_set_el));
2193 new_el->unit_decl = &decl_in_table->decl.unit;
2194 new_el->next_unit_set_el = NULL;
2195 if (last_el == NULL)
2196 el_list = last_el = new_el;
2199 last_el->next_unit_set_el = new_el;
2200 last_el = last_el->next_unit_set_el;
2207 /* The function adds each element from SOURCE_LIST to the exclusion
2208 list of the each element from DEST_LIST. Checking situation "unit
2209 excludes itself". */
2211 add_excls (dest_list, source_list, excl_pos)
2212 unit_set_el_t dest_list;
2213 unit_set_el_t source_list;
2214 pos_t excl_pos ATTRIBUTE_UNUSED;
2218 unit_set_el_t curr_el;
2219 unit_set_el_t prev_el;
2222 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2223 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2225 if (dst->unit_decl == src->unit_decl)
2227 error ("unit `%s' excludes itself", src->unit_decl->name);
2230 if (dst->unit_decl->automaton_name != NULL
2231 && src->unit_decl->automaton_name != NULL
2232 && strcmp (dst->unit_decl->automaton_name,
2233 src->unit_decl->automaton_name) != 0)
2235 error ("units `%s' and `%s' in exclusion set belong to different automata",
2236 src->unit_decl->name, dst->unit_decl->name);
2239 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2241 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2242 if (curr_el->unit_decl == src->unit_decl)
2244 if (curr_el == NULL)
2246 /* Element not found - insert. */
2247 copy = copy_node (src, sizeof (*src));
2248 copy->next_unit_set_el = NULL;
2249 if (prev_el == NULL)
2250 dst->unit_decl->excl_list = copy;
2252 prev_el->next_unit_set_el = copy;
2257 /* Checking NAMES in an presence clause vector and returning formed
2258 unit_set_el_list. The function is called only after processing all
2260 static unit_set_el_t
2261 process_presence_absence (names, num, req_pos, presence_p)
2264 pos_t req_pos ATTRIBUTE_UNUSED;
2267 unit_set_el_t el_list;
2268 unit_set_el_t last_el;
2269 unit_set_el_t new_el;
2270 decl_t decl_in_table;
2275 for (i = 0; i < num; i++)
2277 decl_in_table = find_decl (names [i]);
2278 if (decl_in_table == NULL)
2280 ? "unit `%s' in presence set is not declared"
2281 : "unit `%s' in absence set is not declared"), names [i]);
2282 else if (decl_in_table->mode != dm_unit)
2284 ? "`%s' in presence set is not unit"
2285 : "`%s' in absence set is not unit"), names [i]);
2288 new_el = create_node (sizeof (struct unit_set_el));
2289 new_el->unit_decl = &decl_in_table->decl.unit;
2290 new_el->next_unit_set_el = NULL;
2291 if (last_el == NULL)
2292 el_list = last_el = new_el;
2295 last_el->next_unit_set_el = new_el;
2296 last_el = last_el->next_unit_set_el;
2303 /* The function adds each element from SOURCE_LIST to presence (if
2304 PRESENCE_P) or absence list of the each element from DEST_LIST.
2305 Checking situations "unit requires own presence", "unit requires
2306 own absence", and "unit excludes and requires presence of ...".
2307 Remember that we process absence sets only after all presence
2310 add_presence_absence (dest_list, source_list, req_pos, presence_p)
2311 unit_set_el_t dest_list;
2312 unit_set_el_t source_list;
2313 pos_t req_pos ATTRIBUTE_UNUSED;
2318 unit_set_el_t curr_el;
2319 unit_set_el_t prev_el;
2322 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2323 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2325 if (dst->unit_decl == src->unit_decl)
2328 ? "unit `%s' requires own presence"
2329 : "unit `%s' requires own absence"), src->unit_decl->name);
2332 if (dst->unit_decl->automaton_name != NULL
2333 && src->unit_decl->automaton_name != NULL
2334 && strcmp (dst->unit_decl->automaton_name,
2335 src->unit_decl->automaton_name) != 0)
2338 ? "units `%s' and `%s' in presence set belong to different automata"
2339 : "units `%s' and `%s' in absence set belong to different automata"),
2340 src->unit_decl->name, dst->unit_decl->name);
2343 for (curr_el = (presence_p
2344 ? dst->unit_decl->presence_list
2345 : dst->unit_decl->absence_list), prev_el = NULL;
2347 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2348 if (curr_el->unit_decl == src->unit_decl)
2350 if (curr_el == NULL)
2352 /* Element not found - insert if there is no error. */
2353 int no_error_flag = 1;
2356 for (curr_el = dst->unit_decl->excl_list;
2358 curr_el = curr_el->next_unit_set_el)
2360 if (src->unit_decl == curr_el->unit_decl)
2365 ("unit `%s' excludes and requires presence of `%s'",
2366 dst->unit_decl->name, src->unit_decl->name);
2371 ("unit `%s' excludes and requires presence of `%s'",
2372 dst->unit_decl->name, src->unit_decl->name);
2376 for (curr_el = dst->unit_decl->presence_list;
2378 curr_el = curr_el->next_unit_set_el)
2380 if (src->unit_decl == curr_el->unit_decl)
2385 ("unit `%s' requires absence and presence of `%s'",
2386 dst->unit_decl->name, src->unit_decl->name);
2391 ("unit `%s' requires absence and presence of `%s'",
2392 dst->unit_decl->name, src->unit_decl->name);
2397 copy = copy_node (src, sizeof (*src));
2398 copy->next_unit_set_el = NULL;
2399 if (prev_el == NULL)
2402 dst->unit_decl->presence_list = copy;
2404 dst->unit_decl->absence_list = copy;
2407 prev_el->next_unit_set_el = copy;
2413 /* The function searches for bypass with given IN_INSN_RESERV in given
2415 static struct bypass_decl *
2416 find_bypass (bypass_list, in_insn_reserv)
2417 struct bypass_decl *bypass_list;
2418 struct insn_reserv_decl *in_insn_reserv;
2420 struct bypass_decl *bypass;
2422 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2423 if (bypass->in_insn_reserv == in_insn_reserv)
2428 /* The function processes pipeline description declarations, checks
2429 their correctness, and forms exclusion/presence/absence sets. */
2434 decl_t automaton_decl;
2435 decl_t decl_in_table;
2436 decl_t out_insn_reserv;
2437 decl_t in_insn_reserv;
2438 struct bypass_decl *bypass;
2439 int automaton_presence;
2442 /* Checking repeated automata declarations. */
2443 automaton_presence = 0;
2444 for (i = 0; i < description->decls_num; i++)
2446 decl = description->decls [i];
2447 if (decl->mode == dm_automaton)
2449 automaton_presence = 1;
2450 decl_in_table = insert_automaton_decl (decl);
2451 if (decl_in_table != decl)
2454 error ("repeated declaration of automaton `%s'",
2455 decl->decl.automaton.name);
2457 warning ("repeated declaration of automaton `%s'",
2458 decl->decl.automaton.name);
2462 /* Checking undeclared automata, repeated declarations (except for
2463 automata) and correctness of their attributes (insn latency times
2465 for (i = 0; i < description->decls_num; i++)
2467 decl = description->decls [i];
2468 if (decl->mode == dm_insn_reserv)
2470 decl->decl.insn_reserv.condexp
2471 = check_attr_test (decl->decl.insn_reserv.condexp, 0, 0);
2472 if (decl->decl.insn_reserv.default_latency < 0)
2473 error ("define_insn_reservation `%s' has negative latency time",
2474 decl->decl.insn_reserv.name);
2475 decl->decl.insn_reserv.insn_num = description->insns_num;
2476 description->insns_num++;
2477 decl_in_table = insert_insn_decl (decl);
2478 if (decl_in_table != decl)
2479 error ("`%s' is already used as insn reservation name",
2480 decl->decl.insn_reserv.name);
2482 else if (decl->mode == dm_bypass)
2484 if (decl->decl.bypass.latency < 0)
2485 error ("define_bypass `%s - %s' has negative latency time",
2486 decl->decl.bypass.out_insn_name,
2487 decl->decl.bypass.in_insn_name);
2489 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2491 if (decl->mode == dm_unit)
2493 decl->decl.unit.automaton_decl = NULL;
2494 if (decl->decl.unit.automaton_name != NULL)
2497 = find_automaton_decl (decl->decl.unit.automaton_name);
2498 if (automaton_decl == NULL)
2499 error ("automaton `%s' is not declared",
2500 decl->decl.unit.automaton_name);
2503 automaton_decl->decl.automaton.automaton_is_used = 1;
2504 decl->decl.unit.automaton_decl
2505 = &automaton_decl->decl.automaton;
2508 else if (automaton_presence)
2509 error ("define_unit `%s' without automaton when one defined",
2510 decl->decl.unit.name);
2511 decl->decl.unit.unit_num = description->units_num;
2512 description->units_num++;
2513 if (strcmp (decl->decl.unit.name, NOTHING_NAME) == 0)
2515 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2518 decl_in_table = find_decl (decl->decl.unit.name);
2522 if (strcmp (decl->decl.reserv.name, NOTHING_NAME) == 0)
2524 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2527 decl_in_table = find_decl (decl->decl.reserv.name);
2529 if (decl_in_table == NULL)
2530 decl_in_table = insert_decl (decl);
2533 if (decl->mode == dm_unit)
2534 error ("repeated declaration of unit `%s'",
2535 decl->decl.unit.name);
2537 error ("repeated declaration of reservation `%s'",
2538 decl->decl.reserv.name);
2542 /* Check bypasses and form list of bypasses for each (output)
2544 for (i = 0; i < description->decls_num; i++)
2546 decl = description->decls [i];
2547 if (decl->mode == dm_bypass)
2549 out_insn_reserv = find_insn_decl (decl->decl.bypass.out_insn_name);
2550 in_insn_reserv = find_insn_decl (decl->decl.bypass.in_insn_name);
2551 if (out_insn_reserv == NULL)
2552 error ("there is no insn reservation `%s'",
2553 decl->decl.bypass.out_insn_name);
2554 else if (in_insn_reserv == NULL)
2555 error ("there is no insn reservation `%s'",
2556 decl->decl.bypass.in_insn_name);
2559 decl->decl.bypass.out_insn_reserv
2560 = &out_insn_reserv->decl.insn_reserv;
2561 decl->decl.bypass.in_insn_reserv
2562 = &in_insn_reserv->decl.insn_reserv;
2564 = find_bypass (out_insn_reserv->decl.insn_reserv.bypass_list,
2565 decl->decl.bypass.in_insn_reserv);
2568 if (decl->decl.bypass.latency == bypass->latency)
2572 ("the same bypass `%s - %s' is already defined",
2573 decl->decl.bypass.out_insn_name,
2574 decl->decl.bypass.in_insn_name);
2577 ("the same bypass `%s - %s' is already defined",
2578 decl->decl.bypass.out_insn_name,
2579 decl->decl.bypass.in_insn_name);
2582 error ("bypass `%s - %s' is already defined",
2583 decl->decl.bypass.out_insn_name,
2584 decl->decl.bypass.in_insn_name);
2588 decl->decl.bypass.next
2589 = out_insn_reserv->decl.insn_reserv.bypass_list;
2590 out_insn_reserv->decl.insn_reserv.bypass_list
2591 = &decl->decl.bypass;
2597 /* Check exclusion set declarations and form exclussion sets. */
2598 for (i = 0; i < description->decls_num; i++)
2600 decl = description->decls [i];
2601 if (decl->mode == dm_excl)
2603 unit_set_el_t unit_set_el_list;
2604 unit_set_el_t unit_set_el_list_2;
2607 = process_excls (decl->decl.excl.names,
2608 decl->decl.excl.first_list_length, decl->pos);
2610 = process_excls (&decl->decl.excl.names
2611 [decl->decl.excl.first_list_length],
2612 decl->decl.excl.names_num
2613 - decl->decl.excl.first_list_length,
2615 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2616 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2620 /* Check presence set declarations and form presence sets. */
2621 for (i = 0; i < description->decls_num; i++)
2623 decl = description->decls [i];
2624 if (decl->mode == dm_presence)
2626 unit_set_el_t unit_set_el_list;
2627 unit_set_el_t unit_set_el_list_2;
2630 = process_presence_absence
2631 (decl->decl.presence.names,
2632 decl->decl.presence.first_list_length, decl->pos, 1);
2634 = process_presence_absence
2635 (&decl->decl.presence.names
2636 [decl->decl.presence.first_list_length],
2637 decl->decl.presence.names_num
2638 - decl->decl.presence.first_list_length,
2640 add_presence_absence (unit_set_el_list, unit_set_el_list_2,
2645 /* Check absence set declarations and form absence sets. */
2646 for (i = 0; i < description->decls_num; i++)
2648 decl = description->decls [i];
2649 if (decl->mode == dm_absence)
2651 unit_set_el_t unit_set_el_list;
2652 unit_set_el_t unit_set_el_list_2;
2655 = process_presence_absence
2656 (decl->decl.presence.names,
2657 decl->decl.presence.first_list_length, decl->pos, 0);
2659 = process_presence_absence
2660 (&decl->decl.presence.names
2661 [decl->decl.presence.first_list_length],
2662 decl->decl.presence.names_num
2663 - decl->decl.presence.first_list_length,
2665 add_presence_absence (unit_set_el_list, unit_set_el_list_2,
2671 /* The following function checks that declared automaton is used. If
2672 the automaton is not used, the function fixes error/warning. The
2673 following function must be called only after `process_decls'. */
2675 check_automaton_usage ()
2680 for (i = 0; i < description->decls_num; i++)
2682 decl = description->decls [i];
2683 if (decl->mode == dm_automaton
2684 && !decl->decl.automaton.automaton_is_used)
2687 error ("automaton `%s' is not used", decl->decl.automaton.name);
2689 warning ("automaton `%s' is not used", decl->decl.automaton.name);
2694 /* The following recursive function processes all regexp in order to
2695 fix usage of units or reservations and to fix errors of undeclared
2696 name. The function may change unit_regexp onto reserv_regexp.
2697 Remember that reserv_regexp does not exist before the function
2700 process_regexp (regexp)
2703 decl_t decl_in_table;
2704 regexp_t new_regexp;
2707 if (regexp->mode == rm_unit)
2709 decl_in_table = find_decl (regexp->regexp.unit.name);
2710 if (decl_in_table == NULL)
2711 error ("undeclared unit or reservation `%s'",
2712 regexp->regexp.unit.name);
2713 else if (decl_in_table->mode == dm_unit)
2715 decl_in_table->decl.unit.unit_is_used = 1;
2716 regexp->regexp.unit.unit_decl = &decl_in_table->decl.unit;
2718 else if (decl_in_table->mode == dm_reserv)
2720 decl_in_table->decl.reserv.reserv_is_used = 1;
2721 new_regexp = create_node (sizeof (struct regexp));
2722 new_regexp->mode = rm_reserv;
2723 new_regexp->pos = regexp->pos;
2724 new_regexp->regexp.reserv.name = regexp->regexp.unit.name;
2725 new_regexp->regexp.reserv.reserv_decl = &decl_in_table->decl.reserv;
2726 regexp = new_regexp;
2731 else if (regexp->mode == rm_sequence)
2732 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2733 regexp->regexp.sequence.regexps [i]
2734 = process_regexp (regexp->regexp.sequence.regexps [i]);
2735 else if (regexp->mode == rm_allof)
2736 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2737 regexp->regexp.allof.regexps [i]
2738 = process_regexp (regexp->regexp.allof.regexps [i]);
2739 else if (regexp->mode == rm_oneof)
2740 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2741 regexp->regexp.oneof.regexps [i]
2742 = process_regexp (regexp->regexp.oneof.regexps [i]);
2743 else if (regexp->mode == rm_repeat)
2744 regexp->regexp.repeat.regexp
2745 = process_regexp (regexp->regexp.repeat.regexp);
2746 else if (regexp->mode != rm_nothing)
2751 /* The following function processes regexp of define_reservation and
2752 define_insn_reservation with the aid of function
2753 `process_regexp'. */
2755 process_regexp_decls ()
2760 for (i = 0; i < description->decls_num; i++)
2762 decl = description->decls [i];
2763 if (decl->mode == dm_reserv)
2764 decl->decl.reserv.regexp = process_regexp (decl->decl.reserv.regexp);
2765 else if (decl->mode == dm_insn_reserv)
2766 decl->decl.insn_reserv.regexp
2767 = process_regexp (decl->decl.insn_reserv.regexp);
2771 /* The following function checks that declared unit is used. If the
2772 unit is not used, the function fixes errors/warnings. The
2773 following function must be called only after `process_decls',
2774 `process_regexp_decls'. */
2781 for (i = 0; i < description->decls_num; i++)
2783 decl = description->decls [i];
2784 if (decl->mode == dm_unit && !decl->decl.unit.unit_is_used)
2787 error ("unit `%s' is not used", decl->decl.unit.name);
2789 warning ("unit `%s' is not used", decl->decl.unit.name);
2791 else if (decl->mode == dm_reserv && !decl->decl.reserv.reserv_is_used)
2794 error ("reservation `%s' is not used", decl->decl.reserv.name);
2796 warning ("reservation `%s' is not used", decl->decl.reserv.name);
2801 /* The following variable value is number of reservation being
2802 processed on loop recognition. */
2803 static int curr_loop_pass_num;
2805 /* The following recursive function returns nonzero value if REGEXP
2806 contains given decl or reservations in given regexp refers for
2809 loop_in_regexp (regexp, start_decl)
2817 if (regexp->mode == rm_unit)
2819 else if (regexp->mode == rm_reserv)
2821 if (start_decl->mode == dm_reserv
2822 && regexp->regexp.reserv.reserv_decl == &start_decl->decl.reserv)
2824 else if (regexp->regexp.reserv.reserv_decl->loop_pass_num
2825 == curr_loop_pass_num)
2826 /* declaration has been processed. */
2830 regexp->regexp.reserv.reserv_decl->loop_pass_num
2831 = curr_loop_pass_num;
2832 return loop_in_regexp (regexp->regexp.reserv.reserv_decl->regexp,
2836 else if (regexp->mode == rm_sequence)
2838 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2839 if (loop_in_regexp (regexp->regexp.sequence.regexps [i], start_decl))
2843 else if (regexp->mode == rm_allof)
2845 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2846 if (loop_in_regexp (regexp->regexp.allof.regexps [i], start_decl))
2850 else if (regexp->mode == rm_oneof)
2852 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2853 if (loop_in_regexp (regexp->regexp.oneof.regexps [i], start_decl))
2857 else if (regexp->mode == rm_repeat)
2858 return loop_in_regexp (regexp->regexp.repeat.regexp, start_decl);
2861 if (regexp->mode != rm_nothing)
2867 /* The following function fixes errors "cycle in definition ...". The
2868 function uses function `loop_in_regexp' for that. */
2870 check_loops_in_regexps ()
2875 for (i = 0; i < description->decls_num; i++)
2877 decl = description->decls [i];
2878 if (decl->mode == dm_reserv)
2879 decl->decl.reserv.loop_pass_num = 0;
2881 for (i = 0; i < description->decls_num; i++)
2883 decl = description->decls [i];
2884 curr_loop_pass_num = i;
2886 if (decl->mode == dm_reserv)
2888 decl->decl.reserv.loop_pass_num = curr_loop_pass_num;
2889 if (loop_in_regexp (decl->decl.reserv.regexp, decl))
2891 if (decl->decl.reserv.regexp == NULL)
2893 error ("cycle in definition of reservation `%s'",
2894 decl->decl.reserv.name);
2900 /* The function recursively processes IR of reservation and defines
2901 max and min cycle for reservation of unit and for result in the
2904 process_regexp_cycles (regexp, start_cycle)
2910 if (regexp->mode == rm_unit)
2912 if (regexp->regexp.unit.unit_decl->max_occ_cycle_num < start_cycle)
2913 regexp->regexp.unit.unit_decl->max_occ_cycle_num = start_cycle;
2916 else if (regexp->mode == rm_reserv)
2917 return process_regexp_cycles (regexp->regexp.reserv.reserv_decl->regexp,
2919 else if (regexp->mode == rm_repeat)
2921 for (i = 0; i < regexp->regexp.repeat.repeat_num; i++)
2922 start_cycle = process_regexp_cycles (regexp->regexp.repeat.regexp,
2926 else if (regexp->mode == rm_sequence)
2928 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
2930 = process_regexp_cycles (regexp->regexp.sequence.regexps [i],
2934 else if (regexp->mode == rm_allof)
2936 int finish_cycle = 0;
2939 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
2941 cycle = process_regexp_cycles (regexp->regexp.allof.regexps [i],
2943 if (finish_cycle < cycle)
2944 finish_cycle = cycle;
2946 return finish_cycle;
2948 else if (regexp->mode == rm_oneof)
2950 int finish_cycle = 0;
2953 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
2955 cycle = process_regexp_cycles (regexp->regexp.oneof.regexps [i],
2957 if (finish_cycle < cycle)
2958 finish_cycle = cycle;
2960 return finish_cycle;
2964 if (regexp->mode != rm_nothing)
2970 /* The following function is called only for correct program. The
2971 function defines max reservation of insns in cycles. */
2973 evaluate_max_reserv_cycles ()
2975 int max_insn_cycles_num;
2979 description->max_insn_reserv_cycles = 0;
2980 for (i = 0; i < description->decls_num; i++)
2982 decl = description->decls [i];
2983 if (decl->mode == dm_insn_reserv)
2986 = process_regexp_cycles (decl->decl.insn_reserv.regexp, 0);
2987 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
2988 description->max_insn_reserv_cycles = max_insn_cycles_num;
2993 /* The following function calls functions for checking all
2996 check_all_description ()
2999 check_automaton_usage ();
3000 process_regexp_decls ();
3002 check_loops_in_regexps ();
3004 evaluate_max_reserv_cycles ();
3009 /* The page contains abstract data `ticker'. This data is used to
3010 report time of different phases of building automata. It is
3011 possibly to write a description for which automata will be built
3012 during several minutes even on fast machine. */
3014 /* The following function creates ticker and makes it active. */
3020 ticker.modified_creation_time = get_run_time ();
3021 ticker.incremented_off_time = 0;
3025 /* The following function switches off given ticker. */
3030 if (ticker->incremented_off_time == 0)
3031 ticker->incremented_off_time = get_run_time () + 1;
3034 /* The following function switches on given ticker. */
3039 if (ticker->incremented_off_time != 0)
3041 ticker->modified_creation_time
3042 += get_run_time () - ticker->incremented_off_time + 1;
3043 ticker->incremented_off_time = 0;
3047 /* The following function returns current time in milliseconds since
3048 the moment when given ticker was created. */
3050 active_time (ticker)
3053 if (ticker.incremented_off_time != 0)
3054 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3056 return get_run_time () - ticker.modified_creation_time;
3059 /* The following function returns string representation of active time
3060 of given ticker. The result is string representation of seconds
3061 with accuracy of 1/100 second. Only result of the last call of the
3062 function exists. Therefore the following code is not correct
3064 printf ("parser time: %s\ngeneration time: %s\n",
3065 active_time_string (parser_ticker),
3066 active_time_string (generation_ticker));
3068 Correct code has to be the following
3070 printf ("parser time: %s\n", active_time_string (parser_ticker));
3071 printf ("generation time: %s\n",
3072 active_time_string (generation_ticker));
3076 print_active_time (f, ticker)
3082 msecs = active_time (ticker);
3083 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3088 /* The following variable value is number of automaton which are
3089 really being created. This value is defined on the base of
3090 argument of option `-split'. If the variable has zero value the
3091 number of automata is defined by the constructions `%automaton'.
3092 This case occures when option `-split' is absent or has zero
3093 argument. If constructions `define_automaton' is absent only one
3094 automaton is created. */
3095 static int automata_num;
3097 /* The following variable values are times of
3098 o transformation of regular expressions
3099 o building NDFA (DFA if !ndfa_flag)
3100 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3102 o building insn equivalence classes
3105 static ticker_t transform_time;
3106 static ticker_t NDFA_time;
3107 static ticker_t NDFA_to_DFA_time;
3108 static ticker_t minimize_time;
3109 static ticker_t equiv_time;
3110 static ticker_t automaton_generation_time;
3111 static ticker_t output_time;
3113 /* The following variable values are times of
3116 all pipeline hazard translator work */
3117 static ticker_t check_time;
3118 static ticker_t generation_time;
3119 static ticker_t all_time;
3123 /* Pseudo insn decl which denotes advancing cycle. */
3124 static decl_t advance_cycle_insn_decl;
3126 add_advance_cycle_insn_decl ()
3128 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3129 advance_cycle_insn_decl->mode = dm_insn_reserv;
3130 advance_cycle_insn_decl->pos = no_pos;
3131 advance_cycle_insn_decl->decl.insn_reserv.regexp = NULL;
3132 advance_cycle_insn_decl->decl.insn_reserv.name = (char *) "$advance_cycle";
3133 advance_cycle_insn_decl->decl.insn_reserv.insn_num = description->insns_num;
3134 description->decls [description->decls_num] = advance_cycle_insn_decl;
3135 description->decls_num++;
3136 description->insns_num++;
3141 /* Abstract data `alternative states' which reperesents
3142 nondeterministic nature of the description (see comments for
3143 structures alt_state and state). */
3145 /* List of free states. */
3146 static alt_state_t first_free_alt_state;
3149 /* The following variables is maximal number of allocated nodes
3151 static int allocated_alt_states_num = 0;
3154 /* The following function returns free node alt_state. It may be new
3155 allocated node or node freed eralier. */
3157 get_free_alt_state ()
3161 if (first_free_alt_state != NULL)
3163 result = first_free_alt_state;
3164 first_free_alt_state = first_free_alt_state->next_alt_state;
3169 allocated_alt_states_num++;
3171 result = create_node (sizeof (struct alt_state));
3173 result->state = NULL;
3174 result->next_alt_state = NULL;
3175 result->next_sorted_alt_state = NULL;
3179 /* The function frees node ALT_STATE. */
3181 free_alt_state (alt_state)
3182 alt_state_t alt_state;
3184 if (alt_state == NULL)
3186 alt_state->next_alt_state = first_free_alt_state;
3187 first_free_alt_state = alt_state;
3190 /* The function frees list started with node ALT_STATE_LIST. */
3192 free_alt_states (alt_states_list)
3193 alt_state_t alt_states_list;
3195 alt_state_t curr_alt_state;
3196 alt_state_t next_alt_state;
3198 for (curr_alt_state = alt_states_list;
3199 curr_alt_state != NULL;
3200 curr_alt_state = next_alt_state)
3202 next_alt_state = curr_alt_state->next_alt_state;
3203 free_alt_state (curr_alt_state);
3207 /* The function compares unique numbers of alt states. */
3209 alt_state_cmp (alt_state_ptr_1, alt_state_ptr_2)
3210 const void *alt_state_ptr_1;
3211 const void *alt_state_ptr_2;
3213 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3214 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3216 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3217 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3223 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3224 states from the list. The comparison key is alt state unique
3227 uniq_sort_alt_states (alt_states_list)
3228 alt_state_t alt_states_list;
3230 alt_state_t curr_alt_state;
3231 vla_ptr_t alt_states;
3233 size_t prev_unique_state_ind;
3235 alt_state_t *result_ptr;
3237 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3238 for (curr_alt_state = alt_states_list;
3239 curr_alt_state != NULL;
3240 curr_alt_state = curr_alt_state->next_alt_state)
3241 VLA_PTR_ADD (alt_states, curr_alt_state);
3242 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3243 sizeof (alt_state_t), alt_state_cmp);
3244 if (VLA_PTR_LENGTH (alt_states) == 0)
3248 result_ptr = VLA_PTR_BEGIN (alt_states);
3249 prev_unique_state_ind = 0;
3250 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3251 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3253 prev_unique_state_ind++;
3254 result_ptr [prev_unique_state_ind] = result_ptr [i];
3257 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3258 free_alt_state (result_ptr [i]);
3260 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3261 result_ptr = VLA_PTR_BEGIN (alt_states);
3262 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3263 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3264 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3265 result = *result_ptr;
3267 VLA_PTR_DELETE (alt_states);
3271 /* The function checks equality of alt state lists. Remember that the
3272 lists must be already sorted by the previous function. */
3274 alt_states_eq (alt_states_1, alt_states_2)
3275 alt_state_t alt_states_1;
3276 alt_state_t alt_states_2;
3278 while (alt_states_1 != NULL && alt_states_2 != NULL
3279 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3281 alt_states_1 = alt_states_1->next_sorted_alt_state;
3282 alt_states_2 = alt_states_2->next_sorted_alt_state;
3284 return alt_states_1 == alt_states_2;
3287 /* Initialization of the abstract data. */
3289 initiate_alt_states ()
3291 first_free_alt_state = NULL;
3294 /* Finishing work with the abstract data. */
3296 finish_alt_states ()
3302 /* The page contains macros for work with bits strings. We could use
3303 standard gcc bitmap or sbitmap but it would result in difficulties
3304 of building canadian cross. */
3306 /* Set bit number bitno in the bit string. The macro is not side
3308 #define SET_BIT(bitstring, bitno) \
3309 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3311 /* Test if bit number bitno in the bitstring is set. The macro is not
3312 side effect proof. */
3313 #define TEST_BIT(bitstring, bitno) \
3314 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3318 /* This page contains abstract data `state'. */
3320 /* Maximal length of reservations in cycles (> 1). */
3321 static int max_cycles_num;
3323 /* Number of set elements (see type set_el_t) needed for
3324 representation of one cycle reservation. It is depended on units
3326 static int els_in_cycle_reserv;
3328 /* Number of set elements (see type set_el_t) needed for
3329 representation of maximal length reservation. Deterministic
3330 reservation is stored as set (bit string) of length equal to the
3331 variable value * number of bits in set_el_t. */
3332 static int els_in_reservs;
3334 /* VLA for representation of array of pointers to unit
3336 static vla_ptr_t units_container;
3338 /* The start address of the array. */
3339 static struct unit_decl **units_array;
3341 /* Empty reservation of maximal length. */
3342 static reserv_sets_t empty_reserv;
3344 /* The state table itself is represented by the following variable. */
3345 static htab_t state_table;
3347 /* VLA for representation of array of pointers to free nodes
3349 static vla_ptr_t free_states;
3351 static int curr_unique_state_num;
3354 /* The following variables is maximal number of allocated nodes
3356 static int allocated_states_num = 0;
3359 /* Allocate new reservation set. */
3360 static reserv_sets_t
3361 alloc_empty_reserv_sets ()
3363 reserv_sets_t result;
3365 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3366 result = (reserv_sets_t) obstack_base (&irp);
3367 obstack_finish (&irp);
3368 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3372 /* Hash value of reservation set. */
3374 reserv_sets_hash_value (reservs)
3375 reserv_sets_t reservs;
3377 unsigned int hash_value;
3379 set_el_t *reserv_ptr;
3382 reservs_num = els_in_reservs;
3383 reserv_ptr = reservs;
3384 while (reservs_num != 0)
3387 hash_value = ((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3388 | (hash_value << CHAR_BIT)) + *reserv_ptr;
3394 /* Comparison of given reservation sets. */
3396 reserv_sets_cmp (reservs_1, reservs_2)
3397 reserv_sets_t reservs_1;
3398 reserv_sets_t reservs_2;
3401 set_el_t *reserv_ptr_1;
3402 set_el_t *reserv_ptr_2;
3404 if (reservs_1 == NULL || reservs_2 == NULL)
3406 reservs_num = els_in_reservs;
3407 reserv_ptr_1 = reservs_1;
3408 reserv_ptr_2 = reservs_2;
3409 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3415 if (reservs_num == 0)
3417 else if (*reserv_ptr_1 < *reserv_ptr_2)
3423 /* The function checks equality of the reservation sets. */
3425 reserv_sets_eq (reservs_1, reservs_2)
3426 reserv_sets_t reservs_1;
3427 reserv_sets_t reservs_2;
3429 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3432 /* Set up in the reservation set that unit with UNIT_NUM is used on
3435 set_unit_reserv (reservs, cycle_num, unit_num)
3436 reserv_sets_t reservs;
3440 if (cycle_num >= max_cycles_num)
3442 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3443 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3446 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3447 used on CYCLE_NUM. */
3449 test_unit_reserv (reservs, cycle_num, unit_num)
3450 reserv_sets_t reservs;
3454 if (cycle_num >= max_cycles_num)
3456 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3457 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3460 /* The function checks that the reservation set represents no one unit
3463 it_is_empty_reserv_sets (operand)
3464 reserv_sets_t operand;
3466 set_el_t *reserv_ptr;
3469 if (operand == NULL)
3471 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3473 reserv_ptr++, reservs_num--)
3474 if (*reserv_ptr != 0)
3479 /* The function checks that the reservation sets are intersected,
3480 i.e. there is a unit reservation on a cycle in both reservation
3483 reserv_sets_are_intersected (operand_1, operand_2)
3484 reserv_sets_t operand_1;
3485 reserv_sets_t operand_2;
3489 set_el_t *cycle_ptr_1;
3490 set_el_t *cycle_ptr_2;
3493 if (operand_1 == NULL || operand_2 == NULL)
3495 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3496 el_ptr_1 < operand_1 + els_in_reservs;
3497 el_ptr_1++, el_ptr_2++)
3498 if (*el_ptr_1 & *el_ptr_2)
3500 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3501 cycle_ptr_1 < operand_1 + els_in_reservs;
3502 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3504 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3505 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3506 el_ptr_1++, el_ptr_2++)
3507 if (*el_ptr_1 & *el_ptr_2)
3510 for (el_ptr_1 = cycle_ptr_1,
3511 el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 1);
3512 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3513 el_ptr_1++, el_ptr_2++)
3514 if (*el_ptr_1 & *el_ptr_2)
3516 else if (*el_ptr_2 != 0)
3518 if (nonzero_p && el_ptr_1 >= cycle_ptr_1 + els_in_cycle_reserv)
3520 for (el_ptr_1 = cycle_ptr_1,
3521 el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 0);
3522 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3523 el_ptr_1++, el_ptr_2++)
3524 /* It looks like code for exclusion but exclusion set is
3525 made as symmetric relation preliminary. */
3526 if (*el_ptr_1 & *el_ptr_2)
3532 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3533 cpu cycle. The remaining bits of OPERAND (representing the last
3534 cycle unit reservations) are not chenged. */
3536 reserv_sets_shift (result, operand)
3537 reserv_sets_t result;
3538 reserv_sets_t operand;
3542 if (result == NULL || operand == NULL || result == operand)
3544 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3545 result [i - els_in_cycle_reserv] = operand [i];
3548 /* OR of the reservation sets. */
3550 reserv_sets_or (result, operand_1, operand_2)
3551 reserv_sets_t result;
3552 reserv_sets_t operand_1;
3553 reserv_sets_t operand_2;
3557 set_el_t *result_set_el_ptr;
3559 if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3561 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3562 el_ptr_1 < operand_1 + els_in_reservs;
3563 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3564 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3567 /* AND of the reservation sets. */
3569 reserv_sets_and (result, operand_1, operand_2)
3570 reserv_sets_t result;
3571 reserv_sets_t operand_1;
3572 reserv_sets_t operand_2;
3576 set_el_t *result_set_el_ptr;
3578 if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3580 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3581 el_ptr_1 < operand_1 + els_in_reservs;
3582 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3583 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3586 /* The function outputs string representation of units reservation on
3587 cycle START_CYCLE in the reservation set. The function uses repeat
3588 construction if REPETITION_NUM > 1. */
3590 output_cycle_reservs (f, reservs, start_cycle, repetition_num)
3592 reserv_sets_t reservs;
3597 int reserved_units_num;
3599 reserved_units_num = 0;
3600 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3601 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3602 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3603 reserved_units_num++;
3604 if (repetition_num <= 0)
3606 if (repetition_num != 1 && reserved_units_num > 1)
3608 reserved_units_num = 0;
3610 unit_num < description->units_num;
3612 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3613 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3615 if (reserved_units_num != 0)
3617 reserved_units_num++;
3618 fprintf (f, "%s", units_array [unit_num]->name);
3620 if (reserved_units_num == 0)
3621 fprintf (f, NOTHING_NAME);
3622 if (repetition_num <= 0)
3624 if (reserved_units_num != 0 && repetition_num != 1)
3626 if (reserved_units_num > 1)
3628 fprintf (f, "*%d", repetition_num);
3632 /* The function outputs string representation of units reservation in
3633 the reservation set. */
3635 output_reserv_sets (f, reservs)
3637 reserv_sets_t reservs;
3639 int start_cycle = 0;
3644 for (cycle = 0; cycle < max_cycles_num; cycle++)
3645 if (repetition_num == 0)
3648 start_cycle = cycle;
3651 ((char *) reservs + start_cycle * els_in_cycle_reserv
3652 * sizeof (set_el_t),
3653 (char *) reservs + cycle * els_in_cycle_reserv
3654 * sizeof (set_el_t),
3655 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3659 if (start_cycle != 0)
3661 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3663 start_cycle = cycle;
3665 if (start_cycle < max_cycles_num)
3667 if (start_cycle != 0)
3669 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3673 /* The following function returns free node state for AUTOMATON. It
3674 may be new allocated node or node freed eralier. The function also
3675 allocates reservation set if WITH_RESERVS has nonzero value. */
3677 get_free_state (with_reservs, automaton)
3679 automaton_t automaton;
3683 if (max_cycles_num <= 0 || automaton == NULL)
3685 if (VLA_PTR_LENGTH (free_states) != 0)
3687 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
3688 VLA_PTR_SHORTEN (free_states, 1);
3689 result->automaton = automaton;
3690 result->first_out_arc = NULL;
3691 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3692 result->it_was_placed_in_stack_for_DFA_forming = 0;
3693 result->component_states = NULL;
3694 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3699 allocated_states_num++;
3701 result = create_node (sizeof (struct state));
3702 result->automaton = automaton;
3703 result->first_out_arc = NULL;
3704 result->unique_num = curr_unique_state_num;
3705 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3706 curr_unique_state_num++;
3710 if (result->reservs == NULL)
3711 result->reservs = alloc_empty_reserv_sets ();
3713 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3718 /* The function frees node STATE. */
3723 free_alt_states (state->component_states);
3724 VLA_PTR_ADD (free_states, state);
3727 /* Hash value of STATE. If STATE represents deterministic state it is
3728 simply hash value of the corresponding reservation set. Otherwise
3729 it is formed from hash values of the component deterministic
3730 states. One more key is order number of state automaton. */
3735 unsigned int hash_value;
3736 alt_state_t alt_state;
3738 if (((state_t) state)->component_states == NULL)
3739 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
3743 for (alt_state = ((state_t) state)->component_states;
3745 alt_state = alt_state->next_sorted_alt_state)
3746 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3747 | (hash_value << CHAR_BIT))
3748 + alt_state->state->unique_num);
3750 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3751 | (hash_value << CHAR_BIT))
3752 + ((state_t) state)->automaton->automaton_order_num);
3756 /* Return nonzero value if the states are the same. */
3758 state_eq_p (state_1, state_2)
3759 const void *state_1;
3760 const void *state_2;
3762 alt_state_t alt_state_1;
3763 alt_state_t alt_state_2;
3765 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
3767 else if (((state_t) state_1)->component_states == NULL
3768 && ((state_t) state_2)->component_states == NULL)
3769 return reserv_sets_eq (((state_t) state_1)->reservs,
3770 ((state_t) state_2)->reservs);
3771 else if (((state_t) state_1)->component_states != NULL
3772 && ((state_t) state_2)->component_states != NULL)
3774 for (alt_state_1 = ((state_t) state_1)->component_states,
3775 alt_state_2 = ((state_t) state_2)->component_states;
3776 alt_state_1 != NULL && alt_state_2 != NULL;
3777 alt_state_1 = alt_state_1->next_sorted_alt_state,
3778 alt_state_2 = alt_state_2->next_sorted_alt_state)
3779 /* All state in the list must be already in the hash table.
3780 Also the lists must be sorted. */
3781 if (alt_state_1->state != alt_state_2->state)
3783 return alt_state_1 == alt_state_2;
3789 /* Insert STATE into the state table. */
3791 insert_state (state)
3796 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
3797 if (*entry_ptr == NULL)
3798 *entry_ptr = (void *) state;
3799 return (state_t) *entry_ptr;
3802 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3803 deterministic STATE. */
3805 set_state_reserv (state, cycle_num, unit_num)
3810 set_unit_reserv (state->reservs, cycle_num, unit_num);
3813 /* Return nonzero value if the deterministic states contains a
3814 reservation of the same cpu unit on the same cpu cycle. */
3816 intersected_state_reservs_p (state1, state2)
3820 if (state1->automaton != state2->automaton)
3822 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3825 /* Return deterministic state (inserted into the table) which
3826 representing the automaton state whic is union of reservations of
3827 deterministic states. */
3829 states_union (state1, state2)
3834 state_t state_in_table;
3836 if (state1->automaton != state2->automaton)
3838 result = get_free_state (1, state1->automaton);
3839 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
3840 state_in_table = insert_state (result);
3841 if (result != state_in_table)
3843 free_state (result);
3844 result = state_in_table;
3849 /* Return deterministic state (inserted into the table) which
3850 represent the automaton state is obtained from deterministic STATE
3851 by advancing cpu cycle. */
3857 state_t state_in_table;
3859 result = get_free_state (1, state->automaton);
3860 reserv_sets_shift (result->reservs, state->reservs);
3861 state_in_table = insert_state (result);
3862 if (result != state_in_table)
3864 free_state (result);
3865 result = state_in_table;
3870 /* Initialization of the abstract data. */
3877 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
3879 = (description->decls_num ? VLA_PTR_BEGIN (units_container) : NULL);
3880 for (i = 0; i < description->decls_num; i++)
3882 decl = description->decls [i];
3883 if (decl->mode == dm_unit)
3884 units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
3886 max_cycles_num = description->max_insn_reserv_cycles;
3887 if (max_cycles_num == 0)
3890 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3891 / (sizeof (set_el_t) * CHAR_BIT));
3892 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3893 curr_unique_state_num = 0;
3894 initiate_alt_states ();
3895 VLA_PTR_CREATE (free_states, 1500, "free states");
3896 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3897 empty_reserv = alloc_empty_reserv_sets ();
3900 /* Finisging work with the abstract data. */
3904 VLA_PTR_DELETE (units_container);
3905 htab_delete (state_table);
3906 VLA_PTR_DELETE (free_states);
3907 finish_alt_states ();
3912 /* Abstract data `arcs'. */
3914 /* List of free arcs. */
3915 static arc_t first_free_arc;
3918 /* The following variables is maximal number of allocated nodes
3920 static int allocated_arcs_num = 0;
3923 /* The function frees node ARC. */
3928 arc->next_out_arc = first_free_arc;
3929 first_free_arc = arc;
3932 /* The function removes and frees ARC staring from FROM_STATE. */
3934 remove_arc (from_state, arc)
3943 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3945 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3946 if (curr_arc == arc)
3948 if (curr_arc == NULL)
3950 if (prev_arc == NULL)
3951 from_state->first_out_arc = arc->next_out_arc;
3953 prev_arc->next_out_arc = arc->next_out_arc;
3957 /* The functions returns arc with given characteristics (or NULL if
3958 the arc does not exist). */
3960 find_arc (from_state, to_state, insn)
3967 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3968 if (arc->to_state == to_state && arc->insn == insn)
3973 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
3974 and with given STATE_ALTS. The function returns added arc (or
3975 already existing arc). */
3977 add_arc (from_state, to_state, ainsn, state_alts)
3985 new_arc = find_arc (from_state, to_state, ainsn);
3986 if (new_arc != NULL)
3988 if (first_free_arc == NULL)
3991 allocated_arcs_num++;
3993 new_arc = create_node (sizeof (struct arc));
3994 new_arc->to_state = NULL;
3995 new_arc->insn = NULL;
3996 new_arc->next_out_arc = NULL;
4000 new_arc = first_free_arc;
4001 first_free_arc = first_free_arc->next_out_arc;
4003 new_arc->to_state = to_state;
4004 new_arc->insn = ainsn;
4005 ainsn->arc_exists_p = 1;
4006 new_arc->next_out_arc = from_state->first_out_arc;
4007 from_state->first_out_arc = new_arc;
4008 new_arc->next_arc_marked_by_insn = NULL;
4009 new_arc->state_alts = state_alts;
4013 /* The function returns the first arc starting from STATE. */
4015 first_out_arc (state)
4018 return state->first_out_arc;
4021 /* The function returns next out arc after ARC. */
4026 return arc->next_out_arc;
4029 /* Initialization of the abstract data. */
4033 first_free_arc = NULL;
4036 /* Finishing work with the abstract data. */
4044 /* Abstract data `automata lists'. */
4046 /* List of free states. */
4047 static automata_list_el_t first_free_automata_list_el;
4049 /* The list being formed. */
4050 static automata_list_el_t current_automata_list;
4052 /* Hash table of automata lists. */
4053 static htab_t automata_list_table;
4055 /* The following function returns free automata list el. It may be
4056 new allocated node or node freed earlier. */
4057 static automata_list_el_t
4058 get_free_automata_list_el ()
4060 automata_list_el_t result;
4062 if (first_free_automata_list_el != NULL)
4064 result = first_free_automata_list_el;
4065 first_free_automata_list_el
4066 = first_free_automata_list_el->next_automata_list_el;
4069 result = create_node (sizeof (struct automata_list_el));
4070 result->automaton = NULL;
4071 result->next_automata_list_el = NULL;
4075 /* The function frees node AUTOMATA_LIST_EL. */
4077 free_automata_list_el (automata_list_el)
4078 automata_list_el_t automata_list_el;
4080 if (automata_list_el == NULL)
4082 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4083 first_free_automata_list_el = automata_list_el;
4086 /* The function frees list AUTOMATA_LIST. */
4088 free_automata_list (automata_list)
4089 automata_list_el_t automata_list;
4091 automata_list_el_t curr_automata_list_el;
4092 automata_list_el_t next_automata_list_el;
4094 for (curr_automata_list_el = automata_list;
4095 curr_automata_list_el != NULL;
4096 curr_automata_list_el = next_automata_list_el)
4098 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4099 free_automata_list_el (curr_automata_list_el);
4103 /* Hash value of AUTOMATA_LIST. */
4105 automata_list_hash (automata_list)
4106 const void *automata_list;
4108 unsigned int hash_value;
4109 automata_list_el_t curr_automata_list_el;
4112 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4113 curr_automata_list_el != NULL;
4114 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4115 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4116 | (hash_value << CHAR_BIT))
4117 + curr_automata_list_el->automaton->automaton_order_num);
4121 /* Return nonzero value if the automata_lists are the same. */
4123 automata_list_eq_p (automata_list_1, automata_list_2)
4124 const void *automata_list_1;
4125 const void *automata_list_2;
4127 automata_list_el_t automata_list_el_1;
4128 automata_list_el_t automata_list_el_2;
4130 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4131 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4132 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4133 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4134 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4135 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4137 return automata_list_el_1 == automata_list_el_2;
4140 /* Initialization of the abstract data. */
4142 initiate_automata_lists ()
4144 first_free_automata_list_el = NULL;
4145 automata_list_table = htab_create (1500, automata_list_hash,
4146 automata_list_eq_p, (htab_del) 0);
4149 /* The following function starts new automata list and makes it the
4152 automata_list_start ()
4154 current_automata_list = NULL;
4157 /* The following function adds AUTOMATON to the current list. */
4159 automata_list_add (automaton)
4160 automaton_t automaton;
4162 automata_list_el_t el;
4164 el = get_free_automata_list_el ();
4165 el->automaton = automaton;
4166 el->next_automata_list_el = current_automata_list;
4167 current_automata_list = el;
4170 /* The following function finishes forming the current list, inserts
4171 it into the table and returns it. */
4172 static automata_list_el_t
4173 automata_list_finish ()
4177 if (current_automata_list == NULL)
4179 entry_ptr = htab_find_slot (automata_list_table,
4180 (void *) current_automata_list, 1);
4181 if (*entry_ptr == NULL)
4182 *entry_ptr = (void *) current_automata_list;
4184 free_automata_list (current_automata_list);
4185 current_automata_list = NULL;
4186 return (automata_list_el_t) *entry_ptr;
4189 /* Finishing work with the abstract data. */
4191 finish_automata_lists ()
4193 htab_delete (automata_list_table);
4198 /* The page contains abstract data for work with exclusion sets (see
4199 exclusion_set in file rtl.def). */
4201 /* The following variable refers to an exclusion set returned by
4202 get_excl_set. This is bit string of length equal to cpu units
4203 number. If exclusion set for given unit contains 1 for a unit,
4204 then simultaneous reservation of the units is prohibited. */
4205 static reserv_sets_t excl_set;
4207 /* The array contains exclusion sets for each unit. */
4208 static reserv_sets_t *unit_excl_set_table;
4210 /* The following function forms the array containing exclusion sets
4213 initiate_excl_sets ()
4216 reserv_sets_t unit_excl_set;
4220 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4221 excl_set = (reserv_sets_t) obstack_base (&irp);
4222 obstack_finish (&irp);
4223 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4224 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4225 obstack_finish (&irp);
4226 /* Evaluate unit exclusion sets. */
4227 for (i = 0; i < description->decls_num; i++)
4229 decl = description->decls [i];
4230 if (decl->mode == dm_unit)
4232 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4233 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4234 obstack_finish (&irp);
4235 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4236 for (el = decl->decl.unit.excl_list;
4238 el = el->next_unit_set_el)
4239 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4240 unit_excl_set_table [decl->decl.unit.unit_num] = unit_excl_set;
4245 /* The function sets up and return EXCL_SET which is union of
4246 exclusion sets for each unit in IN_SET. */
4247 static reserv_sets_t
4248 get_excl_set (in_set)
4249 reserv_sets_t in_set;
4257 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4258 memset (excl_set, 0, chars_num);
4259 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4260 if (((unsigned char *) in_set) [excl_char_num])
4261 for (i = CHAR_BIT - 1; i >= 0; i--)
4262 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4264 start_unit_num = excl_char_num * CHAR_BIT + i;
4265 if (start_unit_num >= description->units_num)
4267 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4270 |= unit_excl_set_table [start_unit_num] [unit_num];
4278 /* The page contains abstract data for work with presence/absence sets
4279 (see presence_set/absence_set in file rtl.def). */
4281 /* The following variables refer to correspondingly an presence and an
4282 absence set returned by get_presence_absence_set. This is bit
4283 string of length equal to cpu units number. */
4284 static reserv_sets_t presence_set, absence_set;
4286 /* The following arrays contain correspondingly presence and absence
4287 sets for each unit. */
4288 static reserv_sets_t *unit_presence_set_table, *unit_absence_set_table;
4290 /* The following function forms the array containing presence and
4291 absence sets for each unit */
4293 initiate_presence_absence_sets ()
4296 reserv_sets_t unit_set;
4300 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4301 presence_set = (reserv_sets_t) obstack_base (&irp);
4302 obstack_finish (&irp);
4303 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4304 unit_presence_set_table = (reserv_sets_t *) obstack_base (&irp);
4305 obstack_finish (&irp);
4306 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4307 absence_set = (reserv_sets_t) obstack_base (&irp);
4308 obstack_finish (&irp);
4309 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4310 unit_absence_set_table = (reserv_sets_t *) obstack_base (&irp);
4311 obstack_finish (&irp);
4312 /* Evaluate unit presence/absence sets. */
4313 for (i = 0; i < description->decls_num; i++)
4315 decl = description->decls [i];
4316 if (decl->mode == dm_unit)
4318 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4319 unit_set = (reserv_sets_t) obstack_base (&irp);
4320 obstack_finish (&irp);
4321 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4322 for (el = decl->decl.unit.presence_list;
4324 el = el->next_unit_set_el)
4325 SET_BIT (unit_set, el->unit_decl->unit_num);
4326 unit_presence_set_table [decl->decl.unit.unit_num] = unit_set;
4328 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4329 unit_set = (reserv_sets_t) obstack_base (&irp);
4330 obstack_finish (&irp);
4331 memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4332 for (el = decl->decl.unit.absence_list;
4334 el = el->next_unit_set_el)
4335 SET_BIT (unit_set, el->unit_decl->unit_num);
4336 unit_absence_set_table [decl->decl.unit.unit_num] = unit_set;
4341 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4342 ABSENCE_SET which is union of corresponding sets for each unit in
4344 static reserv_sets_t
4345 get_presence_absence_set (in_set, presence_p)
4346 reserv_sets_t in_set;
4355 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4357 memset (presence_set, 0, chars_num);
4359 memset (absence_set, 0, chars_num);
4360 for (char_num = 0; char_num < chars_num; char_num++)
4361 if (((unsigned char *) in_set) [char_num])
4362 for (i = CHAR_BIT - 1; i >= 0; i--)
4363 if ((((unsigned char *) in_set) [char_num] >> i) & 1)
4365 start_unit_num = char_num * CHAR_BIT + i;
4366 if (start_unit_num >= description->units_num)
4367 return (presence_p ? presence_set : absence_set);
4368 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4370 presence_set [unit_num]
4371 |= unit_presence_set_table [start_unit_num] [unit_num];
4373 absence_set [unit_num]
4374 |= unit_absence_set_table [start_unit_num] [unit_num];
4376 return (presence_p ? presence_set : absence_set);
4381 /* This page contains code for transformation of original reservations
4382 described in .md file. The main goal of transformations is
4383 simplifying reservation and lifting up all `|' on the top of IR
4384 reservation representation. */
4387 /* The following function makes copy of IR representation of
4388 reservation. The function also substitutes all reservations
4389 defined by define_reservation by corresponding value during making
4392 copy_insn_regexp (regexp)
4398 if (regexp->mode == rm_reserv)
4399 result = copy_insn_regexp (regexp->regexp.reserv.reserv_decl->regexp);
4400 else if (regexp->mode == rm_unit)
4401 result = copy_node (regexp, sizeof (struct regexp));
4402 else if (regexp->mode == rm_repeat)
4404 result = copy_node (regexp, sizeof (struct regexp));
4405 result->regexp.repeat.regexp
4406 = copy_insn_regexp (regexp->regexp.repeat.regexp);
4408 else if (regexp->mode == rm_sequence)
4410 result = copy_node (regexp,
4411 sizeof (struct regexp) + sizeof (regexp_t)
4412 * (regexp->regexp.sequence.regexps_num - 1));
4413 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4414 result->regexp.sequence.regexps [i]
4415 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4417 else if (regexp->mode == rm_allof)
4419 result = copy_node (regexp,
4420 sizeof (struct regexp) + sizeof (regexp_t)
4421 * (regexp->regexp.allof.regexps_num - 1));
4422 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4423 result->regexp.allof.regexps [i]
4424 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4426 else if (regexp->mode == rm_oneof)
4428 result = copy_node (regexp,
4429 sizeof (struct regexp) + sizeof (regexp_t)
4430 * (regexp->regexp.oneof.regexps_num - 1));
4431 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4432 result->regexp.oneof.regexps [i]
4433 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4437 if (regexp->mode != rm_nothing)
4439 result = copy_node (regexp, sizeof (struct regexp));
4444 /* The following variable is set up 1 if a transformation has been
4446 static int regexp_transformed_p;
4448 /* The function makes transformation
4451 transform_1 (regexp)
4459 if (regexp->mode == rm_repeat)
4461 repeat_num = regexp->regexp.repeat.repeat_num;
4462 if (repeat_num <= 1)
4464 operand = regexp->regexp.repeat.regexp;
4466 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4467 * (repeat_num - 1));
4468 regexp->mode = rm_sequence;
4470 regexp->regexp.sequence.regexps_num = repeat_num;
4471 for (i = 0; i < repeat_num; i++)
4472 regexp->regexp.sequence.regexps [i] = copy_insn_regexp (operand);
4473 regexp_transformed_p = 1;
4478 /* The function makes transformations
4479 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4480 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4481 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4483 transform_2 (regexp)
4486 if (regexp->mode == rm_sequence)
4493 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4494 if (regexp->regexp.sequence.regexps [i]->mode == rm_sequence)
4497 sequence = regexp->regexp.sequence.regexps [i];
4500 if (i < regexp->regexp.sequence.regexps_num)
4502 if (sequence->regexp.sequence.regexps_num <= 1
4503 || regexp->regexp.sequence.regexps_num <= 1)
4505 result = create_node (sizeof (struct regexp)
4507 * (regexp->regexp.sequence.regexps_num
4508 + sequence->regexp.sequence.regexps_num
4510 result->mode = rm_sequence;
4511 result->pos = regexp->pos;
4512 result->regexp.sequence.regexps_num
4513 = (regexp->regexp.sequence.regexps_num
4514 + sequence->regexp.sequence.regexps_num - 1);
4515 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4516 if (i < sequence_index)
4517 result->regexp.sequence.regexps [i]
4518 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4519 else if (i > sequence_index)
4520 result->regexp.sequence.regexps
4521 [i + sequence->regexp.sequence.regexps_num - 1]
4522 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4524 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4525 result->regexp.sequence.regexps [i + j]
4526 = copy_insn_regexp (sequence->regexp.sequence.regexps [j]);
4527 regexp_transformed_p = 1;
4531 else if (regexp->mode == rm_allof)
4538 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4539 if (regexp->regexp.allof.regexps [i]->mode == rm_allof)
4542 allof = regexp->regexp.allof.regexps [i];
4545 if (i < regexp->regexp.allof.regexps_num)
4547 if (allof->regexp.allof.regexps_num <= 1
4548 || regexp->regexp.allof.regexps_num <= 1)
4550 result = create_node (sizeof (struct regexp)
4552 * (regexp->regexp.allof.regexps_num
4553 + allof->regexp.allof.regexps_num - 2));
4554 result->mode = rm_allof;
4555 result->pos = regexp->pos;
4556 result->regexp.allof.regexps_num
4557 = (regexp->regexp.allof.regexps_num
4558 + allof->regexp.allof.regexps_num - 1);
4559 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4560 if (i < allof_index)
4561 result->regexp.allof.regexps [i]
4562 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4563 else if (i > allof_index)
4564 result->regexp.allof.regexps
4565 [i + allof->regexp.allof.regexps_num - 1]
4566 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4568 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4569 result->regexp.allof.regexps [i + j]
4570 = copy_insn_regexp (allof->regexp.allof.regexps [j]);
4571 regexp_transformed_p = 1;
4575 else if (regexp->mode == rm_oneof)
4582 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4583 if (regexp->regexp.oneof.regexps [i]->mode == rm_oneof)
4586 oneof = regexp->regexp.oneof.regexps [i];
4589 if (i < regexp->regexp.oneof.regexps_num)
4591 if (oneof->regexp.oneof.regexps_num <= 1
4592 || regexp->regexp.oneof.regexps_num <= 1)
4594 result = create_node (sizeof (struct regexp)
4596 * (regexp->regexp.oneof.regexps_num
4597 + oneof->regexp.oneof.regexps_num - 2));
4598 result->mode = rm_oneof;
4599 result->pos = regexp->pos;
4600 result->regexp.oneof.regexps_num
4601 = (regexp->regexp.oneof.regexps_num
4602 + oneof->regexp.oneof.regexps_num - 1);
4603 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4604 if (i < oneof_index)
4605 result->regexp.oneof.regexps [i]
4606 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4607 else if (i > oneof_index)
4608 result->regexp.oneof.regexps
4609 [i + oneof->regexp.oneof.regexps_num - 1]
4610 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4612 for (j = 0; j < oneof->regexp.oneof.regexps_num; j++)
4613 result->regexp.oneof.regexps [i + j]
4614 = copy_insn_regexp (oneof->regexp.oneof.regexps [j]);
4615 regexp_transformed_p = 1;
4622 /* The function makes transformations
4623 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4624 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|... */
4626 transform_3 (regexp)
4629 if (regexp->mode == rm_sequence)
4637 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4638 if (regexp->regexp.sequence.regexps [i]->mode == rm_oneof)
4641 oneof = regexp->regexp.sequence.regexps [i];
4644 if (i < regexp->regexp.sequence.regexps_num)
4646 if (oneof->regexp.oneof.regexps_num <= 1
4647 || regexp->regexp.sequence.regexps_num <= 1)
4649 result = create_node (sizeof (struct regexp)
4651 * (oneof->regexp.oneof.regexps_num - 1));
4652 result->mode = rm_oneof;
4653 result->pos = regexp->pos;
4654 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4655 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4658 = create_node (sizeof (struct regexp)
4660 * (regexp->regexp.sequence.regexps_num - 1));
4661 sequence->mode = rm_sequence;
4662 sequence->pos = regexp->pos;
4663 sequence->regexp.sequence.regexps_num
4664 = regexp->regexp.sequence.regexps_num;
4665 result->regexp.oneof.regexps [i] = sequence;
4666 for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4667 if (j != oneof_index)
4668 sequence->regexp.sequence.regexps [j]
4669 = copy_insn_regexp (regexp->regexp.sequence.regexps [j]);
4671 sequence->regexp.sequence.regexps [j]
4672 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4674 regexp_transformed_p = 1;
4678 else if (regexp->mode == rm_allof)
4686 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4687 if (regexp->regexp.allof.regexps [i]->mode == rm_oneof)
4690 oneof = regexp->regexp.allof.regexps [i];
4693 if (i < regexp->regexp.allof.regexps_num)
4695 if (oneof->regexp.oneof.regexps_num <= 1
4696 || regexp->regexp.allof.regexps_num <= 1)
4698 result = create_node (sizeof (struct regexp)
4700 * (oneof->regexp.oneof.regexps_num - 1));
4701 result->mode = rm_oneof;
4702 result->pos = regexp->pos;
4703 result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4704 for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4707 = create_node (sizeof (struct regexp)
4709 * (regexp->regexp.allof.regexps_num - 1));
4710 allof->mode = rm_allof;
4711 allof->pos = regexp->pos;
4712 allof->regexp.allof.regexps_num
4713 = regexp->regexp.allof.regexps_num;
4714 result->regexp.oneof.regexps [i] = allof;
4715 for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4716 if (j != oneof_index)
4717 allof->regexp.allof.regexps [j]
4718 = copy_insn_regexp (regexp->regexp.allof.regexps [j]);
4720 allof->regexp.allof.regexps [j]
4721 = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4723 regexp_transformed_p = 1;
4730 /* The function traverses IR of reservation and applies transformations
4731 implemented by FUNC. */
4733 regexp_transform_func (regexp, func)
4735 regexp_t (*func) PARAMS ((regexp_t regexp));
4739 if (regexp->mode == rm_sequence)
4740 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4741 regexp->regexp.sequence.regexps [i]
4742 = regexp_transform_func (regexp->regexp.sequence.regexps [i], func);
4743 else if (regexp->mode == rm_allof)
4744 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4745 regexp->regexp.allof.regexps [i]
4746 = regexp_transform_func (regexp->regexp.allof.regexps [i], func);
4747 else if (regexp->mode == rm_oneof)
4748 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4749 regexp->regexp.oneof.regexps [i]
4750 = regexp_transform_func (regexp->regexp.oneof.regexps [i], func);
4751 else if (regexp->mode == rm_repeat)
4752 regexp->regexp.repeat.regexp
4753 = regexp_transform_func (regexp->regexp.repeat.regexp, func);
4754 else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
4756 return (*func) (regexp);
4759 /* The function applies all transformations for IR representation of
4760 reservation REGEXP. */
4762 transform_regexp (regexp)
4765 regexp = regexp_transform_func (regexp, transform_1);
4768 regexp_transformed_p = 0;
4769 regexp = regexp_transform_func (regexp, transform_2);
4770 regexp = regexp_transform_func (regexp, transform_3);
4772 while (regexp_transformed_p);
4776 /* The function applys all transformations for reservations of all
4777 insn declarations. */
4779 transform_insn_regexps ()
4784 for (i = 0; i < description->decls_num; i++)
4786 decl = description->decls [i];
4787 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4788 decl->decl.insn_reserv.transformed_regexp
4789 = transform_regexp (copy_insn_regexp
4790 (decl->decl.insn_reserv.regexp));
4796 /* The page contains code for building alt_states (see comments for
4797 IR) describing all possible insns reservations of an automaton. */
4799 /* Current state being formed for which the current alt_state
4801 static state_t state_being_formed;
4803 /* Current alt_state being formed. */
4804 static alt_state_t alt_state_being_formed;
4806 /* This recursive function processes `,' and units in reservation
4807 REGEXP for forming alt_states of AUTOMATON. It is believed that
4808 CURR_CYCLE is start cycle of all reservation REGEXP. */
4810 process_seq_for_forming_states (regexp, automaton, curr_cycle)
4812 automaton_t automaton;
4819 else if (regexp->mode == rm_unit)
4821 if (regexp->regexp.unit.unit_decl->corresponding_automaton_num
4822 == automaton->automaton_order_num)
4823 set_state_reserv (state_being_formed, curr_cycle,
4824 regexp->regexp.unit.unit_decl->unit_num);
4827 else if (regexp->mode == rm_sequence)
4829 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4831 = process_seq_for_forming_states
4832 (regexp->regexp.sequence.regexps [i], automaton, curr_cycle) + 1;
4835 else if (regexp->mode == rm_allof)
4837 int finish_cycle = 0;
4840 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4843 = process_seq_for_forming_states (regexp->regexp.allof.regexps [i],
4844 automaton, curr_cycle);
4845 if (finish_cycle < cycle)
4846 finish_cycle = cycle;
4848 return finish_cycle;
4852 if (regexp->mode != rm_nothing)
4858 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
4859 inserts alt_state into the table. */
4861 finish_forming_alt_state (alt_state, automaton)
4862 alt_state_t alt_state;
4863 automaton_t automaton ATTRIBUTE_UNUSED;
4865 state_t state_in_table;
4866 state_t corresponding_state;
4868 corresponding_state = alt_state->state;
4869 state_in_table = insert_state (corresponding_state);
4870 if (state_in_table != corresponding_state)
4872 free_state (corresponding_state);
4873 alt_state->state = state_in_table;
4877 /* The following variable value is current automaton insn for whose
4878 reservation the alt states are created. */
4879 static ainsn_t curr_ainsn;
4881 /* This recursive function processes `|' in reservation REGEXP for
4882 forming alt_states of AUTOMATON. List of the alt states should
4883 have the same order as in the description. */
4885 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
4887 automaton_t automaton;
4892 if (regexp->mode != rm_oneof)
4894 alt_state_being_formed = get_free_alt_state ();
4895 state_being_formed = get_free_state (1, automaton);
4896 alt_state_being_formed->state = state_being_formed;
4897 /* We inserts in reverse order but we process alternatives also
4898 in reverse order. So we have the same order of alternative
4899 as in the description. */
4900 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
4901 curr_ainsn->alt_states = alt_state_being_formed;
4902 (void) process_seq_for_forming_states (regexp, automaton, 0);
4903 finish_forming_alt_state (alt_state_being_formed, automaton);
4909 /* We processes it in reverse order to get list with the same
4910 order as in the description. See also the previous
4912 for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4913 process_alts_for_forming_states (regexp->regexp.oneof.regexps [i],
4918 /* Create nodes alt_state for all AUTOMATON insns. */
4920 create_alt_states (automaton)
4921 automaton_t automaton;
4923 struct insn_reserv_decl *reserv_decl;
4925 for (curr_ainsn = automaton->ainsn_list;
4927 curr_ainsn = curr_ainsn->next_ainsn)
4929 reserv_decl = curr_ainsn->insn_reserv_decl;
4930 if (reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
4932 curr_ainsn->alt_states = NULL;
4933 process_alts_for_forming_states (reserv_decl->transformed_regexp,
4935 curr_ainsn->sorted_alt_states
4936 = uniq_sort_alt_states (curr_ainsn->alt_states);
4943 /* The page contains major code for building DFA(s) for fast pipeline
4944 hazards recognition. */
4946 /* The function forms list of ainsns of AUTOMATON with the same
4949 form_ainsn_with_same_reservs (automaton)
4950 automaton_t automaton;
4954 vla_ptr_t first_insns;
4955 vla_ptr_t last_insns;
4957 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
4958 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
4959 for (curr_ainsn = automaton->ainsn_list;
4961 curr_ainsn = curr_ainsn->next_ainsn)
4962 if (curr_ainsn->insn_reserv_decl
4963 == &advance_cycle_insn_decl->decl.insn_reserv)
4965 curr_ainsn->next_same_reservs_insn = NULL;
4966 curr_ainsn->first_insn_with_same_reservs = 1;
4970 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
4972 (curr_ainsn->sorted_alt_states,
4973 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
4975 curr_ainsn->next_same_reservs_insn = NULL;
4976 if (i < VLA_PTR_LENGTH (first_insns))
4978 curr_ainsn->first_insn_with_same_reservs = 0;
4979 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
4981 VLA_PTR (last_insns, i) = curr_ainsn;
4985 VLA_PTR_ADD (first_insns, curr_ainsn);
4986 VLA_PTR_ADD (last_insns, curr_ainsn);
4987 curr_ainsn->first_insn_with_same_reservs = 1;
4990 VLA_PTR_DELETE (first_insns);
4991 VLA_PTR_DELETE (last_insns);
4994 /* The following function creates all states of nondeterministic (if
4995 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
4997 make_automaton (automaton)
4998 automaton_t automaton;
5001 struct insn_reserv_decl *insn_reserv_decl;
5002 alt_state_t alt_state;
5004 state_t start_state;
5006 ainsn_t advance_cycle_ainsn;
5008 vla_ptr_t state_stack;
5010 VLA_PTR_CREATE (state_stack, 150, "state stack");
5011 /* Create the start state (empty state). */
5012 start_state = insert_state (get_free_state (1, automaton));
5013 automaton->start_state = start_state;
5014 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5015 VLA_PTR_ADD (state_stack, start_state);
5016 while (VLA_PTR_LENGTH (state_stack) != 0)
5018 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5019 VLA_PTR_SHORTEN (state_stack, 1);
5020 advance_cycle_ainsn = NULL;
5021 for (ainsn = automaton->ainsn_list;
5023 ainsn = ainsn->next_ainsn)
5024 if (ainsn->first_insn_with_same_reservs)
5026 insn_reserv_decl = ainsn->insn_reserv_decl;
5027 if (insn_reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5029 /* We process alt_states in the same order as they are
5030 present in the description. */
5032 for (alt_state = ainsn->alt_states;
5034 alt_state = alt_state->next_alt_state)
5036 state2 = alt_state->state;
5037 if (!intersected_state_reservs_p (state, state2))
5039 state2 = states_union (state, state2);
5040 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5042 state2->it_was_placed_in_stack_for_NDFA_forming
5044 VLA_PTR_ADD (state_stack, state2);
5046 added_arc = add_arc (state, state2, ainsn, 1);
5051 if (!ndfa_flag && added_arc != NULL)
5053 added_arc->state_alts = 0;
5054 for (alt_state = ainsn->alt_states;
5056 alt_state = alt_state->next_alt_state)
5058 state2 = alt_state->state;
5059 if (!intersected_state_reservs_p (state, state2))
5060 added_arc->state_alts++;
5065 advance_cycle_ainsn = ainsn;
5067 /* Add transition to advance cycle. */
5068 state2 = state_shift (state);
5069 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5071 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5072 VLA_PTR_ADD (state_stack, state2);
5074 if (advance_cycle_ainsn == NULL)
5076 add_arc (state, state2, advance_cycle_ainsn, 1);
5078 VLA_PTR_DELETE (state_stack);
5081 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5083 form_arcs_marked_by_insn (state)
5090 for (i = 0; i < description->decls_num; i++)
5092 decl = description->decls [i];
5093 if (decl->mode == dm_insn_reserv)
5094 decl->decl.insn_reserv.arcs_marked_by_insn = NULL;
5096 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5098 if (arc->insn == NULL)
5100 arc->next_arc_marked_by_insn
5101 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5102 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5106 /* The function creates composed state (see comments for IR) from
5107 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5108 same insn. If the composed state is not in STATE_STACK yet, it is
5109 popped to STATE_STACK. */
5111 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5112 state_t original_state;
5113 arc_t arcs_marked_by_insn;
5114 vla_ptr_t *state_stack;
5117 alt_state_t curr_alt_state;
5118 alt_state_t new_alt_state;
5121 state_t state_in_table;
5123 alt_state_t canonical_alt_states_list;
5126 if (arcs_marked_by_insn == NULL)
5128 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5129 state = arcs_marked_by_insn->to_state;
5134 /* Create composed state. */
5135 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5136 curr_alt_state = NULL;
5137 for (curr_arc = arcs_marked_by_insn;
5139 curr_arc = curr_arc->next_arc_marked_by_insn)
5141 new_alt_state = get_free_alt_state ();
5142 new_alt_state->next_alt_state = curr_alt_state;
5143 new_alt_state->state = curr_arc->to_state;
5144 if (curr_arc->to_state->component_states != NULL)
5146 curr_alt_state = new_alt_state;
5148 /* There are not identical sets in the alt state list. */
5149 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5150 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5153 state = canonical_alt_states_list->state;
5154 free_state (temp_state);
5158 state->component_states = canonical_alt_states_list;
5159 state_in_table = insert_state (state);
5160 if (state_in_table != state)
5162 if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5165 state = state_in_table;
5169 if (state->it_was_placed_in_stack_for_DFA_forming)
5171 for (curr_alt_state = state->component_states;
5172 curr_alt_state != NULL;
5173 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5174 for (curr_arc = first_out_arc (curr_alt_state->state);
5176 curr_arc = next_out_arc (curr_arc))
5177 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5179 arcs_marked_by_insn->to_state = state;
5180 for (alts_number = 0,
5181 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5183 curr_arc = next_arc)
5185 next_arc = curr_arc->next_arc_marked_by_insn;
5186 remove_arc (original_state, curr_arc);
5189 arcs_marked_by_insn->state_alts = alts_number;
5192 if (!state->it_was_placed_in_stack_for_DFA_forming)
5194 state->it_was_placed_in_stack_for_DFA_forming = 1;
5195 VLA_PTR_ADD (*state_stack, state);
5199 /* The function transformes nondeterminstic AUTOMATON into
5202 NDFA_to_DFA (automaton)
5203 automaton_t automaton;
5205 state_t start_state;
5208 vla_ptr_t state_stack;
5211 VLA_PTR_CREATE (state_stack, 150, "state stack");
5212 /* Create the start state (empty state). */
5213 start_state = automaton->start_state;
5214 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5215 VLA_PTR_ADD (state_stack, start_state);
5216 while (VLA_PTR_LENGTH (state_stack) != 0)
5218 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5219 VLA_PTR_SHORTEN (state_stack, 1);
5220 form_arcs_marked_by_insn (state);
5221 for (i = 0; i < description->decls_num; i++)
5223 decl = description->decls [i];
5224 if (decl->mode == dm_insn_reserv)
5225 create_composed_state
5226 (state, decl->decl.insn_reserv.arcs_marked_by_insn,
5230 VLA_PTR_DELETE (state_stack);
5233 /* The following variable value is current number (1, 2, ...) of passing
5235 static int curr_state_graph_pass_num;
5237 /* This recursive function passes all states achieved from START_STATE
5238 and applies APPLIED_FUNC to them. */
5240 pass_state_graph (start_state, applied_func)
5241 state_t start_state;
5242 void (*applied_func) PARAMS ((state_t state));
5246 if (start_state->pass_num == curr_state_graph_pass_num)
5248 start_state->pass_num = curr_state_graph_pass_num;
5249 (*applied_func) (start_state);
5250 for (arc = first_out_arc (start_state);
5252 arc = next_out_arc (arc))
5253 pass_state_graph (arc->to_state, applied_func);
5256 /* This recursive function passes all states of AUTOMATON and applies
5257 APPLIED_FUNC to them. */
5259 pass_states (automaton, applied_func)
5260 automaton_t automaton;
5261 void (*applied_func) PARAMS ((state_t state));
5263 curr_state_graph_pass_num++;
5264 pass_state_graph (automaton->start_state, applied_func);
5267 /* The function initializes code for passing of all states. */
5269 initiate_pass_states ()
5271 curr_state_graph_pass_num = 0;
5274 /* The following vla is used for storing pointers to all achieved
5276 static vla_ptr_t all_achieved_states;
5278 /* This function is called by function pass_states to add an achieved
5281 add_achieved_state (state)
5284 VLA_PTR_ADD (all_achieved_states, state);
5287 /* The function sets up equivalence numbers of insns which mark all
5288 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5289 nonzero value) or by equiv_class_num_2 of the destination state.
5290 The function returns number of out arcs of STATE. */
5292 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
5294 int odd_iteration_flag;
5296 int state_out_arcs_num;
5299 state_out_arcs_num = 0;
5300 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5302 if (arc->insn->insn_reserv_decl->equiv_class_num != 0
5303 || arc->insn->insn_reserv_decl->state_alts != 0)
5305 state_out_arcs_num++;
5306 arc->insn->insn_reserv_decl->equiv_class_num
5307 = (odd_iteration_flag
5308 ? arc->to_state->equiv_class_num_1
5309 : arc->to_state->equiv_class_num_2);
5310 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5311 if (arc->insn->insn_reserv_decl->equiv_class_num == 0
5312 || arc->insn->insn_reserv_decl->state_alts <= 0)
5315 return state_out_arcs_num;
5318 /* The function clears equivalence numbers and alt_states in all insns
5319 which mark all out arcs of STATE. */
5321 clear_arc_insns_equiv_num (state)
5326 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5328 arc->insn->insn_reserv_decl->equiv_class_num = 0;
5329 arc->insn->insn_reserv_decl->state_alts = 0;
5333 /* The function copies pointers to equivalent states from vla FROM
5336 copy_equiv_class (to, from)
5338 const vla_ptr_t *from;
5342 VLA_PTR_NULLIFY (*to);
5343 for (class_ptr = VLA_PTR_BEGIN (*from);
5344 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
5346 VLA_PTR_ADD (*to, *class_ptr);
5349 /* The function returns nonzero value if STATE is not equivalent to
5350 another state from the same current partition on equivalence
5351 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5352 output arcs. Iteration of making equivalence partition is defined
5353 by ODD_ITERATION_FLAG. */
5355 state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
5357 int original_state_out_arcs_num;
5358 int odd_iteration_flag;
5361 int state_out_arcs_num;
5363 state_out_arcs_num = 0;
5364 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5366 state_out_arcs_num++;
5367 if ((odd_iteration_flag
5368 ? arc->to_state->equiv_class_num_1
5369 : arc->to_state->equiv_class_num_2)
5370 != arc->insn->insn_reserv_decl->equiv_class_num
5371 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
5374 return state_out_arcs_num != original_state_out_arcs_num;
5377 /* The function makes initial partition of STATES on equivalent
5380 init_equiv_class (states, states_num)
5385 state_t result_equiv_class;
5387 result_equiv_class = NULL;
5388 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
5390 (*state_ptr)->equiv_class_num_1 = 1;
5391 (*state_ptr)->next_equiv_class_state = result_equiv_class;
5392 result_equiv_class = *state_ptr;
5394 return result_equiv_class;
5397 /* The function processes equivalence class given by its pointer
5398 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5399 are not equvalent states, the function partitions the class
5400 removing nonequivalent states and placing them in
5401 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5402 assigns it to the state equivalence number. If the class has been
5403 partitioned, the function returns nonzero value. */
5405 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5406 next_iteration_classes, new_equiv_class_num_ptr)
5407 state_t *equiv_class_ptr;
5408 int odd_iteration_flag;
5409 vla_ptr_t *next_iteration_classes;
5410 int *new_equiv_class_num_ptr;
5412 state_t new_equiv_class;
5414 state_t first_state;
5421 if (*equiv_class_ptr == NULL)
5423 for (first_state = *equiv_class_ptr;
5424 first_state != NULL;
5425 first_state = new_equiv_class)
5427 new_equiv_class = NULL;
5428 if (first_state->next_equiv_class_state != NULL)
5430 /* There are more one states in the class equivalence. */
5431 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
5432 odd_iteration_flag);
5433 for (prev_state = first_state,
5434 curr_state = first_state->next_equiv_class_state;
5436 curr_state = next_state)
5438 next_state = curr_state->next_equiv_class_state;
5439 if (state_is_differed (curr_state, out_arcs_num,
5440 odd_iteration_flag))
5442 /* Remove curr state from the class equivalence. */
5443 prev_state->next_equiv_class_state = next_state;
5444 /* Add curr state to the new class equivalence. */
5445 curr_state->next_equiv_class_state = new_equiv_class;
5446 if (new_equiv_class == NULL)
5447 (*new_equiv_class_num_ptr)++;
5448 if (odd_iteration_flag)
5449 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5451 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5452 new_equiv_class = curr_state;
5456 prev_state = curr_state;
5458 clear_arc_insns_equiv_num (first_state);
5460 if (new_equiv_class != NULL)
5461 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
5466 /* The function finds equivalent states of AUTOMATON. */
5468 evaluate_equiv_classes (automaton, equiv_classes)
5469 automaton_t automaton;
5470 vla_ptr_t *equiv_classes;
5472 state_t new_equiv_class;
5473 int new_equiv_class_num;
5474 int odd_iteration_flag;
5476 vla_ptr_t next_iteration_classes;
5477 state_t *equiv_class_ptr;
5480 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
5481 pass_states (automaton, add_achieved_state);
5482 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
5483 VLA_PTR_LENGTH (all_achieved_states));
5484 odd_iteration_flag = 0;
5485 new_equiv_class_num = 1;
5486 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
5487 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
5490 odd_iteration_flag = !odd_iteration_flag;
5492 copy_equiv_class (equiv_classes, &next_iteration_classes);
5493 /* Transfer equiv numbers for the next iteration. */
5494 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
5495 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
5497 if (odd_iteration_flag)
5498 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
5500 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
5501 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5502 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5504 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5505 &next_iteration_classes,
5506 &new_equiv_class_num))
5509 while (!finish_flag);
5510 VLA_PTR_DELETE (next_iteration_classes);
5511 VLA_PTR_DELETE (all_achieved_states);
5514 /* The function merges equivalent states of AUTOMATON. */
5516 merge_states (automaton, equiv_classes)
5517 automaton_t automaton;
5518 vla_ptr_t *equiv_classes;
5520 state_t *equiv_class_ptr;
5523 state_t first_class_state;
5524 alt_state_t alt_states;
5525 alt_state_t new_alt_state;
5529 /* Create states corresponding to equivalence classes containing two
5531 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5532 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5534 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5536 /* There are more one states in the class equivalence. */
5537 /* Create new compound state. */
5538 new_state = get_free_state (0, automaton);
5540 first_class_state = *equiv_class_ptr;
5541 for (curr_state = first_class_state;
5543 curr_state = curr_state->next_equiv_class_state)
5545 curr_state->equiv_class_state = new_state;
5546 new_alt_state = get_free_alt_state ();
5547 new_alt_state->state = curr_state;
5548 new_alt_state->next_sorted_alt_state = alt_states;
5549 alt_states = new_alt_state;
5551 new_state->component_states = alt_states;
5554 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
5555 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5556 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5558 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5560 first_class_state = *equiv_class_ptr;
5561 /* Create new arcs output from the state corresponding to
5563 for (curr_arc = first_out_arc (first_class_state);
5565 curr_arc = next_out_arc (curr_arc))
5566 add_arc (first_class_state->equiv_class_state,
5567 curr_arc->to_state->equiv_class_state,
5568 curr_arc->insn, curr_arc->state_alts);
5569 /* Delete output arcs from states of given class equivalence. */
5570 for (curr_state = first_class_state;
5572 curr_state = curr_state->next_equiv_class_state)
5574 if (automaton->start_state == curr_state)
5575 automaton->start_state = curr_state->equiv_class_state;
5576 /* Delete the state and its output arcs. */
5577 for (curr_arc = first_out_arc (curr_state);
5579 curr_arc = next_arc)
5581 next_arc = next_out_arc (curr_arc);
5582 free_arc (curr_arc);
5588 /* Change `to_state' of arcs output from the state of given
5589 equivalence class. */
5590 for (curr_arc = first_out_arc (*equiv_class_ptr);
5592 curr_arc = next_out_arc (curr_arc))
5593 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
5597 /* The function sets up new_cycle_p for states if there is arc to the
5598 state marked by advance_cycle_insn_decl. */
5600 set_new_cycle_flags (state)
5605 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5606 if (arc->insn->insn_reserv_decl
5607 == &advance_cycle_insn_decl->decl.insn_reserv)
5608 arc->to_state->new_cycle_p = 1;
5611 /* The top level function for minimization of deterministic
5614 minimize_DFA (automaton)
5615 automaton_t automaton;
5617 vla_ptr_t equiv_classes;
5619 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
5620 evaluate_equiv_classes (automaton, &equiv_classes);
5621 merge_states (automaton, &equiv_classes);
5622 pass_states (automaton, set_new_cycle_flags);
5623 VLA_PTR_DELETE (equiv_classes);
5626 /* Values of two variables are counted number of states and arcs in an
5628 static int curr_counted_states_num;
5629 static int curr_counted_arcs_num;
5631 /* The function is called by function `pass_states' to count states
5632 and arcs of an automaton. */
5634 incr_states_and_arcs_nums (state)
5639 curr_counted_states_num++;
5640 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5641 curr_counted_arcs_num++;
5644 /* The function counts states and arcs of AUTOMATON. */
5646 count_states_and_arcs (automaton, states_num, arcs_num)
5647 automaton_t automaton;
5651 curr_counted_states_num = 0;
5652 curr_counted_arcs_num = 0;
5653 pass_states (automaton, incr_states_and_arcs_nums);
5654 *states_num = curr_counted_states_num;
5655 *arcs_num = curr_counted_arcs_num;
5658 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5659 recognition after checking and simplifying IR of the
5662 build_automaton (automaton)
5663 automaton_t automaton;
5668 ticker_on (&NDFA_time);
5669 make_automaton (automaton);
5670 ticker_off (&NDFA_time);
5671 count_states_and_arcs (automaton, &states_num, &arcs_num);
5672 automaton->NDFA_states_num = states_num;
5673 automaton->NDFA_arcs_num = arcs_num;
5674 ticker_on (&NDFA_to_DFA_time);
5675 NDFA_to_DFA (automaton);
5676 ticker_off (&NDFA_to_DFA_time);
5677 count_states_and_arcs (automaton, &states_num, &arcs_num);
5678 automaton->DFA_states_num = states_num;
5679 automaton->DFA_arcs_num = arcs_num;
5680 if (!no_minimization_flag)
5682 ticker_on (&minimize_time);
5683 minimize_DFA (automaton);
5684 ticker_off (&minimize_time);
5685 count_states_and_arcs (automaton, &states_num, &arcs_num);
5686 automaton->minimal_DFA_states_num = states_num;
5687 automaton->minimal_DFA_arcs_num = arcs_num;
5693 /* The page contains code for enumeration of all states of an automaton. */
5695 /* Variable used for enumeration of all states of an automaton. Its
5696 value is current number of automaton states. */
5697 static int curr_state_order_num;
5699 /* The function is called by function `pass_states' for enumerating
5702 set_order_state_num (state)
5705 state->order_state_num = curr_state_order_num;
5706 curr_state_order_num++;
5709 /* The function enumerates all states of AUTOMATON. */
5711 enumerate_states (automaton)
5712 automaton_t automaton;
5714 curr_state_order_num = 0;
5715 pass_states (automaton, set_order_state_num);
5716 automaton->achieved_states_num = curr_state_order_num;
5721 /* The page contains code for finding equivalent automaton insns
5724 /* The function inserts AINSN into cyclic list
5725 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
5727 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
5729 ainsn_t cyclic_equiv_class_insn_list;
5731 if (cyclic_equiv_class_insn_list == NULL)
5732 ainsn->next_equiv_class_insn = ainsn;
5735 ainsn->next_equiv_class_insn
5736 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
5737 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
5742 /* The function deletes equiv_class_insn into cyclic list of
5743 equivalent ainsns. */
5745 delete_ainsn_from_equiv_class (equiv_class_insn)
5746 ainsn_t equiv_class_insn;
5748 ainsn_t curr_equiv_class_insn;
5749 ainsn_t prev_equiv_class_insn;
5751 prev_equiv_class_insn = equiv_class_insn;
5752 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
5753 curr_equiv_class_insn != equiv_class_insn;
5754 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
5755 prev_equiv_class_insn = curr_equiv_class_insn;
5756 if (prev_equiv_class_insn != equiv_class_insn)
5757 prev_equiv_class_insn->next_equiv_class_insn
5758 = equiv_class_insn->next_equiv_class_insn;
5761 /* The function processes AINSN of a state in order to find equivalent
5762 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
5765 process_insn_equiv_class (ainsn, insn_arcs_array)
5767 arc_t *insn_arcs_array;
5771 ainsn_t cyclic_insn_list;
5774 if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
5777 /* New class of ainsns which are not equivalent to given ainsn. */
5778 cyclic_insn_list = NULL;
5781 next_insn = curr_insn->next_equiv_class_insn;
5782 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
5784 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
5787 delete_ainsn_from_equiv_class (curr_insn);
5788 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
5791 curr_insn = next_insn;
5793 while (curr_insn != ainsn);
5796 /* The function processes STATE in order to find equivalent ainsns. */
5798 process_state_for_insn_equiv_partition (state)
5802 arc_t *insn_arcs_array;
5804 vla_ptr_t insn_arcs_vect;
5806 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
5807 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
5808 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
5809 /* Process insns of the arcs. */
5810 for (i = 0; i < description->insns_num; i++)
5811 insn_arcs_array [i] = NULL;
5812 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5813 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
5814 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5815 process_insn_equiv_class (arc->insn, insn_arcs_array);
5816 VLA_PTR_DELETE (insn_arcs_vect);
5819 /* The function searches for equivalent ainsns of AUTOMATON. */
5821 set_insn_equiv_classes (automaton)
5822 automaton_t automaton;
5827 ainsn_t cyclic_insn_list;
5828 ainsn_t insn_with_same_reservs;
5829 int equiv_classes_num;
5831 /* All insns are included in one equivalence class. */
5832 cyclic_insn_list = NULL;
5833 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
5834 if (ainsn->first_insn_with_same_reservs)
5835 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
5837 /* Process insns in order to make equivalence partition. */
5838 pass_states (automaton, process_state_for_insn_equiv_partition);
5839 /* Enumerate equiv classes. */
5840 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
5841 /* Set undefined value. */
5842 ainsn->insn_equiv_class_num = -1;
5843 equiv_classes_num = 0;
5844 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
5845 if (ainsn->insn_equiv_class_num < 0)
5848 if (!first_insn->first_insn_with_same_reservs)
5850 first_insn->first_ainsn_with_given_equialence_num = 1;
5851 curr_insn = first_insn;
5854 for (insn_with_same_reservs = curr_insn;
5855 insn_with_same_reservs != NULL;
5856 insn_with_same_reservs
5857 = insn_with_same_reservs->next_same_reservs_insn)
5858 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
5859 curr_insn = curr_insn->next_equiv_class_insn;
5861 while (curr_insn != first_insn);
5862 equiv_classes_num++;
5864 automaton->insn_equiv_classes_num = equiv_classes_num;
5869 /* This page contains code for creating DFA(s) and calls functions
5873 /* The following value is used to prevent floating point overflow for
5874 estimating an automaton bound. The value should be less DBL_MAX on
5875 the host machine. We use here approximate minimum of maximal
5876 double floating point value required by ANSI C standard. It
5877 will work for non ANSI sun compiler too. */
5879 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
5881 /* The function estimate size of the single DFA used by PHR (pipeline
5882 hazards recognizer). */
5884 estimate_one_automaton_bound ()
5887 double one_automaton_estimation_bound;
5891 one_automaton_estimation_bound = 1.0;
5892 for (i = 0; i < description->decls_num; i++)
5894 decl = description->decls [i];
5895 if (decl->mode == dm_unit)
5897 root_value = exp (log (decl->decl.unit.max_occ_cycle_num + 1.0)
5899 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
5900 > one_automaton_estimation_bound)
5901 one_automaton_estimation_bound *= root_value;
5904 return one_automaton_estimation_bound;
5907 /* The function compares unit declarations acoording to their maximal
5908 cycle in reservations. */
5910 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
5911 const void *unit_decl_1;
5912 const void *unit_decl_2;
5914 if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
5915 < ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
5917 else if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
5918 == ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
5924 /* The function makes heuristic assigning automata to units. Actually
5925 efficacy of the algorithm has been checked yet??? */
5927 units_to_automata_heuristic_distr ()
5929 double estimation_bound;
5931 decl_t *unit_decl_ptr;
5935 vla_ptr_t unit_decls;
5938 if (description->units_num == 0)
5940 estimation_bound = estimate_one_automaton_bound ();
5941 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
5942 for (i = 0; i < description->decls_num; i++)
5944 decl = description->decls [i];
5945 if (decl->mode == dm_unit)
5946 VLA_PTR_ADD (unit_decls, decl);
5948 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
5949 sizeof (decl_t), compare_max_occ_cycle_nums);
5951 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
5952 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
5953 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
5954 for (unit_decl_ptr++;
5955 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
5959 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
5960 if (automata_num - automaton_num - 1 > rest_units_num)
5962 if (automaton_num < automata_num - 1
5963 && ((automata_num - automaton_num - 1 == rest_units_num)
5966 / ((*unit_decl_ptr)->decl.unit.max_occ_cycle_num)))))
5968 bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
5972 bound_value *= (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
5973 (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
5975 if (automaton_num != automata_num - 1)
5977 VLA_PTR_DELETE (unit_decls);
5980 /* The functions creates automaton insns for each automata. Automaton
5981 insn is simply insn for given automaton which makes reservation
5982 only of units of the automaton. */
5987 ainsn_t first_ainsn;
5994 for (i = 0; i < description->decls_num; i++)
5996 decl = description->decls [i];
5997 if (decl->mode == dm_insn_reserv)
5999 curr_ainsn = create_node (sizeof (struct ainsn));
6000 curr_ainsn->insn_reserv_decl = &decl->decl.insn_reserv;
6001 curr_ainsn->important_p = FALSE;
6002 curr_ainsn->next_ainsn = NULL;
6003 if (prev_ainsn == NULL)
6004 first_ainsn = curr_ainsn;
6006 prev_ainsn->next_ainsn = curr_ainsn;
6007 prev_ainsn = curr_ainsn;
6013 /* The function assigns automata to units according to constructions
6014 `define_automaton' in the description. */
6016 units_to_automata_distr ()
6021 for (i = 0; i < description->decls_num; i++)
6023 decl = description->decls [i];
6024 if (decl->mode == dm_unit)
6026 if (decl->decl.unit.automaton_decl == NULL
6027 || (decl->decl.unit.automaton_decl->corresponding_automaton
6029 /* Distribute to the first automaton. */
6030 decl->decl.unit.corresponding_automaton_num = 0;
6032 decl->decl.unit.corresponding_automaton_num
6033 = (decl->decl.unit.automaton_decl
6034 ->corresponding_automaton->automaton_order_num);
6039 /* The function creates DFA(s) for fast pipeline hazards recognition
6040 after checking and simplifying IR of the description. */
6044 automaton_t curr_automaton;
6045 automaton_t prev_automaton;
6047 int curr_automaton_num;
6050 if (automata_num != 0)
6052 units_to_automata_heuristic_distr ();
6053 for (prev_automaton = NULL, curr_automaton_num = 0;
6054 curr_automaton_num < automata_num;
6055 curr_automaton_num++, prev_automaton = curr_automaton)
6057 curr_automaton = create_node (sizeof (struct automaton));
6058 curr_automaton->ainsn_list = create_ainsns ();
6059 curr_automaton->corresponding_automaton_decl = NULL;
6060 curr_automaton->next_automaton = NULL;
6061 curr_automaton->automaton_order_num = curr_automaton_num;
6062 if (prev_automaton == NULL)
6063 description->first_automaton = curr_automaton;
6065 prev_automaton->next_automaton = curr_automaton;
6070 curr_automaton_num = 0;
6071 prev_automaton = NULL;
6072 for (i = 0; i < description->decls_num; i++)
6074 decl = description->decls [i];
6075 if (decl->mode == dm_automaton
6076 && decl->decl.automaton.automaton_is_used)
6078 curr_automaton = create_node (sizeof (struct automaton));
6079 curr_automaton->ainsn_list = create_ainsns ();
6080 curr_automaton->corresponding_automaton_decl
6081 = &decl->decl.automaton;
6082 curr_automaton->next_automaton = NULL;
6083 decl->decl.automaton.corresponding_automaton = curr_automaton;
6084 curr_automaton->automaton_order_num = curr_automaton_num;
6085 if (prev_automaton == NULL)
6086 description->first_automaton = curr_automaton;
6088 prev_automaton->next_automaton = curr_automaton;
6089 curr_automaton_num++;
6090 prev_automaton = curr_automaton;
6093 if (curr_automaton_num == 0)
6095 curr_automaton = create_node (sizeof (struct automaton));
6096 curr_automaton->ainsn_list = create_ainsns ();
6097 curr_automaton->corresponding_automaton_decl = NULL;
6098 curr_automaton->next_automaton = NULL;
6099 description->first_automaton = curr_automaton;
6101 units_to_automata_distr ();
6103 NDFA_time = create_ticker ();
6104 ticker_off (&NDFA_time);
6105 NDFA_to_DFA_time = create_ticker ();
6106 ticker_off (&NDFA_to_DFA_time);
6107 minimize_time = create_ticker ();
6108 ticker_off (&minimize_time);
6109 equiv_time = create_ticker ();
6110 ticker_off (&equiv_time);
6111 for (curr_automaton = description->first_automaton;
6112 curr_automaton != NULL;
6113 curr_automaton = curr_automaton->next_automaton)
6115 if (curr_automaton->corresponding_automaton_decl == NULL)
6116 fprintf (stderr, "Create anonymous automaton ...");
6118 fprintf (stderr, "Create automaton `%s'...",
6119 curr_automaton->corresponding_automaton_decl->name);
6120 create_alt_states (curr_automaton);
6121 form_ainsn_with_same_reservs (curr_automaton);
6122 build_automaton (curr_automaton);
6123 enumerate_states (curr_automaton);
6124 ticker_on (&equiv_time);
6125 set_insn_equiv_classes (curr_automaton);
6126 ticker_off (&equiv_time);
6127 fprintf (stderr, "done\n");
6133 /* This page contains code for forming string representation of
6134 regexp. The representation is formed on IR obstack. So you should
6135 not work with IR obstack between regexp_representation and
6136 finish_regexp_representation calls. */
6138 /* This recursive function forms string representation of regexp
6139 (without tailing '\0'). */
6141 form_regexp (regexp)
6146 if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6148 const char *name = (regexp->mode == rm_unit
6149 ? regexp->regexp.unit.name
6150 : regexp->regexp.reserv.name);
6152 obstack_grow (&irp, name, strlen (name));
6154 else if (regexp->mode == rm_sequence)
6155 for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
6158 obstack_1grow (&irp, ',');
6159 form_regexp (regexp->regexp.sequence.regexps [i]);
6161 else if (regexp->mode == rm_allof)
6163 obstack_1grow (&irp, '(');
6164 for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
6167 obstack_1grow (&irp, '+');
6168 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6169 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6170 obstack_1grow (&irp, '(');
6171 form_regexp (regexp->regexp.allof.regexps [i]);
6172 if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6173 || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6174 obstack_1grow (&irp, ')');
6176 obstack_1grow (&irp, ')');
6178 else if (regexp->mode == rm_oneof)
6179 for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
6182 obstack_1grow (&irp, '|');
6183 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6184 obstack_1grow (&irp, '(');
6185 form_regexp (regexp->regexp.oneof.regexps [i]);
6186 if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6187 obstack_1grow (&irp, ')');
6189 else if (regexp->mode == rm_repeat)
6193 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6194 || regexp->regexp.repeat.regexp->mode == rm_allof
6195 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6196 obstack_1grow (&irp, '(');
6197 form_regexp (regexp->regexp.repeat.regexp);
6198 if (regexp->regexp.repeat.regexp->mode == rm_sequence
6199 || regexp->regexp.repeat.regexp->mode == rm_allof
6200 || regexp->regexp.repeat.regexp->mode == rm_oneof)
6201 obstack_1grow (&irp, ')');
6202 sprintf (digits, "*%d", regexp->regexp.repeat.repeat_num);
6203 obstack_grow (&irp, digits, strlen (digits));
6205 else if (regexp->mode == rm_nothing)
6206 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6211 /* The function returns string representation of REGEXP on IR
6214 regexp_representation (regexp)
6217 form_regexp (regexp);
6218 obstack_1grow (&irp, '\0');
6219 return obstack_base (&irp);
6222 /* The function frees memory allocated for last formed string
6223 representation of regexp. */
6225 finish_regexp_representation ()
6227 int length = obstack_object_size (&irp);
6229 obstack_blank_fast (&irp, -length);
6234 /* This page contains code for output PHR (pipeline hazards recognizer). */
6236 /* The function outputs minimal C type which is sufficient for
6237 representation numbers in range min_range_value and
6238 max_range_value. Because host machine and build machine may be
6239 different, we use here minimal values required by ANSI C standard
6240 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6244 output_range_type (f, min_range_value, max_range_value)
6246 long int min_range_value;
6247 long int max_range_value;
6249 if (min_range_value >= 0 && max_range_value <= 255)
6250 fprintf (f, "unsigned char");
6251 else if (min_range_value >= -127 && max_range_value <= 127)
6252 fprintf (f, "signed char");
6253 else if (min_range_value >= 0 && max_range_value <= 65535)
6254 fprintf (f, "unsigned short");
6255 else if (min_range_value >= -32767 && max_range_value <= 32767)
6256 fprintf (f, "short");
6261 /* The following macro value is used as value of member
6262 `longest_path_length' of state when we are processing path and the
6263 state on the path. */
6265 #define ON_THE_PATH -2
6267 /* The following recursive function searches for the length of the
6268 longest path starting from STATE which does not contain cycles and
6269 `cycle advance' arcs. */
6272 longest_path_length (state)
6278 if (state->longest_path_length == ON_THE_PATH)
6279 /* We don't expect the path cycle here. Our graph may contain
6280 only cycles with one state on the path not containing `cycle
6281 advance' arcs -- see comment below. */
6283 else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6284 /* We alreday visited the state. */
6285 return state->longest_path_length;
6288 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6289 /* Ignore cycles containing one state and `cycle advance' arcs. */
6290 if (arc->to_state != state
6291 && (arc->insn->insn_reserv_decl
6292 != &advance_cycle_insn_decl->decl.insn_reserv))
6294 length = longest_path_length (arc->to_state);
6295 if (length > result)
6298 state->longest_path_length = result + 1;
6302 /* The following variable value is value of the corresponding global
6303 variable in the automaton based pipeline interface. */
6305 static int max_dfa_issue_rate;
6307 /* The following function processes the longest path length staring
6308 from STATE to find MAX_DFA_ISSUE_RATE. */
6311 process_state_longest_path_length (state)
6316 value = longest_path_length (state);
6317 if (value > max_dfa_issue_rate)
6318 max_dfa_issue_rate = value;
6321 /* The following nacro value is name of the corresponding global
6322 variable in the automaton based pipeline interface. */
6324 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6326 /* The following function calculates value of the the corresponding
6327 global variable and outputs its declaration. */
6330 output_dfa_max_issue_rate ()
6332 automaton_t automaton;
6334 if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
6336 max_dfa_issue_rate = 0;
6337 for (automaton = description->first_automaton;
6339 automaton = automaton->next_automaton)
6340 pass_states (automaton, process_state_longest_path_length);
6341 fprintf (output_file, "\nint %s = %d;\n",
6342 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
6345 /* The function outputs all initialization values of VECT with length
6348 output_vect (vect, vect_length)
6355 if (vect_length == 0)
6356 fprintf (output_file,
6357 "0 /* This is dummy el because the vect is empty */");
6362 fprintf (output_file, "%5ld", (long) *vect);
6364 if (els_on_line == 10)
6367 fprintf (output_file, ",\n");
6369 else if (vect_length != 0)
6370 fprintf (output_file, ", ");
6374 while (vect_length != 0);
6378 /* The following is name of the structure which represents DFA(s) for
6380 #define CHIP_NAME "DFA_chip"
6382 /* The following is name of member which represents state of a DFA for
6385 output_chip_member_name (f, automaton)
6387 automaton_t automaton;
6389 if (automaton->corresponding_automaton_decl == NULL)
6390 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6392 fprintf (f, "%s_automaton_state",
6393 automaton->corresponding_automaton_decl->name);
6396 /* The following is name of temporary variable which stores state of a
6399 output_temp_chip_member_name (f, automaton)
6401 automaton_t automaton;
6404 output_chip_member_name (f, automaton);
6407 /* This is name of macro value which is code of pseudo_insn
6408 representing advancing cpu cycle. Its value is used as internal
6409 code unknown insn. */
6410 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6412 /* Output name of translate vector for given automaton. */
6414 output_translate_vect_name (f, automaton)
6416 automaton_t automaton;
6418 if (automaton->corresponding_automaton_decl == NULL)
6419 fprintf (f, "translate_%d", automaton->automaton_order_num);
6421 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6424 /* Output name for simple transition table representation. */
6426 output_trans_full_vect_name (f, automaton)
6428 automaton_t automaton;
6430 if (automaton->corresponding_automaton_decl == NULL)
6431 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6433 fprintf (f, "%s_transitions",
6434 automaton->corresponding_automaton_decl->name);
6437 /* Output name of comb vector of the transition table for given
6440 output_trans_comb_vect_name (f, automaton)
6442 automaton_t automaton;
6444 if (automaton->corresponding_automaton_decl == NULL)
6445 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6447 fprintf (f, "%s_transitions",
6448 automaton->corresponding_automaton_decl->name);
6451 /* Output name of check vector of the transition table for given
6454 output_trans_check_vect_name (f, automaton)
6456 automaton_t automaton;
6458 if (automaton->corresponding_automaton_decl == NULL)
6459 fprintf (f, "check_%d", automaton->automaton_order_num);
6461 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6464 /* Output name of base vector of the transition table for given
6467 output_trans_base_vect_name (f, automaton)
6469 automaton_t automaton;
6471 if (automaton->corresponding_automaton_decl == NULL)
6472 fprintf (f, "base_%d", automaton->automaton_order_num);
6474 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6477 /* Output name for simple alternatives number representation. */
6479 output_state_alts_full_vect_name (f, automaton)
6481 automaton_t automaton;
6483 if (automaton->corresponding_automaton_decl == NULL)
6484 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6486 fprintf (f, "%s_state_alts",
6487 automaton->corresponding_automaton_decl->name);
6490 /* Output name of comb vector of the alternatives number table for given
6493 output_state_alts_comb_vect_name (f, automaton)
6495 automaton_t automaton;
6497 if (automaton->corresponding_automaton_decl == NULL)
6498 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6500 fprintf (f, "%s_state_alts",
6501 automaton->corresponding_automaton_decl->name);
6504 /* Output name of check vector of the alternatives number table for given
6507 output_state_alts_check_vect_name (f, automaton)
6509 automaton_t automaton;
6511 if (automaton->corresponding_automaton_decl == NULL)
6512 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
6514 fprintf (f, "%s_check_state_alts",
6515 automaton->corresponding_automaton_decl->name);
6518 /* Output name of base vector of the alternatives number table for given
6521 output_state_alts_base_vect_name (f, automaton)
6523 automaton_t automaton;
6525 if (automaton->corresponding_automaton_decl == NULL)
6526 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
6528 fprintf (f, "%s_base_state_alts",
6529 automaton->corresponding_automaton_decl->name);
6532 /* Output name of simple min issue delay table representation. */
6534 output_min_issue_delay_vect_name (f, automaton)
6536 automaton_t automaton;
6538 if (automaton->corresponding_automaton_decl == NULL)
6539 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6541 fprintf (f, "%s_min_issue_delay",
6542 automaton->corresponding_automaton_decl->name);
6545 /* Output name of deadlock vector for given automaton. */
6547 output_dead_lock_vect_name (f, automaton)
6549 automaton_t automaton;
6551 if (automaton->corresponding_automaton_decl == NULL)
6552 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6554 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6557 /* Output name of reserved units table for AUTOMATON into file F. */
6559 output_reserved_units_table_name (f, automaton)
6561 automaton_t automaton;
6563 if (automaton->corresponding_automaton_decl == NULL)
6564 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6566 fprintf (f, "%s_reserved_units",
6567 automaton->corresponding_automaton_decl->name);
6570 /* Name of the PHR interface macro. */
6571 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6573 /* Name of the PHR interface macro. */
6574 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6576 /* Names of an internal functions: */
6577 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6579 /* This is external type of DFA(s) state. */
6580 #define STATE_TYPE_NAME "state_t"
6582 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6584 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6586 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6588 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6590 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6592 /* Name of cache of insn dfa codes. */
6593 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6595 /* Name of length of cache of insn dfa codes. */
6596 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6598 /* Names of the PHR interface functions: */
6599 #define SIZE_FUNC_NAME "state_size"
6601 #define TRANSITION_FUNC_NAME "state_transition"
6603 #define STATE_ALTS_FUNC_NAME "state_alts"
6605 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6607 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6609 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6611 #define RESET_FUNC_NAME "state_reset"
6613 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6615 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6617 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6619 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6621 #define DFA_START_FUNC_NAME "dfa_start"
6623 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6625 /* Names of parameters of the PHR interface functions. */
6626 #define STATE_NAME "state"
6628 #define INSN_PARAMETER_NAME "insn"
6630 #define INSN2_PARAMETER_NAME "insn2"
6632 #define CHIP_PARAMETER_NAME "chip"
6634 #define FILE_PARAMETER_NAME "f"
6636 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6638 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6640 /* Names of the variables whose values are internal insn code of rtx
6642 #define INTERNAL_INSN_CODE_NAME "insn_code"
6644 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6646 /* Names of temporary variables in some functions. */
6647 #define TEMPORARY_VARIABLE_NAME "temp"
6649 #define I_VARIABLE_NAME "i"
6651 /* Name of result variable in some functions. */
6652 #define RESULT_VARIABLE_NAME "res"
6654 /* Name of function (attribute) to translate insn into number of insn
6655 alternatives reservation. */
6656 #define INSN_ALTS_FUNC_NAME "insn_alts"
6658 /* Name of function (attribute) to translate insn into internal insn
6660 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6662 /* Name of function (attribute) to translate insn into internal insn
6663 code with caching. */
6664 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6666 /* Name of function (attribute) to translate insn into internal insn
6668 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6670 /* Name of function (attribute) to translate insn into internal insn
6672 #define BYPASS_P_FUNC_NAME "bypass_p"
6674 /* Output C type which is used for representation of codes of states
6677 output_state_member_type (f, automaton)
6679 automaton_t automaton;
6681 output_range_type (f, 0, automaton->achieved_states_num);
6684 /* Output definition of the structure representing current DFA(s)
6687 output_chip_definitions ()
6689 automaton_t automaton;
6691 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
6692 for (automaton = description->first_automaton;
6694 automaton = automaton->next_automaton)
6696 fprintf (output_file, " ");
6697 output_state_member_type (output_file, automaton);
6698 fprintf (output_file, " ");
6699 output_chip_member_name (output_file, automaton);
6700 fprintf (output_file, ";\n");
6702 fprintf (output_file, "};\n\n");
6704 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
6709 /* The function outputs translate vector of internal insn code into
6710 insn equivalence class number. The equivalence class number is
6711 used to access to table and vectors reprewsenting DFA(s). */
6713 output_translate_vect (automaton)
6714 automaton_t automaton;
6718 vla_hwint_t translate_vect;
6720 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
6721 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
6722 for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
6723 /* Undefined value */
6724 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
6725 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6726 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
6727 = ainsn->insn_equiv_class_num;
6728 fprintf (output_file,
6729 "/* Vector translating external insn codes to internal ones.*/\n");
6730 fprintf (output_file, "static const ");
6731 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
6732 fprintf (output_file, " ");
6733 output_translate_vect_name (output_file, automaton);
6734 fprintf (output_file, "[] = {\n");
6735 output_vect (VLA_HWINT_BEGIN (translate_vect),
6736 VLA_HWINT_LENGTH (translate_vect));
6737 fprintf (output_file, "};\n\n");
6738 VLA_HWINT_DELETE (translate_vect);
6741 /* The value in a table state x ainsn -> something which represents
6743 static int undefined_vect_el_value;
6745 /* The following function returns nonzero value if the best
6746 representation of the table is comb vector. */
6749 state_ainsn_table_t tab;
6751 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
6752 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
6755 /* The following function creates new table for AUTOMATON. */
6756 static state_ainsn_table_t
6757 create_state_ainsn_table (automaton)
6758 automaton_t automaton;
6760 state_ainsn_table_t tab;
6761 int full_vect_length;
6764 tab = create_node (sizeof (struct state_ainsn_table));
6765 tab->automaton = automaton;
6766 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
6767 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
6768 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
6769 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
6770 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
6771 full_vect_length = (automaton->insn_equiv_classes_num
6772 * automaton->achieved_states_num);
6773 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
6774 for (i = 0; i < full_vect_length; i++)
6775 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
6776 tab->min_base_vect_el_value = 0;
6777 tab->max_base_vect_el_value = 0;
6778 tab->min_comb_vect_el_value = 0;
6779 tab->max_comb_vect_el_value = 0;
6783 /* The following function outputs the best C representation of the
6784 table TAB of given TABLE_NAME. */
6786 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
6787 output_comb_vect_name_func,
6788 output_check_vect_name_func,
6789 output_base_vect_name_func)
6790 state_ainsn_table_t tab;
6792 void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
6793 void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
6794 void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
6795 void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
6797 if (!comb_vect_p (tab))
6799 fprintf (output_file, "/* Vector for %s. */\n", table_name);
6800 fprintf (output_file, "static const ");
6801 output_range_type (output_file, tab->min_comb_vect_el_value,
6802 tab->max_comb_vect_el_value);
6803 fprintf (output_file, " ");
6804 (*output_full_vect_name_func) (output_file, tab->automaton);
6805 fprintf (output_file, "[] = {\n");
6806 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
6807 VLA_HWINT_LENGTH (tab->full_vect));
6808 fprintf (output_file, "};\n\n");
6812 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
6813 fprintf (output_file, "static const ");
6814 output_range_type (output_file, tab->min_comb_vect_el_value,
6815 tab->max_comb_vect_el_value);
6816 fprintf (output_file, " ");
6817 (*output_comb_vect_name_func) (output_file, tab->automaton);
6818 fprintf (output_file, "[] = {\n");
6819 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
6820 VLA_HWINT_LENGTH (tab->comb_vect));
6821 fprintf (output_file, "};\n\n");
6822 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
6823 fprintf (output_file, "static const ");
6824 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
6825 fprintf (output_file, " ");
6826 (*output_check_vect_name_func) (output_file, tab->automaton);
6827 fprintf (output_file, "[] = {\n");
6828 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
6829 VLA_HWINT_LENGTH (tab->check_vect));
6830 fprintf (output_file, "};\n\n");
6831 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
6832 fprintf (output_file, "static const ");
6833 output_range_type (output_file, tab->min_base_vect_el_value,
6834 tab->max_base_vect_el_value);
6835 fprintf (output_file, " ");
6836 (*output_base_vect_name_func) (output_file, tab->automaton);
6837 fprintf (output_file, "[] = {\n");
6838 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
6839 VLA_HWINT_LENGTH (tab->base_vect));
6840 fprintf (output_file, "};\n\n");
6844 /* The following function adds vector with length VECT_LENGTH and
6845 elements pointed by VECT to table TAB as its line with number
6848 add_vect (tab, vect_num, vect, vect_length)
6849 state_ainsn_table_t tab;
6854 int real_vect_length;
6855 vect_el_t *comb_vect_start;
6856 vect_el_t *check_vect_start;
6857 int comb_vect_index;
6858 int comb_vect_els_num;
6860 int first_unempty_vect_index;
6861 int additional_els_num;
6866 if (vect_length == 0)
6868 real_vect_length = tab->automaton->insn_equiv_classes_num;
6869 if (vect [vect_length - 1] == undefined_vect_el_value)
6871 /* Form full vector in the table: */
6872 for (i = 0; i < vect_length; i++)
6873 VLA_HWINT (tab->full_vect,
6874 i + tab->automaton->insn_equiv_classes_num * vect_num)
6876 /* Form comb vector in the table: */
6877 if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
6879 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
6880 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
6881 for (first_unempty_vect_index = 0;
6882 first_unempty_vect_index < vect_length;
6883 first_unempty_vect_index++)
6884 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
6886 /* Search for the place in comb vect for the inserted vect. */
6887 for (comb_vect_index = 0;
6888 comb_vect_index < comb_vect_els_num;
6891 for (vect_index = first_unempty_vect_index;
6892 vect_index < vect_length
6893 && vect_index + comb_vect_index < comb_vect_els_num;
6895 if (vect [vect_index] != undefined_vect_el_value
6896 && (comb_vect_start [vect_index + comb_vect_index]
6897 != undefined_vect_el_value))
6899 if (vect_index >= vect_length
6900 || vect_index + comb_vect_index >= comb_vect_els_num)
6903 /* Slot was found. */
6904 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
6905 if (additional_els_num < 0)
6906 additional_els_num = 0;
6907 /* Expand comb and check vectors. */
6908 vect_el = undefined_vect_el_value;
6909 no_state_value = tab->automaton->achieved_states_num;
6910 while (additional_els_num > 0)
6912 VLA_HWINT_ADD (tab->comb_vect, vect_el);
6913 VLA_HWINT_ADD (tab->check_vect, no_state_value);
6914 additional_els_num--;
6916 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
6917 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
6918 if (VLA_HWINT_LENGTH (tab->comb_vect)
6919 < (size_t) (comb_vect_index + real_vect_length))
6921 /* Fill comb and check vectors. */
6922 for (vect_index = 0; vect_index < vect_length; vect_index++)
6923 if (vect [vect_index] != undefined_vect_el_value)
6925 if (comb_vect_start [comb_vect_index + vect_index]
6926 != undefined_vect_el_value)
6928 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
6929 if (vect [vect_index] < 0)
6931 if (tab->max_comb_vect_el_value < vect [vect_index])
6932 tab->max_comb_vect_el_value = vect [vect_index];
6933 if (tab->min_comb_vect_el_value > vect [vect_index])
6934 tab->min_comb_vect_el_value = vect [vect_index];
6935 check_vect_start [comb_vect_index + vect_index] = vect_num;
6937 if (tab->max_base_vect_el_value < comb_vect_index)
6938 tab->max_base_vect_el_value = comb_vect_index;
6939 if (tab->min_base_vect_el_value > comb_vect_index)
6940 tab->min_base_vect_el_value = comb_vect_index;
6941 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
6944 /* Return number of out arcs of STATE. */
6946 out_state_arcs_num (state)
6953 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6955 if (arc->insn == NULL)
6957 if (arc->insn->first_ainsn_with_given_equialence_num)
6963 /* Compare number of possible transitions from the states. */
6965 compare_transition_els_num (state_ptr_1, state_ptr_2)
6966 const void *state_ptr_1;
6967 const void *state_ptr_2;
6969 int transition_els_num_1;
6970 int transition_els_num_2;
6972 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
6973 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
6974 if (transition_els_num_1 < transition_els_num_2)
6976 else if (transition_els_num_1 == transition_els_num_2)
6982 /* The function adds element EL_VALUE to vector VECT for a table state
6985 add_vect_el (vect, ainsn, el_value)
6990 int equiv_class_num;
6995 equiv_class_num = ainsn->insn_equiv_class_num;
6996 for (vect_index = VLA_HWINT_LENGTH (*vect);
6997 vect_index <= equiv_class_num;
6999 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7000 VLA_HWINT (*vect, equiv_class_num) = el_value;
7003 /* This is for forming vector of states of an automaton. */
7004 static vla_ptr_t output_states_vect;
7006 /* The function is called by function pass_states. The function adds
7007 STATE to `output_states_vect'. */
7009 add_states_vect_el (state)
7012 VLA_PTR_ADD (output_states_vect, state);
7015 /* Form and output vectors (comb, check, base or full vector)
7016 representing transition table of AUTOMATON. */
7018 output_trans_table (automaton)
7019 automaton_t automaton;
7023 vla_hwint_t transition_vect;
7025 undefined_vect_el_value = automaton->achieved_states_num;
7026 automaton->trans_table = create_state_ainsn_table (automaton);
7027 /* Create vect of pointers to states ordered by num of transitions
7028 from the state (state with the maximum num is the first). */
7029 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7030 pass_states (automaton, add_states_vect_el);
7031 qsort (VLA_PTR_BEGIN (output_states_vect),
7032 VLA_PTR_LENGTH (output_states_vect),
7033 sizeof (state_t), compare_transition_els_num);
7034 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7035 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7036 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7039 VLA_HWINT_NULLIFY (transition_vect);
7040 for (arc = first_out_arc (*state_ptr);
7042 arc = next_out_arc (arc))
7044 if (arc->insn == NULL)
7046 if (arc->insn->first_ainsn_with_given_equialence_num)
7047 add_vect_el (&transition_vect, arc->insn,
7048 arc->to_state->order_state_num);
7050 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7051 VLA_HWINT_BEGIN (transition_vect),
7052 VLA_HWINT_LENGTH (transition_vect));
7054 output_state_ainsn_table
7055 (automaton->trans_table, (char *) "state transitions",
7056 output_trans_full_vect_name, output_trans_comb_vect_name,
7057 output_trans_check_vect_name, output_trans_base_vect_name);
7058 VLA_PTR_DELETE (output_states_vect);
7059 VLA_HWINT_DELETE (transition_vect);
7062 /* Form and output vectors (comb, check, base or simple vect)
7063 representing alts number table of AUTOMATON. The table is state x
7064 ainsn -> number of possible alternative reservations by the
7067 output_state_alts_table (automaton)
7068 automaton_t automaton;
7072 vla_hwint_t state_alts_vect;
7074 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7075 automaton->state_alts_table = create_state_ainsn_table (automaton);
7076 /* Create vect of pointers to states ordered by num of transitions
7077 from the state (state with the maximum num is the first). */
7078 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7079 pass_states (automaton, add_states_vect_el);
7080 qsort (VLA_PTR_BEGIN (output_states_vect),
7081 VLA_PTR_LENGTH (output_states_vect),
7082 sizeof (state_t), compare_transition_els_num);
7083 /* Create base, comb, and check vectors. */
7084 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7085 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7086 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7089 VLA_HWINT_NULLIFY (state_alts_vect);
7090 for (arc = first_out_arc (*state_ptr);
7092 arc = next_out_arc (arc))
7094 if (arc->insn == NULL)
7096 if (arc->insn->first_ainsn_with_given_equialence_num)
7097 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7099 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7100 VLA_HWINT_BEGIN (state_alts_vect),
7101 VLA_HWINT_LENGTH (state_alts_vect));
7103 output_state_ainsn_table
7104 (automaton->state_alts_table, (char *) "state insn alternatives",
7105 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7106 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7107 VLA_PTR_DELETE (output_states_vect);
7108 VLA_HWINT_DELETE (state_alts_vect);
7111 /* The current number of passing states to find minimal issue delay
7112 value for an ainsn and state. */
7113 static int curr_state_pass_num;
7116 /* This recursive function passes states to find minimal issue delay
7117 value for AINSN. The state being visited is STATE. */
7119 min_issue_delay_pass_states (state, ainsn)
7124 int min_insn_issue_delay, insn_issue_delay;
7126 if (state->state_pass_num == curr_state_pass_num)
7128 state->state_pass_num = curr_state_pass_num;
7129 min_insn_issue_delay = state->min_insn_issue_delay = -1;
7130 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7131 if (arc->insn == ainsn)
7133 min_insn_issue_delay = 0;
7138 min_issue_delay_pass_states (arc->to_state, ainsn);
7139 if (arc->to_state->min_insn_issue_delay != -1)
7142 = (arc->to_state->min_insn_issue_delay
7143 + (arc->insn->insn_reserv_decl
7144 == &advance_cycle_insn_decl->decl.insn_reserv ? 1 : 0));
7145 if (min_insn_issue_delay == -1
7146 || min_insn_issue_delay > insn_issue_delay)
7147 min_insn_issue_delay = insn_issue_delay;
7150 state->min_insn_issue_delay = min_insn_issue_delay;
7153 /* The function searches minimal issue delay value for AINSN in STATE.
7154 The function can return negative can not issue AINSN. We will
7155 report about it later. */
7157 min_issue_delay (state, ainsn)
7161 curr_state_pass_num++;
7162 min_issue_delay_pass_states (state, ainsn);
7163 return state->min_insn_issue_delay;
7166 /* The function initiates code for finding minimal issue delay values.
7167 It should be called only once. */
7169 initiate_min_issue_delay_pass_states ()
7171 curr_state_pass_num = 0;
7174 /* Form and output vectors representing minimal issue delay table of
7175 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7178 output_min_issue_delay_table (automaton)
7179 automaton_t automaton;
7181 vla_hwint_t min_issue_delay_vect;
7182 vla_hwint_t compressed_min_issue_delay_vect;
7183 vect_el_t min_delay;
7188 /* Create vect of pointers to states ordered by num of transitions
7189 from the state (state with the maximum num is the first). */
7190 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7191 pass_states (automaton, add_states_vect_el);
7192 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7193 VLA_HWINT_EXPAND (min_issue_delay_vect,
7194 VLA_HWINT_LENGTH (output_states_vect)
7195 * automaton->insn_equiv_classes_num);
7197 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7198 * automaton->insn_equiv_classes_num);
7200 VLA_HWINT (min_issue_delay_vect, i) = 0;
7201 automaton->max_min_delay = 0;
7202 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7203 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7206 for (ainsn = automaton->ainsn_list;
7208 ainsn = ainsn->next_ainsn)
7209 if (ainsn->first_ainsn_with_given_equialence_num)
7211 min_delay = min_issue_delay (*state_ptr, ainsn);
7212 if (automaton->max_min_delay < min_delay)
7213 automaton->max_min_delay = min_delay;
7214 VLA_HWINT (min_issue_delay_vect,
7215 (*state_ptr)->order_state_num
7216 * automaton->insn_equiv_classes_num
7217 + ainsn->insn_equiv_class_num) = min_delay;
7220 fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
7221 fprintf (output_file, "static const ");
7222 output_range_type (output_file, 0, automaton->max_min_delay);
7223 fprintf (output_file, " ");
7224 output_min_issue_delay_vect_name (output_file, automaton);
7225 fprintf (output_file, "[] = {\n");
7226 /* Compress the vector */
7227 if (automaton->max_min_delay < 2)
7228 automaton->min_issue_delay_table_compression_factor = 8;
7229 else if (automaton->max_min_delay < 4)
7230 automaton->min_issue_delay_table_compression_factor = 4;
7231 else if (automaton->max_min_delay < 16)
7232 automaton->min_issue_delay_table_compression_factor = 2;
7234 automaton->min_issue_delay_table_compression_factor = 1;
7235 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7236 "compressed min issue delay vector");
7237 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7238 (VLA_HWINT_LENGTH (min_issue_delay_vect)
7239 + automaton->min_issue_delay_table_compression_factor
7241 / automaton->min_issue_delay_table_compression_factor);
7243 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7245 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7246 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7247 VLA_HWINT (compressed_min_issue_delay_vect,
7248 i / automaton->min_issue_delay_table_compression_factor)
7249 |= (VLA_HWINT (min_issue_delay_vect, i)
7250 << (8 - (i % automaton->min_issue_delay_table_compression_factor
7252 * (8 / automaton->min_issue_delay_table_compression_factor)));
7253 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7254 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7255 fprintf (output_file, "};\n\n");
7256 VLA_PTR_DELETE (output_states_vect);
7257 VLA_HWINT_DELETE (min_issue_delay_vect);
7258 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7262 /* Number of states which contains transition only by advancing cpu
7264 static int locked_states_num;
7267 /* Form and output vector representing the locked states of
7270 output_dead_lock_vect (automaton)
7271 automaton_t automaton;
7275 vla_hwint_t dead_lock_vect;
7277 /* Create vect of pointers to states ordered by num of
7278 transitions from the state (state with the maximum num is the
7280 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7281 pass_states (automaton, add_states_vect_el);
7282 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7283 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7284 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7285 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7288 arc = first_out_arc (*state_ptr);
7291 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
7292 = (next_out_arc (arc) == NULL
7293 && (arc->insn->insn_reserv_decl
7294 == &advance_cycle_insn_decl->decl.insn_reserv) ? 1 : 0);
7296 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
7297 locked_states_num++;
7300 fprintf (output_file, "/* Vector for locked state flags. */\n");
7301 fprintf (output_file, "static const ");
7302 output_range_type (output_file, 0, 1);
7303 fprintf (output_file, " ");
7304 output_dead_lock_vect_name (output_file, automaton);
7305 fprintf (output_file, "[] = {\n");
7306 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
7307 VLA_HWINT_LENGTH (dead_lock_vect));
7308 fprintf (output_file, "};\n\n");
7309 VLA_HWINT_DELETE (dead_lock_vect);
7310 VLA_PTR_DELETE (output_states_vect);
7313 /* Form and output vector representing reserved units of the states of
7316 output_reserved_units_table (automaton)
7317 automaton_t automaton;
7319 state_t *curr_state_ptr;
7320 vla_hwint_t reserved_units_table;
7321 size_t state_byte_size;
7324 /* Create vect of pointers to states. */
7325 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7326 pass_states (automaton, add_states_vect_el);
7327 /* Create vector. */
7328 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
7329 state_byte_size = (description->query_units_num + 7) / 8;
7330 VLA_HWINT_EXPAND (reserved_units_table,
7331 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7333 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7335 VLA_HWINT (reserved_units_table, i) = 0;
7336 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
7337 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7340 for (i = 0; i < description->units_num; i++)
7341 if (units_array [i]->query_p)
7343 if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
7344 VLA_HWINT (reserved_units_table,
7345 (*curr_state_ptr)->order_state_num * state_byte_size
7346 + units_array [i]->query_num / 8)
7347 += (1 << (units_array [i]->query_num % 8));
7350 fprintf (output_file, "/* Vector for reserved units of states. */\n");
7351 fprintf (output_file, "static const ");
7352 output_range_type (output_file, 0, 255);
7353 fprintf (output_file, " ");
7354 output_reserved_units_table_name (output_file, automaton);
7355 fprintf (output_file, "[] = {\n");
7356 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
7357 VLA_HWINT_LENGTH (reserved_units_table));
7358 fprintf (output_file, "};\n\n");
7359 VLA_HWINT_DELETE (reserved_units_table);
7360 VLA_PTR_DELETE (output_states_vect);
7363 /* The function outputs all tables representing DFA(s) used for fast
7364 pipeline hazards recognition. */
7368 automaton_t automaton;
7371 locked_states_num = 0;
7373 initiate_min_issue_delay_pass_states ();
7374 for (automaton = description->first_automaton;
7376 automaton = automaton->next_automaton)
7378 output_translate_vect (automaton);
7379 output_trans_table (automaton);
7380 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
7381 output_state_alts_table (automaton);
7382 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7383 AUTOMATON_STATE_ALTS_MACRO_NAME);
7384 output_min_issue_delay_table (automaton);
7385 output_dead_lock_vect (automaton);
7386 if (no_minimization_flag)
7388 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
7389 output_reserved_units_table (automaton);
7390 fprintf (output_file, "\n#endif /* #if %s */\n\n",
7391 CPU_UNITS_QUERY_MACRO_NAME);
7394 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7395 advance_cycle_insn_decl->decl.insn_reserv.insn_num);
7398 /* The function outputs definition and value of PHR interface variable
7399 `max_insn_queue_index' */
7401 output_max_insn_queue_index_def ()
7405 for (i = 0; (1 << i) <= description->max_insn_reserv_cycles; i++)
7409 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
7413 /* The function outputs switch cases for insn reseravtions using
7414 function *output_automata_list_code. */
7416 output_insn_code_cases (output_automata_list_code)
7417 void (*output_automata_list_code) (automata_list_el_t);
7419 decl_t decl, decl_2;
7422 for (i = 0; i < description->decls_num; i++)
7424 decl = description->decls [i];
7425 if (decl->mode == dm_insn_reserv)
7426 decl->decl.insn_reserv.processed_p = FALSE;
7428 for (i = 0; i < description->decls_num; i++)
7430 decl = description->decls [i];
7431 if (decl->mode == dm_insn_reserv && !decl->decl.insn_reserv.processed_p)
7433 for (j = i; j < description->decls_num; j++)
7435 decl_2 = description->decls [j];
7436 if (decl_2->mode == dm_insn_reserv
7437 && (decl_2->decl.insn_reserv.important_automata_list
7438 == decl->decl.insn_reserv.important_automata_list))
7440 decl_2->decl.insn_reserv.processed_p = TRUE;
7441 fprintf (output_file, " case %d: /* %s */\n",
7442 decl_2->decl.insn_reserv.insn_num,
7443 decl_2->decl.insn_reserv.name);
7446 (*output_automata_list_code)
7447 (decl->decl.insn_reserv.important_automata_list);
7453 /* The function outputs a code for evaluation of a minimal delay of
7454 issue of insns which have reservations in given AUTOMATA_LIST. */
7456 output_automata_list_min_issue_delay_code (automata_list)
7457 automata_list_el_t automata_list;
7459 automata_list_el_t el;
7460 automaton_t automaton;
7462 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7464 automaton = el->automaton;
7465 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7466 output_min_issue_delay_vect_name (output_file, automaton);
7467 fprintf (output_file,
7468 (automaton->min_issue_delay_table_compression_factor != 1
7470 output_translate_vect_name (output_file, automaton);
7471 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7472 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7473 output_chip_member_name (output_file, automaton);
7474 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7475 if (automaton->min_issue_delay_table_compression_factor == 1)
7476 fprintf (output_file, "];\n");
7479 fprintf (output_file, ") / %d];\n",
7480 automaton->min_issue_delay_table_compression_factor);
7481 fprintf (output_file, " %s = (%s >> (8 - (",
7482 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7483 output_translate_vect_name (output_file, automaton);
7485 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
7486 INTERNAL_INSN_CODE_NAME,
7487 automaton->min_issue_delay_table_compression_factor,
7488 8 / automaton->min_issue_delay_table_compression_factor,
7489 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7492 if (el == automata_list)
7493 fprintf (output_file, " %s = %s;\n",
7494 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7497 fprintf (output_file, " if (%s > %s)\n",
7498 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7499 fprintf (output_file, " %s = %s;\n",
7500 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7503 fprintf (output_file, " break;\n\n");
7506 /* Output function `internal_min_issue_delay'. */
7508 output_internal_min_issue_delay_func ()
7510 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7511 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
7512 fprintf (output_file,
7513 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7514 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7515 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
7516 CHIP_PARAMETER_NAME);
7517 fprintf (output_file, "{\n int %s;\n int %s;\n",
7518 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7519 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7520 output_insn_code_cases (output_automata_list_min_issue_delay_code);
7521 fprintf (output_file,
7522 "\n default:\n %s = -1;\n break;\n }\n",
7523 RESULT_VARIABLE_NAME);
7524 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
7525 fprintf (output_file, "}\n\n");
7528 /* The function outputs a code changing state after issue of insns
7529 which have reservations in given AUTOMATA_LIST. */
7531 output_automata_list_transition_code (automata_list)
7532 automata_list_el_t automata_list;
7534 automata_list_el_t el, next_el;
7536 fprintf (output_file, " {\n");
7537 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7538 for (el = automata_list;; el = next_el)
7540 next_el = el->next_automata_list_el;
7541 if (next_el == NULL)
7543 fprintf (output_file, " ");
7544 output_state_member_type (output_file, el->automaton);
7545 fprintf (output_file, " ");
7546 output_temp_chip_member_name (output_file, el->automaton);
7547 fprintf (output_file, ";\n");
7549 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7550 if (comb_vect_p (el->automaton->trans_table))
7552 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7553 output_trans_base_vect_name (output_file, el->automaton);
7554 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7555 output_chip_member_name (output_file, el->automaton);
7556 fprintf (output_file, "] + ");
7557 output_translate_vect_name (output_file, el->automaton);
7558 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7559 fprintf (output_file, " if (");
7560 output_trans_check_vect_name (output_file, el->automaton);
7561 fprintf (output_file, " [%s] != %s->",
7562 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7563 output_chip_member_name (output_file, el->automaton);
7564 fprintf (output_file, ")\n");
7565 fprintf (output_file, " return %s (%s, %s);\n",
7566 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7567 CHIP_PARAMETER_NAME);
7568 fprintf (output_file, " else\n");
7569 fprintf (output_file, " ");
7570 if (el->next_automata_list_el != NULL)
7571 output_temp_chip_member_name (output_file, el->automaton);
7574 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7575 output_chip_member_name (output_file, el->automaton);
7577 fprintf (output_file, " = ");
7578 output_trans_comb_vect_name (output_file, el->automaton);
7579 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7583 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7584 output_trans_full_vect_name (output_file, el->automaton);
7585 fprintf (output_file, " [");
7586 output_translate_vect_name (output_file, el->automaton);
7587 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7588 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7589 output_chip_member_name (output_file, el->automaton);
7590 fprintf (output_file, " * %d];\n",
7591 el->automaton->insn_equiv_classes_num);
7592 fprintf (output_file, " if (%s >= %d)\n",
7593 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7594 fprintf (output_file, " return %s (%s, %s);\n",
7595 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7596 CHIP_PARAMETER_NAME);
7597 fprintf (output_file, " else\n ");
7598 if (el->next_automata_list_el != NULL)
7599 output_temp_chip_member_name (output_file, el->automaton);
7602 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7603 output_chip_member_name (output_file, el->automaton);
7605 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7607 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7608 for (el = automata_list;; el = next_el)
7610 next_el = el->next_automata_list_el;
7611 if (next_el == NULL)
7613 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
7614 output_chip_member_name (output_file, el->automaton);
7615 fprintf (output_file, " = ");
7616 output_temp_chip_member_name (output_file, el->automaton);
7617 fprintf (output_file, ";\n");
7619 fprintf (output_file, " return -1;\n");
7620 fprintf (output_file, " }\n");
7623 /* Output function `internal_state_transition'. */
7625 output_internal_trans_func ()
7627 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7628 INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
7629 fprintf (output_file,
7630 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7631 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7632 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
7633 CHIP_NAME, CHIP_PARAMETER_NAME);
7634 fprintf (output_file, "{\n int %s;\n", TEMPORARY_VARIABLE_NAME);
7635 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7636 output_insn_code_cases (output_automata_list_transition_code);
7637 fprintf (output_file, "\n default:\n return -1;\n }\n");
7638 fprintf (output_file, "}\n\n");
7645 insn_code = dfa_insn_code (insn);
7646 if (insn_code > DFA__ADVANCE_CYCLE)
7650 insn_code = DFA__ADVANCE_CYCLE;
7652 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7653 code denotes CODE. */
7655 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
7656 const char *insn_name;
7657 const char *insn_code_name;
7660 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
7661 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
7662 DFA_INSN_CODE_FUNC_NAME, insn_name);
7663 fprintf (output_file, " if (%s > %s)\n return %d;\n",
7664 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
7665 fprintf (output_file, " }\n else\n %s = %s;\n\n",
7666 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
7670 /* The function outputs function `dfa_insn_code'. */
7672 output_dfa_insn_code_func ()
7674 fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
7675 fprintf (output_file, "static int %s PARAMS ((rtx));\n",
7676 DFA_INSN_CODE_FUNC_NAME);
7677 fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
7678 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
7679 fprintf (output_file, "{\n int %s;\n int %s;\n\n",
7680 INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
7681 fprintf (output_file, " if (INSN_UID (%s) >= %s)\n {\n",
7682 INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7683 fprintf (output_file, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
7684 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7685 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
7686 fprintf (output_file, " %s = xrealloc (%s, %s * sizeof (int));\n",
7687 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7688 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7689 fprintf (output_file,
7690 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
7691 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7692 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7693 TEMPORARY_VARIABLE_NAME);
7694 fprintf (output_file, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
7695 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7696 INSN_PARAMETER_NAME);
7697 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
7698 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
7699 fprintf (output_file, " %s [INSN_UID (%s)] = %s;\n",
7700 DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
7701 INTERNAL_INSN_CODE_NAME);
7702 fprintf (output_file, " }\n return %s;\n}\n\n",
7703 INTERNAL_INSN_CODE_NAME);
7706 /* The function outputs PHR interface function `state_transition'. */
7708 output_trans_func ()
7710 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7711 TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
7712 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
7713 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7714 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7715 INTERNAL_INSN_CODE_NAME, -1);
7716 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
7717 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
7720 /* The function outputs a code for evaluation of alternative states
7721 number for insns which have reservations in given AUTOMATA_LIST. */
7723 output_automata_list_state_alts_code (automata_list)
7724 automata_list_el_t automata_list;
7726 automata_list_el_t el;
7727 automaton_t automaton;
7729 fprintf (output_file, " {\n");
7730 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7731 if (comb_vect_p (el->automaton->state_alts_table))
7733 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
7736 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7738 automaton = el->automaton;
7739 if (comb_vect_p (automaton->state_alts_table))
7741 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7742 output_state_alts_base_vect_name (output_file, automaton);
7743 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7744 output_chip_member_name (output_file, automaton);
7745 fprintf (output_file, "] + ");
7746 output_translate_vect_name (output_file, automaton);
7747 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7748 fprintf (output_file, " if (");
7749 output_state_alts_check_vect_name (output_file, automaton);
7750 fprintf (output_file, " [%s] != %s->",
7751 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7752 output_chip_member_name (output_file, automaton);
7753 fprintf (output_file, ")\n");
7754 fprintf (output_file, " return 0;\n");
7755 fprintf (output_file, " else\n");
7756 fprintf (output_file,
7757 (el == automata_list
7758 ? " %s = " : " %s += "),
7759 RESULT_VARIABLE_NAME);
7760 output_state_alts_comb_vect_name (output_file, automaton);
7761 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7765 fprintf (output_file,
7766 (el == automata_list
7767 ? "\n %s = " : " %s += "),
7768 RESULT_VARIABLE_NAME);
7769 output_state_alts_full_vect_name (output_file, automaton);
7770 fprintf (output_file, " [");
7771 output_translate_vect_name (output_file, automaton);
7772 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7773 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7774 output_chip_member_name (output_file, automaton);
7775 fprintf (output_file, " * %d];\n",
7776 automaton->insn_equiv_classes_num);
7779 fprintf (output_file, " break;\n }\n\n");
7782 /* Output function `internal_state_alts'. */
7784 output_internal_state_alts_func ()
7786 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7787 INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
7788 fprintf (output_file,
7789 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7790 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7791 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
7792 CHIP_PARAMETER_NAME);
7793 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
7794 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7795 output_insn_code_cases (output_automata_list_state_alts_code);
7796 fprintf (output_file,
7797 "\n default:\n %s = 0;\n break;\n }\n",
7798 RESULT_VARIABLE_NAME);
7799 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
7800 fprintf (output_file, "}\n\n");
7803 /* The function outputs PHR interface function `state_alts'. */
7805 output_state_alts_func ()
7807 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7808 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
7809 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
7810 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7811 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7812 INTERNAL_INSN_CODE_NAME, 0);
7813 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
7814 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
7817 /* Output function `min_issue_delay'. */
7819 output_min_issue_delay_func ()
7821 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7822 MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
7823 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
7824 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7825 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
7826 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
7827 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
7828 fprintf (output_file, " if (%s > %s)\n return 0;\n",
7829 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
7830 fprintf (output_file, " }\n else\n %s = %s;\n",
7831 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
7832 fprintf (output_file, "\n return %s (%s, %s);\n",
7833 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7835 fprintf (output_file, "}\n\n");
7838 /* Output function `internal_dead_lock'. */
7840 output_internal_dead_lock_func ()
7842 automaton_t automaton;
7844 fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
7845 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
7846 fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
7847 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
7848 CHIP_PARAMETER_NAME);
7849 fprintf (output_file, "{\n");
7850 for (automaton = description->first_automaton;
7852 automaton = automaton->next_automaton)
7854 fprintf (output_file, " if (");
7855 output_dead_lock_vect_name (output_file, automaton);
7856 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7857 output_chip_member_name (output_file, automaton);
7858 fprintf (output_file, "])\n return 1/* TRUE */;\n");
7860 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
7863 /* The function outputs PHR interface function `state_dead_lock_p'. */
7865 output_dead_lock_func ()
7867 fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
7868 DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
7869 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
7870 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
7873 /* Output function `internal_reset'. */
7875 output_internal_reset_func ()
7877 fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
7878 INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
7879 fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
7880 INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
7881 CHIP_NAME, CHIP_PARAMETER_NAME);
7882 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
7883 CHIP_PARAMETER_NAME, CHIP_NAME);
7886 /* The function outputs PHR interface function `state_size'. */
7890 fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
7891 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
7894 /* The function outputs PHR interface function `state_reset'. */
7896 output_reset_func ()
7898 fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
7899 RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
7900 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
7904 /* Output function `min_insn_conflict_delay'. */
7906 output_min_insn_conflict_delay_func ()
7908 fprintf (output_file,
7909 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
7910 MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
7911 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
7912 STATE_TYPE_NAME, STATE_NAME,
7913 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
7914 fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
7915 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
7916 INTERNAL_INSN2_CODE_NAME);
7917 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7918 INTERNAL_INSN_CODE_NAME, 0);
7919 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
7920 INTERNAL_INSN2_CODE_NAME, 0);
7921 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
7922 CHIP_NAME, STATE_NAME, CHIP_NAME);
7923 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
7924 fprintf (output_file, " if (%s (%s, &%s) > 0)\n abort ();\n",
7925 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
7926 fprintf (output_file, " return %s (%s, &%s);\n",
7927 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
7929 fprintf (output_file, "}\n\n");
7932 /* Output function `internal_insn_latency'. */
7934 output_internal_insn_latency_func ()
7937 struct bypass_decl *bypass;
7940 fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
7941 INTERNAL_INSN_LATENCY_FUNC_NAME);
7942 fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
7943 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7944 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
7945 INSN2_PARAMETER_NAME);
7946 fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
7947 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
7948 fprintf (output_file,
7949 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
7950 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
7951 fprintf (output_file, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7952 for (i = 0; i < description->decls_num; i++)
7954 decl = description->decls [i];
7955 if (decl->mode == dm_insn_reserv)
7957 fprintf (output_file, " case %d:\n",
7958 decl->decl.insn_reserv.insn_num);
7959 if (decl->decl.insn_reserv.bypass_list == NULL)
7960 fprintf (output_file, " return (%s != %s ? %d : 0);\n",
7961 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
7962 decl->decl.insn_reserv.default_latency);
7965 fprintf (output_file, " switch (%s)\n {\n",
7966 INTERNAL_INSN2_CODE_NAME);
7967 for (bypass = decl->decl.insn_reserv.bypass_list;
7969 bypass = bypass->next)
7971 fprintf (output_file, " case %d:\n",
7972 bypass->in_insn_reserv->insn_num);
7973 if (bypass->bypass_guard_name == NULL)
7974 fprintf (output_file, " return %d;\n",
7977 fprintf (output_file,
7978 " return (%s (%s, %s) ? %d : %d);\n",
7979 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
7980 INSN2_PARAMETER_NAME, bypass->latency,
7981 decl->decl.insn_reserv.default_latency);
7983 fprintf (output_file, " default:\n");
7984 fprintf (output_file,
7985 " return (%s != %s ? %d : 0);\n }\n",
7986 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
7987 decl->decl.insn_reserv.default_latency);
7992 fprintf (output_file, " default:\n return 0;\n }\n}\n\n");
7995 /* The function outputs PHR interface function `insn_latency'. */
7997 output_insn_latency_func ()
7999 fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8000 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8001 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8002 fprintf (output_file, "{\n int %s, %s;\n",
8003 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8004 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8005 INTERNAL_INSN_CODE_NAME, 0);
8006 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8007 INTERNAL_INSN2_CODE_NAME, 0);
8008 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8009 INTERNAL_INSN_LATENCY_FUNC_NAME,
8010 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8011 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8014 /* The function outputs PHR interface function `print_reservation'. */
8016 output_print_reservation_func ()
8021 fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8022 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8023 INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8024 INSN_PARAMETER_NAME);
8025 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8026 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8027 fprintf (output_file, " %s = %s (%s);\n",
8028 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8029 INSN_PARAMETER_NAME);
8030 fprintf (output_file, " if (%s > %s)\n",
8031 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8032 fprintf (output_file, " {\n fprintf (%s, \"%s\");\n",
8033 FILE_PARAMETER_NAME, NOTHING_NAME);
8034 fprintf (output_file, " return;\n }\n");
8035 fprintf (output_file, " }\n else\n");
8036 fprintf (output_file,
8037 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8038 FILE_PARAMETER_NAME, NOTHING_NAME);
8039 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8040 for (i = 0; i < description->decls_num; i++)
8042 decl = description->decls [i];
8043 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8045 fprintf (output_file,
8046 " case %d:\n", decl->decl.insn_reserv.insn_num);
8047 fprintf (output_file,
8048 " fprintf (%s, \"%s\");\n break;\n",
8049 FILE_PARAMETER_NAME,
8050 regexp_representation (decl->decl.insn_reserv.regexp));
8051 finish_regexp_representation ();
8054 fprintf (output_file, " default:\n fprintf (%s, \"%s\");\n }\n",
8055 FILE_PARAMETER_NAME, NOTHING_NAME);
8056 fprintf (output_file, "}\n\n");
8059 /* The following function is used to sort unit declaration by their
8062 units_cmp (unit1, unit2)
8063 const void *unit1, *unit2;
8065 const struct unit_decl *u1 = *(struct unit_decl **) unit1;
8066 const struct unit_decl *u2 = *(struct unit_decl **) unit2;
8068 return strcmp (u1->name, u2->name);
8071 /* The following macro value is name of struct containing unit name
8073 #define NAME_CODE_STRUCT_NAME "name_code"
8075 /* The following macro value is name of table of struct name_code. */
8076 #define NAME_CODE_TABLE_NAME "name_code_table"
8078 /* The following macro values are member names for struct name_code. */
8079 #define NAME_MEMBER_NAME "name"
8080 #define CODE_MEMBER_NAME "code"
8082 /* The following macro values are local variable names for function
8083 `get_cpu_unit_code'. */
8084 #define CMP_VARIABLE_NAME "cmp"
8085 #define LOW_VARIABLE_NAME "l"
8086 #define MIDDLE_VARIABLE_NAME "m"
8087 #define HIGH_VARIABLE_NAME "h"
8089 /* The following function outputs function to obtain internal cpu unit
8090 code by the cpu unit name. */
8092 output_get_cpu_unit_code_func ()
8095 struct unit_decl **units;
8097 fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8098 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8099 CPU_UNIT_NAME_PARAMETER_NAME);
8100 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8101 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8102 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8103 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8104 fprintf (output_file, " static struct %s %s [] =\n {\n",
8105 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8106 units = (struct unit_decl **) xmalloc (sizeof (struct unit_decl *)
8107 * description->units_num);
8108 memcpy (units, units_array,
8109 sizeof (struct unit_decl *) * description->units_num);
8110 qsort (units, description->units_num,
8111 sizeof (struct unit_decl *), units_cmp);
8112 for (i = 0; i < description->units_num; i++)
8113 if (units [i]->query_p)
8114 fprintf (output_file, " {\"%s\", %d},\n",
8115 units[i]->name, units[i]->query_num);
8116 fprintf (output_file, " };\n\n");
8117 fprintf (output_file, " /* The following is binary search: */\n");
8118 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8119 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8120 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8121 fprintf (output_file, " while (%s <= %s)\n {\n",
8122 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8123 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8124 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8125 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8126 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8127 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8128 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8129 fprintf (output_file, " %s = %s - 1;\n",
8130 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8131 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8132 fprintf (output_file, " %s = %s + 1;\n",
8133 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8134 fprintf (output_file, " else\n");
8135 fprintf (output_file, " return %s [%s].%s;\n }\n",
8136 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8137 fprintf (output_file, " return -1;\n}\n\n");
8141 /* The following function outputs function to check reservation of cpu
8142 unit (its internal code will be passed as the function argument) in
8145 output_cpu_unit_reservation_p ()
8147 automaton_t automaton;
8149 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8150 CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8151 CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8152 CPU_CODE_PARAMETER_NAME);
8153 fprintf (output_file, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8154 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8155 description->query_units_num);
8156 for (automaton = description->first_automaton;
8158 automaton = automaton->next_automaton)
8160 fprintf (output_file, " if ((");
8161 output_reserved_units_table_name (output_file, automaton);
8162 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8163 output_chip_member_name (output_file, automaton);
8164 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8165 (description->query_units_num + 7) / 8,
8166 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8167 fprintf (output_file, " return 1;\n");
8169 fprintf (output_file, " return 0;\n}\n\n");
8172 /* The function outputs PHR interface function `dfa_start'. */
8174 output_dfa_start_func ()
8176 fprintf (output_file,
8177 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8178 DFA_START_FUNC_NAME, I_VARIABLE_NAME,
8179 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8180 fprintf (output_file, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8181 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8182 fprintf (output_file,
8183 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8184 I_VARIABLE_NAME, I_VARIABLE_NAME,
8185 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8186 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8189 /* The function outputs PHR interface function `dfa_finish'. */
8191 output_dfa_finish_func ()
8193 fprintf (output_file, "void\n%s ()\n{\n free (%s);\n}\n\n",
8194 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8199 /* The page contains code for output description file (readable
8200 representation of original description and generated DFA(s). */
8202 /* The function outputs string representation of IR reservation. */
8204 output_regexp (regexp)
8207 fprintf (output_description_file, "%s", regexp_representation (regexp));
8208 finish_regexp_representation ();
8211 /* Output names of units in LIST separated by comma. */
8213 output_unit_set_el_list (list)
8218 for (el = list; el != NULL; el = el->next_unit_set_el)
8221 fprintf (output_description_file, ",");
8222 fprintf (output_description_file, "%s", el->unit_decl->name);
8226 /* The function outputs string representation of IR define_reservation
8227 and define_insn_reservation. */
8229 output_description ()
8234 for (i = 0; i < description->decls_num; i++)
8236 decl = description->decls [i];
8237 if (decl->mode == dm_unit)
8239 if (decl->decl.unit.excl_list != NULL)
8241 fprintf (output_description_file, "unit %s exlusion_set: ",
8242 decl->decl.unit.name);
8243 output_unit_set_el_list (decl->decl.unit.excl_list);
8244 fprintf (output_description_file, "\n");
8246 if (decl->decl.unit.presence_list != NULL)
8248 fprintf (output_description_file, "unit %s presence_set: ",
8249 decl->decl.unit.name);
8250 output_unit_set_el_list (decl->decl.unit.presence_list);
8251 fprintf (output_description_file, "\n");
8253 if (decl->decl.unit.absence_list != NULL)
8255 fprintf (output_description_file, "unit %s absence_set: ",
8256 decl->decl.unit.name);
8257 output_unit_set_el_list (decl->decl.unit.absence_list);
8258 fprintf (output_description_file, "\n");
8262 fprintf (output_description_file, "\n");
8263 for (i = 0; i < description->decls_num; i++)
8265 decl = description->decls [i];
8266 if (decl->mode == dm_reserv)
8268 fprintf (output_description_file, "reservation ");
8269 fprintf (output_description_file, decl->decl.reserv.name);
8270 fprintf (output_description_file, ": ");
8271 output_regexp (decl->decl.reserv.regexp);
8272 fprintf (output_description_file, "\n");
8274 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8276 fprintf (output_description_file, "insn reservation %s ",
8277 decl->decl.insn_reserv.name);
8278 print_rtl (output_description_file, decl->decl.insn_reserv.condexp);
8279 fprintf (output_description_file, ": ");
8280 output_regexp (decl->decl.insn_reserv.regexp);
8281 fprintf (output_description_file, "\n");
8283 else if (decl->mode == dm_bypass)
8284 fprintf (output_description_file, "bypass %d %s %s\n",
8285 decl->decl.bypass.latency, decl->decl.bypass.out_insn_name,
8286 decl->decl.bypass.in_insn_name);
8288 fprintf (output_description_file, "\n\f\n");
8291 /* The function outputs name of AUTOMATON. */
8293 output_automaton_name (f, automaton)
8295 automaton_t automaton;
8297 if (automaton->corresponding_automaton_decl == NULL)
8298 fprintf (f, "#%d", automaton->automaton_order_num);
8300 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8303 /* Maximal length of line for pretty printing into description
8305 #define MAX_LINE_LENGTH 70
8307 /* The function outputs units name belonging to AUTOMATON. */
8309 output_automaton_units (automaton)
8310 automaton_t automaton;
8314 int curr_line_length;
8315 int there_is_an_automaton_unit;
8318 fprintf (output_description_file, "\n Coresponding units:\n");
8319 fprintf (output_description_file, " ");
8320 curr_line_length = 4;
8321 there_is_an_automaton_unit = 0;
8322 for (i = 0; i < description->decls_num; i++)
8324 decl = description->decls [i];
8325 if (decl->mode == dm_unit
8326 && (decl->decl.unit.corresponding_automaton_num
8327 == automaton->automaton_order_num))
8329 there_is_an_automaton_unit = 1;
8330 name = decl->decl.unit.name;
8331 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8333 curr_line_length = strlen (name) + 4;
8334 fprintf (output_description_file, "\n ");
8338 curr_line_length += strlen (name) + 1;
8339 fprintf (output_description_file, " ");
8341 fprintf (output_description_file, name);
8344 if (!there_is_an_automaton_unit)
8345 fprintf (output_description_file, "<None>");
8346 fprintf (output_description_file, "\n\n");
8349 /* The following variable is used for forming array of all possible cpu unit
8350 reservations described by the current DFA state. */
8351 static vla_ptr_t state_reservs;
8353 /* The function forms `state_reservs' for STATE. */
8355 add_state_reservs (state)
8358 alt_state_t curr_alt_state;
8359 reserv_sets_t reservs;
8361 if (state->component_states != NULL)
8362 for (curr_alt_state = state->component_states;
8363 curr_alt_state != NULL;
8364 curr_alt_state = curr_alt_state->next_sorted_alt_state)
8365 add_state_reservs (curr_alt_state->state);
8368 reservs = state->reservs;
8369 VLA_PTR_ADD (state_reservs, reservs);
8373 /* The function outputs readable represenatation of all out arcs of
8376 output_state_arcs (state)
8382 int curr_line_length;
8384 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8387 if (!ainsn->first_insn_with_same_reservs)
8389 fprintf (output_description_file, " ");
8390 curr_line_length = 7;
8391 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8394 insn_name = ainsn->insn_reserv_decl->name;
8395 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8397 if (ainsn != arc->insn)
8399 fprintf (output_description_file, ",\n ");
8400 curr_line_length = strlen (insn_name) + 6;
8403 curr_line_length += strlen (insn_name);
8407 curr_line_length += strlen (insn_name);
8408 if (ainsn != arc->insn)
8410 curr_line_length += 2;
8411 fprintf (output_description_file, ", ");
8414 fprintf (output_description_file, insn_name);
8415 ainsn = ainsn->next_same_reservs_insn;
8417 while (ainsn != NULL);
8418 fprintf (output_description_file, " %d (%d)\n",
8419 arc->to_state->order_state_num, arc->state_alts);
8421 fprintf (output_description_file, "\n");
8424 /* The following function is used for sorting possible cpu unit
8425 reservation of a DFA state. */
8427 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
8428 const void *reservs_ptr_1;
8429 const void *reservs_ptr_2;
8431 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
8432 *(reserv_sets_t *) reservs_ptr_2);
8435 /* The following function is used for sorting possible cpu unit
8436 reservation of a DFA state. */
8438 remove_state_duplicate_reservs ()
8440 reserv_sets_t *reservs_ptr;
8441 reserv_sets_t *last_formed_reservs_ptr;
8443 last_formed_reservs_ptr = NULL;
8444 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8445 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8447 if (last_formed_reservs_ptr == NULL)
8448 last_formed_reservs_ptr = reservs_ptr;
8449 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
8451 ++last_formed_reservs_ptr;
8452 *last_formed_reservs_ptr = *reservs_ptr;
8454 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
8457 /* The following function output readable representation of DFA(s)
8458 state used for fast recognition of pipeline hazards. State is
8459 described by possible (current and scehduled) cpu unit
8462 output_state (state)
8465 reserv_sets_t *reservs_ptr;
8467 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
8468 fprintf (output_description_file, " State #%d", state->order_state_num);
8469 fprintf (output_description_file,
8470 state->new_cycle_p ? " (new cycle)\n" : "\n");
8471 add_state_reservs (state);
8472 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
8473 sizeof (reserv_sets_t), state_reservs_cmp);
8474 remove_state_duplicate_reservs ();
8475 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8476 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8479 fprintf (output_description_file, " ");
8480 output_reserv_sets (output_description_file, *reservs_ptr);
8481 fprintf (output_description_file, "\n");
8483 fprintf (output_description_file, "\n");
8484 output_state_arcs (state);
8485 VLA_PTR_DELETE (state_reservs);
8488 /* The following function output readable representation of
8489 DFAs used for fast recognition of pipeline hazards. */
8491 output_automaton_descriptions ()
8493 automaton_t automaton;
8495 for (automaton = description->first_automaton;
8497 automaton = automaton->next_automaton)
8499 fprintf (output_description_file, "\nAutomaton ");
8500 output_automaton_name (output_description_file, automaton);
8501 fprintf (output_description_file, "\n");
8502 output_automaton_units (automaton);
8503 pass_states (automaton, output_state);
8509 /* The page contains top level function for generation DFA(s) used for
8512 /* The function outputs statistics about work of different phases of
8515 output_statistics (f)
8518 automaton_t automaton;
8520 int transition_comb_vect_els = 0;
8521 int transition_full_vect_els = 0;
8522 int state_alts_comb_vect_els = 0;
8523 int state_alts_full_vect_els = 0;
8524 int min_issue_delay_vect_els = 0;
8527 for (automaton = description->first_automaton;
8529 automaton = automaton->next_automaton)
8531 fprintf (f, "\nAutomaton ");
8532 output_automaton_name (f, automaton);
8533 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
8534 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
8535 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
8536 automaton->DFA_states_num, automaton->DFA_arcs_num);
8537 if (!no_minimization_flag)
8538 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8539 automaton->minimal_DFA_states_num,
8540 automaton->minimal_DFA_arcs_num);
8541 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
8542 description->insns_num, automaton->insn_equiv_classes_num);
8545 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8546 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
8547 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
8548 (comb_vect_p (automaton->trans_table)
8549 ? "use comb vect" : "use simple vect"));
8551 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8552 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
8553 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
8554 (comb_vect_p (automaton->state_alts_table)
8555 ? "use comb vect" : "use simple vect"));
8557 (f, "%5ld min delay table els, compression factor %d\n",
8558 (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
8559 automaton->min_issue_delay_table_compression_factor);
8560 transition_comb_vect_els
8561 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
8562 transition_full_vect_els
8563 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
8564 state_alts_comb_vect_els
8565 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
8566 state_alts_full_vect_els
8567 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
8568 min_issue_delay_vect_els
8569 += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
8573 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
8574 allocated_states_num, allocated_arcs_num);
8575 fprintf (f, "%5d all allocated alternative states\n",
8576 allocated_alt_states_num);
8577 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
8578 transition_comb_vect_els, transition_full_vect_els);
8580 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
8581 state_alts_comb_vect_els, state_alts_full_vect_els);
8582 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
8583 fprintf (f, "%5d locked states num\n", locked_states_num);
8587 /* The function output times of work of different phases of DFA
8590 output_time_statistics (f)
8593 fprintf (f, "\n transformation: ");
8594 print_active_time (f, transform_time);
8595 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
8596 print_active_time (f, NDFA_time);
8599 fprintf (f, ", NDFA -> DFA: ");
8600 print_active_time (f, NDFA_to_DFA_time);
8602 fprintf (f, "\n DFA minimization: ");
8603 print_active_time (f, minimize_time);
8604 fprintf (f, ", making insn equivalence: ");
8605 print_active_time (f, equiv_time);
8606 fprintf (f, "\n all automaton generation: ");
8607 print_active_time (f, automaton_generation_time);
8608 fprintf (f, ", output: ");
8609 print_active_time (f, output_time);
8613 /* The function generates DFA (deterministic finate state automaton)
8614 for fast recognition of pipeline hazards. No errors during
8615 checking must be fixed before this function call. */
8619 automata_num = split_argument;
8620 if (description->units_num < automata_num)
8621 automata_num = description->units_num;
8624 initiate_automata_lists ();
8625 initiate_pass_states ();
8626 initiate_excl_sets ();
8627 initiate_presence_absence_sets ();
8628 automaton_generation_time = create_ticker ();
8629 transform_time = create_ticker ();
8630 add_advance_cycle_insn_decl ();
8631 fprintf (stderr, "Reservation transformation...");
8633 transform_insn_regexps ();
8634 fprintf (stderr, "done\n");
8635 ticker_off (&transform_time);
8638 ticker_off (&automaton_generation_time);
8643 /* The following function creates attribute which order number of insn
8644 in pipeline hazard description translator. */
8646 make_insn_alts_attr ()
8652 condexp = rtx_alloc (COND);
8653 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8654 XEXP (condexp, 1) = make_numeric_value (0);
8655 for (i = insn_num = 0; i < description->decls_num; i++)
8657 decl = description->decls [i];
8658 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8660 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8661 XVECEXP (condexp, 0, 2 * insn_num + 1)
8662 = make_numeric_value (decl->decl.insn_reserv.transformed_regexp
8663 ->regexp.oneof.regexps_num);
8667 if (description->insns_num != insn_num + 1)
8669 make_internal_attr (attr_printf (sizeof ("*")
8670 + strlen (INSN_ALTS_FUNC_NAME) + 1,
8671 "*%s", INSN_ALTS_FUNC_NAME),
8677 /* The following function creates attribute which is order number of
8678 insn in pipeline hazard description translator. */
8680 make_internal_dfa_insn_code_attr ()
8686 condexp = rtx_alloc (COND);
8687 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8688 XEXP (condexp, 1) = make_numeric_value (advance_cycle_insn_decl
8689 ->decl.insn_reserv.insn_num + 1);
8690 for (i = insn_num = 0; i < description->decls_num; i++)
8692 decl = description->decls [i];
8693 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8695 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8696 XVECEXP (condexp, 0, 2 * insn_num + 1)
8697 = make_numeric_value (decl->decl.insn_reserv.insn_num);
8701 if (description->insns_num != insn_num + 1)
8704 (attr_printf (sizeof ("*")
8705 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
8706 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
8712 /* The following function creates attribute which order number of insn
8713 in pipeline hazard description translator. */
8715 make_default_insn_latency_attr ()
8721 condexp = rtx_alloc (COND);
8722 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8723 XEXP (condexp, 1) = make_numeric_value (0);
8724 for (i = insn_num = 0; i < description->decls_num; i++)
8726 decl = description->decls [i];
8727 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8729 XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8730 XVECEXP (condexp, 0, 2 * insn_num + 1)
8731 = make_numeric_value (decl->decl.insn_reserv.default_latency);
8735 if (description->insns_num != insn_num + 1)
8737 make_internal_attr (attr_printf (sizeof ("*")
8738 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
8739 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
8745 /* The following function creates attribute which returns 1 if given
8746 output insn has bypassing and 0 otherwise. */
8751 int bypass_insns_num = 0;
8755 for (i = 0; i < description->decls_num; i++)
8757 decl = description->decls [i];
8758 if (decl->mode == dm_insn_reserv
8759 && decl->decl.insn_reserv.condexp != NULL
8760 && decl->decl.insn_reserv.bypass_list != NULL)
8763 if (bypass_insns_num == 0)
8764 result_rtx = make_numeric_value (0);
8767 result_rtx = rtx_alloc (COND);
8768 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
8769 XEXP (result_rtx, 1) = make_numeric_value (0);
8771 for (i = bypass_insn = 0; i < description->decls_num; i++)
8773 decl = description->decls [i];
8774 if (decl->mode == dm_insn_reserv
8775 && decl->decl.insn_reserv.condexp != NULL
8776 && decl->decl.insn_reserv.bypass_list != NULL)
8778 XVECEXP (result_rtx, 0, 2 * bypass_insn)
8779 = decl->decl.insn_reserv.condexp;
8780 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
8781 = make_numeric_value (1);
8786 make_internal_attr (attr_printf (sizeof ("*")
8787 + strlen (BYPASS_P_FUNC_NAME) + 1,
8788 "*%s", BYPASS_P_FUNC_NAME),
8794 /* This page mainly contains top level functions of pipeline hazards
8795 description translator. */
8797 /* The following macro value is suffix of name of description file of
8798 pipeline hazards description translator. */
8799 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
8801 /* The function returns suffix of given file name. The returned
8802 string can not be changed. */
8804 file_name_suffix (file_name)
8805 const char *file_name;
8807 const char *last_period;
8809 for (last_period = NULL; *file_name != '\0'; file_name++)
8810 if (*file_name == '.')
8811 last_period = file_name;
8812 return (last_period == NULL ? file_name : last_period);
8815 /* The function returns base name of given file name, i.e. pointer to
8816 first char after last `/' (or `\' for WIN32) in given file name,
8817 given file name itself if the directory name is absent. The
8818 returned string can not be changed. */
8820 base_file_name (file_name)
8821 const char *file_name;
8823 int directory_name_length;
8825 directory_name_length = strlen (file_name);
8827 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
8828 && file_name[directory_name_length] != '\\')
8830 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
8832 directory_name_length--;
8833 return file_name + directory_name_length + 1;
8836 /* The following is top level function to initialize the work of
8837 pipeline hazards description translator. */
8839 initiate_automaton_gen (argc, argv)
8843 const char *base_name;
8847 split_argument = 0; /* default value */
8848 no_minimization_flag = 0;
8852 for (i = 2; i < argc; i++)
8853 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
8854 no_minimization_flag = 1;
8855 else if (strcmp (argv [i], "-time") == 0)
8857 else if (strcmp (argv [i], "-v") == 0)
8859 else if (strcmp (argv [i], W_OPTION) == 0)
8861 else if (strcmp (argv [i], NDFA_OPTION) == 0)
8863 else if (strcmp (argv [i], "-split") == 0)
8866 fatal ("-split has no argument.");
8867 fatal ("option `-split' has not been implemented yet\n");
8868 /* split_argument = atoi (argument_vect [i + 1]); */
8870 VLA_PTR_CREATE (decls, 150, "decls");
8871 /* Initialize IR storage. */
8872 obstack_init (&irp);
8873 initiate_automaton_decl_table ();
8874 initiate_insn_decl_table ();
8875 initiate_decl_table ();
8876 output_file = stdout;
8877 output_description_file = NULL;
8878 base_name = base_file_name (argv[1]);
8879 obstack_grow (&irp, base_name,
8880 strlen (base_name) - strlen (file_name_suffix (base_name)));
8881 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
8882 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
8883 obstack_1grow (&irp, '\0');
8884 output_description_file_name = obstack_base (&irp);
8885 obstack_finish (&irp);
8888 /* The following function checks existence at least one arc marked by
8893 automaton_t automaton;
8894 ainsn_t ainsn, reserv_ainsn;
8896 for (automaton = description->first_automaton;
8898 automaton = automaton->next_automaton)
8900 for (ainsn = automaton->ainsn_list;
8902 ainsn = ainsn->next_ainsn)
8903 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
8905 for (reserv_ainsn = ainsn;
8906 reserv_ainsn != NULL;
8907 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
8908 if (automaton->corresponding_automaton_decl != NULL)
8911 error ("Automaton `%s': Insn `%s' will never be issued",
8912 automaton->corresponding_automaton_decl->name,
8913 reserv_ainsn->insn_reserv_decl->name);
8916 ("Automaton `%s': Insn `%s' will never be issued",
8917 automaton->corresponding_automaton_decl->name,
8918 reserv_ainsn->insn_reserv_decl->name);
8923 error ("Insn `%s' will never be issued",
8924 reserv_ainsn->insn_reserv_decl->name);
8926 warning ("Insn `%s' will never be issued",
8927 reserv_ainsn->insn_reserv_decl->name);
8933 /* The following vla is used for storing pointers to all achieved
8935 static vla_ptr_t automaton_states;
8937 /* This function is called by function pass_states to add an achieved
8940 add_automaton_state (state)
8943 VLA_PTR_ADD (automaton_states, state);
8946 /* The following function forms list of important automata (whose
8947 states may be changed after the insn issue) for each insn. */
8949 form_important_insn_automata_lists ()
8951 automaton_t automaton;
8958 VLA_PTR_CREATE (automaton_states, 1500,
8959 "automaton states for forming important insn automata sets");
8960 /* Mark important ainsns. */
8961 for (automaton = description->first_automaton;
8963 automaton = automaton->next_automaton)
8965 VLA_PTR_NULLIFY (automaton_states);
8966 pass_states (automaton, add_automaton_state);
8967 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
8968 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
8971 for (arc = first_out_arc (*state_ptr);
8973 arc = next_out_arc (arc))
8974 if (arc->to_state != *state_ptr)
8976 if (!arc->insn->first_insn_with_same_reservs)
8978 for (ainsn = arc->insn;
8980 ainsn = ainsn->next_same_reservs_insn)
8981 ainsn->important_p = TRUE;
8985 VLA_PTR_DELETE (automaton_states);
8986 /* Create automata sets for the insns. */
8987 for (i = 0; i < description->decls_num; i++)
8989 decl = description->decls [i];
8990 if (decl->mode == dm_insn_reserv)
8992 automata_list_start ();
8993 for (automaton = description->first_automaton;
8995 automaton = automaton->next_automaton)
8996 for (ainsn = automaton->ainsn_list;
8998 ainsn = ainsn->next_ainsn)
8999 if (ainsn->important_p
9000 && ainsn->insn_reserv_decl == &decl->decl.insn_reserv)
9002 automata_list_add (automaton);
9005 decl->decl.insn_reserv.important_automata_list
9006 = automata_list_finish ();
9012 /* The following is top level function to generate automat(a,on) for
9013 fast recognition of pipeline hazards. */
9019 description = create_node (sizeof (struct description)
9020 /* One entry for cycle advancing insn. */
9021 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9022 description->decls_num = VLA_PTR_LENGTH (decls);
9023 description->query_units_num = 0;
9024 for (i = 0; i < description->decls_num; i++)
9026 description->decls [i] = VLA_PTR (decls, i);
9027 if (description->decls [i]->mode == dm_unit
9028 && description->decls [i]->decl.unit.query_p)
9029 description->decls [i]->decl.unit.query_num
9030 = description->query_units_num++;
9032 all_time = create_ticker ();
9033 check_time = create_ticker ();
9034 fprintf (stderr, "Check description...");
9036 check_all_description ();
9037 fprintf (stderr, "done\n");
9038 ticker_off (&check_time);
9039 generation_time = create_ticker ();
9046 form_important_insn_automata_lists ();
9047 fprintf (stderr, "Generation of attributes...");
9049 make_internal_dfa_insn_code_attr ();
9050 make_insn_alts_attr ();
9051 make_default_insn_latency_attr ();
9052 make_bypass_attr ();
9053 fprintf (stderr, "done\n");
9056 ticker_off (&generation_time);
9057 ticker_off (&all_time);
9058 fprintf (stderr, "All other genattrtab stuff...");
9062 /* The following is top level function to output PHR and to finish
9063 work with pipeline description translator. */
9067 fprintf (stderr, "done\n");
9069 fatal ("Errors in DFA description");
9070 ticker_on (&all_time);
9071 output_time = create_ticker ();
9072 fprintf (stderr, "Forming and outputing automata tables...");
9074 output_dfa_max_issue_rate ();
9076 fprintf (stderr, "done\n");
9077 fprintf (stderr, "Output functions to work with automata...");
9079 output_chip_definitions ();
9080 output_max_insn_queue_index_def ();
9081 output_internal_min_issue_delay_func ();
9082 output_internal_trans_func ();
9083 /* Cache of insn dfa codes: */
9084 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9085 fprintf (output_file, "\nstatic int %s;\n\n",
9086 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9087 output_dfa_insn_code_func ();
9088 output_trans_func ();
9089 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9090 output_internal_state_alts_func ();
9091 output_state_alts_func ();
9092 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9093 AUTOMATON_STATE_ALTS_MACRO_NAME);
9094 output_min_issue_delay_func ();
9095 output_internal_dead_lock_func ();
9096 output_dead_lock_func ();
9097 output_size_func ();
9098 output_internal_reset_func ();
9099 output_reset_func ();
9100 output_min_insn_conflict_delay_func ();
9101 output_internal_insn_latency_func ();
9102 output_insn_latency_func ();
9103 output_print_reservation_func ();
9104 if (no_minimization_flag)
9106 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9107 output_get_cpu_unit_code_func ();
9108 output_cpu_unit_reservation_p ();
9109 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9110 CPU_UNITS_QUERY_MACRO_NAME);
9112 output_dfa_start_func ();
9113 output_dfa_finish_func ();
9114 fprintf (stderr, "done\n");
9117 output_description_file = fopen (output_description_file_name, "w");
9118 if (output_description_file == NULL)
9120 perror (output_description_file_name);
9121 exit (FATAL_EXIT_CODE);
9123 fprintf (stderr, "Output automata description...");
9125 output_description ();
9126 output_automaton_descriptions ();
9127 fprintf (stderr, "done\n");
9128 output_statistics (output_description_file);
9130 output_statistics (stderr);
9131 ticker_off (&output_time);
9132 output_time_statistics (stderr);
9135 finish_automata_lists ();
9138 fprintf (stderr, "Summary:\n");
9139 fprintf (stderr, " check time ");
9140 print_active_time (stderr, check_time);
9141 fprintf (stderr, ", generation time ");
9142 print_active_time (stderr, generation_time);
9143 fprintf (stderr, ", all time ");
9144 print_active_time (stderr, all_time);
9145 fprintf (stderr, "\n");
9147 /* Finish all work. */
9148 if (output_description_file != NULL)
9150 fflush (output_description_file);
9151 if (ferror (stdout) != 0)
9152 fatal ("Error in writing DFA description file %s",
9153 output_description_file_name);
9154 fclose (output_description_file);
9156 finish_automaton_decl_table ();
9157 finish_insn_decl_table ();
9158 finish_decl_table ();
9159 obstack_free (&irp, NULL);
9160 if (have_error && output_description_file != NULL)
9161 remove (output_description_file_name);