1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 Written by Vladimir Makarov <vmakarov@redhat.com>
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 GNU CC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 1. Detecting pipeline structural hazards quickly. T. Proebsting,
26 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
27 Principles of Programming Languages, pages 280--286, 1994.
29 This article is a good start point to understand usage of finite
30 state automata for pipeline hazard recognizers. But I'd
31 recommend the 2nd article for more deep understanding.
33 2. Efficient Instruction Scheduling Using Finite State Automata:
34 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
35 article about usage of finite state automata for pipeline hazard
38 The current implementation is different from the 2nd article in the
41 1. New operator `|' (alternative) is permitted in functional unit
42 reservation which can be treated deterministicly and
45 2. Possibility of usage of nondeterministic automata too.
47 3. Possibility to query functional unit reservations for given
50 4. Several constructions to describe impossible reservations
51 (`exclusion_set', `presence_set', and `absence_set').
53 5. No reverse automata are generated. Trace instruction scheduling
54 requires this. It can be easily added in the future if we
57 6. Union of automaton states are not generated yet. It is planned
58 to be implemented. Such feature is needed to make more accurate
59 interlock insn scheduling to get state describing functional
60 unit reservation in a joint CFG point.
63 /* This file code processes constructions of machine description file
64 which describes automaton used for recognition of processor pipeline
65 hazards by insn scheduler and can be used for other tasks (such as
68 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
69 `gen_bypass', `gen_excl_set', `gen_presence_set',
70 `gen_absence_set', `gen_automaton', `gen_automata_option',
71 `gen_reserv', `gen_insn_reserv' are called from file
72 `genattrtab.c'. They transform RTL constructions describing
73 automata in .md file into internal representation convenient for
76 The translator major function `expand_automata' processes the
77 description internal representation into finite state automaton.
80 o checking correctness of the automaton pipeline description
81 (major function is `check_all_description').
83 o generating automaton (automata) from the description (major
84 function is `make_automaton').
86 o optional transformation of nondeterministic finite state
87 automata into deterministic ones if the alternative operator
88 `|' is treated nondeterministicly in the description (major
89 function is NDFA_to_DFA).
91 o optional minimization of the finite state automata by merging
92 equivalent automaton states (major function is `minimize_DFA').
94 o forming tables (some as comb vectors) and attributes
95 representing the automata (functions output_..._table).
97 Function `write_automata' outputs the created finite state
98 automaton as different tables and functions which works with the
99 automata to inquire automaton state and to change its state. These
100 function are used by gcc instruction scheduler and may be some
122 #include "genattrtab.h"
124 #define obstack_chunk_alloc xmalloc
125 #define obstack_chunk_free free
127 /* Positions in machine description file. Now they are not used. But
128 they could be used in the future for better diagnostic messages. */
131 /* The following is element of vector of current (and planned in the
132 future) functional unit reservations. */
133 typedef unsigned HOST_WIDE_INT set_el_t
;
135 /* Reservations of function units are represented by value of the following
137 typedef set_el_t
*reserv_sets_t
;
139 /* The following structure represents variable length array (vla) of
140 pointers and HOST WIDE INTs. We could be use only varray. But we
141 add new lay because we add elements very frequently and this could
142 stress OS allocator when varray is used only. */
144 size_t length
; /* current size of vla. */
145 varray_type varray
; /* container for vla. */
148 typedef vla_ptr_t vla_hwint_t
;
150 /* The following structure describes a ticker. */
153 /* The following member value is time of the ticker creation with
154 taking into account time when the ticker is off. Active time of
155 the ticker is current time minus the value. */
156 int modified_creation_time
;
157 /* The following member value is time (incremented by one) when the
158 ticker was off. Zero value means that now the ticker is on. */
159 int incremented_off_time
;
162 /* The ticker is represented by the following type. */
163 typedef struct ticker ticker_t
;
165 /* The following type describes elements of output vectors. */
166 typedef HOST_WIDE_INT vect_el_t
;
168 /* Forward declaration of structures of internal representation of
169 pipeline description based on NDFA. */
174 struct automaton_decl
;
175 struct unit_rel_decl
;
177 struct insn_reserv_decl
;
180 struct result_regexp
;
181 struct reserv_regexp
;
182 struct nothing_regexp
;
183 struct sequence_regexp
;
184 struct repeat_regexp
;
195 struct state_ainsn_table
;
197 /* The following typedefs are for brevity. */
198 typedef struct unit_decl
*unit_decl_t
;
199 typedef struct decl
*decl_t
;
200 typedef struct regexp
*regexp_t
;
201 typedef struct unit_set_el
*unit_set_el_t
;
202 typedef struct alt_state
*alt_state_t
;
203 typedef struct state
*state_t
;
204 typedef struct arc
*arc_t
;
205 typedef struct ainsn
*ainsn_t
;
206 typedef struct automaton
*automaton_t
;
207 typedef struct automata_list_el
*automata_list_el_t
;
208 typedef struct state_ainsn_table
*state_ainsn_table_t
;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
213 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
214 initiate_automaton_gen, expand_automata, write_automata are
215 described on the file top because the functions are called from
218 static void *create_node
PARAMS ((size_t));
219 static void *copy_node
PARAMS ((void *, size_t));
220 static char *check_name
PARAMS ((char *, pos_t
));
221 static char *next_sep_el
PARAMS ((char **, int, int));
222 static int n_sep_els
PARAMS ((char *, int, int));
223 static char **get_str_vect
PARAMS ((char *, int *, int, int));
224 static regexp_t gen_regexp_el
PARAMS ((char *));
225 static regexp_t gen_regexp_repeat
PARAMS ((char *));
226 static regexp_t gen_regexp_allof
PARAMS ((char *));
227 static regexp_t gen_regexp_oneof
PARAMS ((char *));
228 static regexp_t gen_regexp_sequence
PARAMS ((char *));
229 static regexp_t gen_regexp
PARAMS ((char *));
231 static unsigned string_hash
PARAMS ((const char *));
232 static unsigned automaton_decl_hash
PARAMS ((const void *));
233 static int automaton_decl_eq_p
PARAMS ((const void *,
235 static decl_t insert_automaton_decl
PARAMS ((decl_t
));
236 static decl_t find_automaton_decl
PARAMS ((char *));
237 static void initiate_automaton_decl_table
PARAMS ((void));
238 static void finish_automaton_decl_table
PARAMS ((void));
240 static unsigned insn_decl_hash
PARAMS ((const void *));
241 static int insn_decl_eq_p
PARAMS ((const void *,
243 static decl_t insert_insn_decl
PARAMS ((decl_t
));
244 static decl_t find_insn_decl
PARAMS ((char *));
245 static void initiate_insn_decl_table
PARAMS ((void));
246 static void finish_insn_decl_table
PARAMS ((void));
248 static unsigned decl_hash
PARAMS ((const void *));
249 static int decl_eq_p
PARAMS ((const void *,
251 static decl_t insert_decl
PARAMS ((decl_t
));
252 static decl_t find_decl
PARAMS ((char *));
253 static void initiate_decl_table
PARAMS ((void));
254 static void finish_decl_table
PARAMS ((void));
256 static unit_set_el_t process_excls
PARAMS ((char **, int, pos_t
));
257 static void add_excls
PARAMS ((unit_set_el_t
, unit_set_el_t
,
259 static unit_set_el_t process_presence_absence
260 PARAMS ((char **, int, pos_t
, int));
261 static void add_presence_absence
PARAMS ((unit_set_el_t
, unit_set_el_t
,
263 static void process_decls
PARAMS ((void));
264 static struct bypass_decl
*find_bypass
PARAMS ((struct bypass_decl
*,
265 struct insn_reserv_decl
*));
266 static void check_automaton_usage
PARAMS ((void));
267 static regexp_t process_regexp
PARAMS ((regexp_t
));
268 static void process_regexp_decls
PARAMS ((void));
269 static void check_usage
PARAMS ((void));
270 static int loop_in_regexp
PARAMS ((regexp_t
, decl_t
));
271 static void check_loops_in_regexps
PARAMS ((void));
272 static int process_regexp_cycles
PARAMS ((regexp_t
, int));
273 static void evaluate_max_reserv_cycles
PARAMS ((void));
274 static void check_all_description
PARAMS ((void));
276 static ticker_t create_ticker
PARAMS ((void));
277 static void ticker_off
PARAMS ((ticker_t
*));
278 static void ticker_on
PARAMS ((ticker_t
*));
279 static int active_time
PARAMS ((ticker_t
));
280 static void print_active_time
PARAMS ((FILE *, ticker_t
));
282 static void add_advance_cycle_insn_decl
PARAMS ((void));
284 static alt_state_t get_free_alt_state
PARAMS ((void));
285 static void free_alt_state
PARAMS ((alt_state_t
));
286 static void free_alt_states
PARAMS ((alt_state_t
));
287 static int alt_state_cmp
PARAMS ((const void *alt_state_ptr_1
,
288 const void *alt_state_ptr_2
));
289 static alt_state_t uniq_sort_alt_states
PARAMS ((alt_state_t
));
290 static int alt_states_eq
PARAMS ((alt_state_t
, alt_state_t
));
291 static void initiate_alt_states
PARAMS ((void));
292 static void finish_alt_states
PARAMS ((void));
294 static reserv_sets_t alloc_empty_reserv_sets
PARAMS ((void));
295 static unsigned reserv_sets_hash_value
PARAMS ((reserv_sets_t
));
296 static int reserv_sets_cmp
PARAMS ((reserv_sets_t
, reserv_sets_t
));
297 static int reserv_sets_eq
PARAMS ((reserv_sets_t
, reserv_sets_t
));
298 static void set_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
299 static int test_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
300 static int it_is_empty_reserv_sets
PARAMS ((reserv_sets_t
))
302 static int reserv_sets_are_intersected
PARAMS ((reserv_sets_t
, reserv_sets_t
));
303 static void reserv_sets_shift
PARAMS ((reserv_sets_t
, reserv_sets_t
));
304 static void reserv_sets_or
PARAMS ((reserv_sets_t
, reserv_sets_t
,
306 static void reserv_sets_and
PARAMS ((reserv_sets_t
, reserv_sets_t
,
309 static void output_cycle_reservs
PARAMS ((FILE *, reserv_sets_t
,
311 static void output_reserv_sets
PARAMS ((FILE *, reserv_sets_t
));
312 static state_t get_free_state
PARAMS ((int, automaton_t
));
313 static void free_state
PARAMS ((state_t
));
314 static unsigned state_hash
PARAMS ((const void *));
315 static int state_eq_p
PARAMS ((const void *, const void *));
316 static state_t insert_state
PARAMS ((state_t
));
317 static void set_state_reserv
PARAMS ((state_t
, int, int));
318 static int intersected_state_reservs_p
PARAMS ((state_t
, state_t
));
319 static state_t states_union
PARAMS ((state_t
, state_t
));
320 static state_t state_shift
PARAMS ((state_t
));
321 static void initiate_states
PARAMS ((void));
322 static void finish_states
PARAMS ((void));
324 static void free_arc
PARAMS ((arc_t
));
325 static void remove_arc
PARAMS ((state_t
, arc_t
));
326 static arc_t find_arc
PARAMS ((state_t
, state_t
, ainsn_t
));
327 static arc_t add_arc
PARAMS ((state_t
, state_t
, ainsn_t
, int));
328 static arc_t first_out_arc
PARAMS ((state_t
));
329 static arc_t next_out_arc
PARAMS ((arc_t
));
330 static void initiate_arcs
PARAMS ((void));
331 static void finish_arcs
PARAMS ((void));
333 static automata_list_el_t get_free_automata_list_el
PARAMS ((void));
334 static void free_automata_list_el
PARAMS ((automata_list_el_t
));
335 static void free_automata_list
PARAMS ((automata_list_el_t
));
336 static unsigned automata_list_hash
PARAMS ((const void *));
337 static int automata_list_eq_p
PARAMS ((const void *, const void *));
338 static void initiate_automata_lists
PARAMS ((void));
339 static void automata_list_start
PARAMS ((void));
340 static void automata_list_add
PARAMS ((automaton_t
));
341 static automata_list_el_t automata_list_finish
PARAMS ((void));
342 static void finish_automata_lists
PARAMS ((void));
344 static void initiate_excl_sets
PARAMS ((void));
345 static reserv_sets_t get_excl_set
PARAMS ((reserv_sets_t
));
347 static void initiate_presence_absence_sets
PARAMS ((void));
348 static reserv_sets_t get_presence_absence_set
PARAMS ((reserv_sets_t
, int));
350 static regexp_t copy_insn_regexp
PARAMS ((regexp_t
));
351 static regexp_t transform_1
PARAMS ((regexp_t
));
352 static regexp_t transform_2
PARAMS ((regexp_t
));
353 static regexp_t transform_3
PARAMS ((regexp_t
));
354 static regexp_t regexp_transform_func
355 PARAMS ((regexp_t
, regexp_t (*) (regexp_t
)));
356 static regexp_t transform_regexp
PARAMS ((regexp_t
));
357 static void transform_insn_regexps
PARAMS ((void));
359 static void process_unit_to_form_the_same_automaton_unit_lists
360 PARAMS ((regexp_t
, regexp_t
, int));
361 static void form_the_same_automaton_unit_lists_from_regexp
PARAMS ((regexp_t
));
362 static void form_the_same_automaton_unit_lists
PARAMS ((void));
363 static void check_unit_distributions_to_automata
PARAMS ((void));
365 static int process_seq_for_forming_states
PARAMS ((regexp_t
, automaton_t
,
367 static void finish_forming_alt_state
PARAMS ((alt_state_t
,
369 static void process_alts_for_forming_states
PARAMS ((regexp_t
,
371 static void create_alt_states
PARAMS ((automaton_t
));
373 static void form_ainsn_with_same_reservs
PARAMS ((automaton_t
));
375 static void make_automaton
PARAMS ((automaton_t
));
376 static void form_arcs_marked_by_insn
PARAMS ((state_t
));
377 static void create_composed_state
PARAMS ((state_t
, arc_t
, vla_ptr_t
*));
378 static void NDFA_to_DFA
PARAMS ((automaton_t
));
379 static void pass_state_graph
PARAMS ((state_t
, void (*) (state_t
)));
380 static void pass_states
PARAMS ((automaton_t
,
381 void (*) (state_t
)));
382 static void initiate_pass_states
PARAMS ((void));
383 static void add_achieved_state
PARAMS ((state_t
));
384 static int set_out_arc_insns_equiv_num
PARAMS ((state_t
, int));
385 static void clear_arc_insns_equiv_num
PARAMS ((state_t
));
386 static void copy_equiv_class
PARAMS ((vla_ptr_t
*to
,
387 const vla_ptr_t
*from
));
388 static int state_is_differed
PARAMS ((state_t
, int, int));
389 static state_t init_equiv_class
PARAMS ((state_t
*states
, int));
390 static int partition_equiv_class
PARAMS ((state_t
*, int,
391 vla_ptr_t
*, int *));
392 static void evaluate_equiv_classes
PARAMS ((automaton_t
, vla_ptr_t
*));
393 static void merge_states
PARAMS ((automaton_t
, vla_ptr_t
*));
394 static void set_new_cycle_flags
PARAMS ((state_t
));
395 static void minimize_DFA
PARAMS ((automaton_t
));
396 static void incr_states_and_arcs_nums
PARAMS ((state_t
));
397 static void count_states_and_arcs
PARAMS ((automaton_t
, int *, int *));
398 static void build_automaton
PARAMS ((automaton_t
));
400 static void set_order_state_num
PARAMS ((state_t
));
401 static void enumerate_states
PARAMS ((automaton_t
));
403 static ainsn_t insert_ainsn_into_equiv_class
PARAMS ((ainsn_t
, ainsn_t
));
404 static void delete_ainsn_from_equiv_class
PARAMS ((ainsn_t
));
405 static void process_insn_equiv_class
PARAMS ((ainsn_t
, arc_t
*));
406 static void process_state_for_insn_equiv_partition
PARAMS ((state_t
));
407 static void set_insn_equiv_classes
PARAMS ((automaton_t
));
409 static double estimate_one_automaton_bound
PARAMS ((void));
410 static int compare_max_occ_cycle_nums
PARAMS ((const void *,
412 static void units_to_automata_heuristic_distr
PARAMS ((void));
413 static ainsn_t create_ainsns
PARAMS ((void));
414 static void units_to_automata_distr
PARAMS ((void));
415 static void create_automata
PARAMS ((void));
417 static void form_regexp
PARAMS ((regexp_t
));
418 static const char *regexp_representation
PARAMS ((regexp_t
));
419 static void finish_regexp_representation
PARAMS ((void));
421 static void output_range_type
PARAMS ((FILE *, long int, long int));
422 static int longest_path_length
PARAMS ((state_t
));
423 static void process_state_longest_path_length
PARAMS ((state_t
));
424 static void output_dfa_max_issue_rate
PARAMS ((void));
425 static void output_vect
PARAMS ((vect_el_t
*, int));
426 static void output_chip_member_name
PARAMS ((FILE *, automaton_t
));
427 static void output_temp_chip_member_name
PARAMS ((FILE *, automaton_t
));
428 static void output_translate_vect_name
PARAMS ((FILE *, automaton_t
));
429 static void output_trans_full_vect_name
PARAMS ((FILE *, automaton_t
));
430 static void output_trans_comb_vect_name
PARAMS ((FILE *, automaton_t
));
431 static void output_trans_check_vect_name
PARAMS ((FILE *, automaton_t
));
432 static void output_trans_base_vect_name
PARAMS ((FILE *, automaton_t
));
433 static void output_state_alts_full_vect_name
PARAMS ((FILE *, automaton_t
));
434 static void output_state_alts_comb_vect_name
PARAMS ((FILE *, automaton_t
));
435 static void output_state_alts_check_vect_name
PARAMS ((FILE *, automaton_t
));
436 static void output_state_alts_base_vect_name
PARAMS ((FILE *, automaton_t
));
437 static void output_min_issue_delay_vect_name
PARAMS ((FILE *, automaton_t
));
438 static void output_dead_lock_vect_name
PARAMS ((FILE *, automaton_t
));
439 static void output_reserved_units_table_name
PARAMS ((FILE *, automaton_t
));
440 static void output_state_member_type
PARAMS ((FILE *, automaton_t
));
441 static void output_chip_definitions
PARAMS ((void));
442 static void output_translate_vect
PARAMS ((automaton_t
));
443 static int comb_vect_p
PARAMS ((state_ainsn_table_t
));
444 static state_ainsn_table_t create_state_ainsn_table
PARAMS ((automaton_t
));
445 static void output_state_ainsn_table
446 PARAMS ((state_ainsn_table_t
, char *, void (*) (FILE *, automaton_t
),
447 void (*) (FILE *, automaton_t
), void (*) (FILE *, automaton_t
),
448 void (*) (FILE *, automaton_t
)));
449 static void add_vect
PARAMS ((state_ainsn_table_t
,
450 int, vect_el_t
*, int));
451 static int out_state_arcs_num
PARAMS ((state_t
));
452 static int compare_transition_els_num
PARAMS ((const void *, const void *));
453 static void add_vect_el
PARAMS ((vla_hwint_t
*,
455 static void add_states_vect_el
PARAMS ((state_t
));
456 static void output_trans_table
PARAMS ((automaton_t
));
457 static void output_state_alts_table
PARAMS ((automaton_t
));
458 static int min_issue_delay_pass_states
PARAMS ((state_t
, ainsn_t
));
459 static int min_issue_delay
PARAMS ((state_t
, ainsn_t
));
460 static void initiate_min_issue_delay_pass_states
PARAMS ((void));
461 static void output_min_issue_delay_table
PARAMS ((automaton_t
));
462 static void output_dead_lock_vect
PARAMS ((automaton_t
));
463 static void output_reserved_units_table
PARAMS ((automaton_t
));
464 static void output_tables
PARAMS ((void));
465 static void output_max_insn_queue_index_def
PARAMS ((void));
466 static void output_insn_code_cases
PARAMS ((void (*) (automata_list_el_t
)));
467 static void output_automata_list_min_issue_delay_code
PARAMS ((automata_list_el_t
));
468 static void output_internal_min_issue_delay_func
PARAMS ((void));
469 static void output_automata_list_transition_code
PARAMS ((automata_list_el_t
));
470 static void output_internal_trans_func
PARAMS ((void));
471 static void output_internal_insn_code_evaluation
PARAMS ((const char *,
473 static void output_dfa_insn_code_func
PARAMS ((void));
474 static void output_trans_func
PARAMS ((void));
475 static void output_automata_list_state_alts_code
PARAMS ((automata_list_el_t
));
476 static void output_internal_state_alts_func
PARAMS ((void));
477 static void output_state_alts_func
PARAMS ((void));
478 static void output_min_issue_delay_func
PARAMS ((void));
479 static void output_internal_dead_lock_func
PARAMS ((void));
480 static void output_dead_lock_func
PARAMS ((void));
481 static void output_internal_reset_func
PARAMS ((void));
482 static void output_size_func
PARAMS ((void));
483 static void output_reset_func
PARAMS ((void));
484 static void output_min_insn_conflict_delay_func
PARAMS ((void));
485 static void output_internal_insn_latency_func
PARAMS ((void));
486 static void output_insn_latency_func
PARAMS ((void));
487 static void output_print_reservation_func
PARAMS ((void));
488 static int units_cmp
PARAMS ((const void *,
490 static void output_get_cpu_unit_code_func
PARAMS ((void));
491 static void output_cpu_unit_reservation_p
PARAMS ((void));
492 static void output_dfa_start_func
PARAMS ((void));
493 static void output_dfa_finish_func
PARAMS ((void));
495 static void output_regexp
PARAMS ((regexp_t
));
496 static void output_unit_set_el_list
PARAMS ((unit_set_el_t
));
497 static void output_description
PARAMS ((void));
498 static void output_automaton_name
PARAMS ((FILE *, automaton_t
));
499 static void output_automaton_units
PARAMS ((automaton_t
));
500 static void add_state_reservs
PARAMS ((state_t
));
501 static void output_state_arcs
PARAMS ((state_t
));
502 static int state_reservs_cmp
PARAMS ((const void *,
504 static void remove_state_duplicate_reservs
PARAMS ((void));
505 static void output_state
PARAMS ((state_t
));
506 static void output_automaton_descriptions
PARAMS ((void));
507 static void output_statistics
PARAMS ((FILE *));
508 static void output_time_statistics
PARAMS ((FILE *));
509 static void generate
PARAMS ((void));
511 static void make_insn_alts_attr
PARAMS ((void));
512 static void make_internal_dfa_insn_code_attr
PARAMS ((void));
513 static void make_default_insn_latency_attr
PARAMS ((void));
514 static void make_bypass_attr
PARAMS ((void));
515 static const char *file_name_suffix
PARAMS ((const char *));
516 static const char *base_file_name
PARAMS ((const char *));
517 static void check_automata_insn_issues
PARAMS ((void));
518 static void add_automaton_state
PARAMS ((state_t
));
519 static void form_important_insn_automata_lists
PARAMS ((void));
521 /* Undefined position. */
522 static pos_t no_pos
= 0;
524 /* All IR is stored in the following obstack. */
525 static struct obstack irp
;
529 /* This page contains code for work with variable length array (vla)
530 of pointers. We could be use only varray. But we add new lay
531 because we add elements very frequently and this could stress OS
532 allocator when varray is used only. */
534 /* Start work with vla. */
535 #define VLA_PTR_CREATE(vla, allocated_length, name) \
538 vla_ptr_t *vla_ptr = &(vla); \
540 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
541 vla_ptr->length = 0; \
545 /* Finish work with the vla. */
546 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
548 /* Return start address of the vla. */
549 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
551 /* Address of the last element of the vla. Do not use side effects in
552 the macro argument. */
553 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
555 /* Nullify the vla. */
556 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
558 /* Shorten the vla on given number bytes. */
559 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
561 /* Expand the vla on N elements. The values of new elements are
563 #define VLA_PTR_EXPAND(vla, n) \
565 vla_ptr_t *expand_vla_ptr = &(vla); \
566 size_t new_length = (n) + expand_vla_ptr->length; \
568 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
569 VARRAY_GROW (expand_vla_ptr->varray, \
570 (new_length - expand_vla_ptr->length < 128 \
571 ? expand_vla_ptr->length + 128 : new_length)); \
572 expand_vla_ptr->length = new_length; \
575 /* Add element to the end of the vla. */
576 #define VLA_PTR_ADD(vla, ptr) \
578 vla_ptr_t *vla_ptr = &(vla); \
580 VLA_PTR_EXPAND (*vla_ptr, 1); \
581 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
584 /* Length of the vla in elements. */
585 #define VLA_PTR_LENGTH(vla) ((vla).length)
587 /* N-th element of the vla. */
588 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
591 /* The following macros are analogous to the previous ones but for
592 VLAs of HOST WIDE INTs. */
594 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
596 vla_hwint_t *vla_ptr = &(vla); \
598 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
599 vla_ptr->length = 0; \
602 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
604 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
606 /* Do not use side effects in the macro argument. */
607 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
610 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
612 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
614 #define VLA_HWINT_EXPAND(vla, n) \
616 vla_hwint_t *expand_vla_ptr = &(vla); \
617 size_t new_length = (n) + expand_vla_ptr->length; \
619 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
620 VARRAY_GROW (expand_vla_ptr->varray, \
621 (new_length - expand_vla_ptr->length < 128 \
622 ? expand_vla_ptr->length + 128 : new_length)); \
623 expand_vla_ptr->length = new_length; \
626 #define VLA_HWINT_ADD(vla, ptr) \
628 vla_hwint_t *vla_ptr = &(vla); \
630 VLA_HWINT_EXPAND (*vla_ptr, 1); \
631 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
634 #define VLA_HWINT_LENGTH(vla) ((vla).length)
636 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
640 /* Options with the following names can be set up in automata_option
641 construction. Because the strings occur more one time we use the
644 #define NO_MINIMIZATION_OPTION "-no-minimization"
646 #define W_OPTION "-w"
648 #define NDFA_OPTION "-ndfa"
650 /* The following flags are set up by function `initiate_automaton_gen'. */
652 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
653 static int ndfa_flag
;
655 /* Do not make minimization of DFA (`-no-minimization'). */
656 static int no_minimization_flag
;
658 /* Value of this variable is number of automata being generated. The
659 actual number of automata may be less this value if there is not
660 sufficient number of units. This value is defined by argument of
661 option `-split' or by constructions automaton if the value is zero
662 (it is default value of the argument). */
663 static int split_argument
;
665 /* Flag of output time statistics (`-time'). */
666 static int time_flag
;
668 /* Flag of creation of description file which contains description of
669 result automaton and statistics information (`-v'). */
672 /* Flag of generating warning instead of error for non-critical errors
677 /* Output file for pipeline hazard recognizer (PHR) being generated.
678 The value is NULL if the file is not defined. */
679 static FILE *output_file
;
681 /* Description file of PHR. The value is NULL if the file is not
683 static FILE *output_description_file
;
685 /* PHR description file name. */
686 static char *output_description_file_name
;
688 /* Value of the following variable is node representing description
689 being processed. This is start point of IR. */
690 static struct description
*description
;
694 /* This page contains description of IR structure (nodes). */
708 /* This describes define_cpu_unit and define_query_cpu_unit (see file
713 /* NULL if the automaton name is absent. */
714 char *automaton_name
;
715 /* If the following value is not zero, the cpu unit reservation is
716 described in define_query_cpu_unit. */
719 /* The following fields are defined by checker. */
721 /* The following field value is nonzero if the unit is used in an
725 /* The following field value is used to form cyclic lists of units
726 which should be in the same automaton because the unit is
727 reserved not on all alternatives of a regexp on a cycle. */
728 unit_decl_t the_same_automaton_unit
;
729 /* The following field is TRUE if we already reported that the unit
730 is not in the same automaton. */
731 int the_same_automaton_message_reported_p
;
733 /* The following field value is order number (0, 1, ...) of given
736 /* The following field value is corresponding declaration of
737 automaton which was given in description. If the field value is
738 NULL then automaton in the unit declaration was absent. */
739 struct automaton_decl
*automaton_decl
;
740 /* The following field value is maximal cycle number (1, ...) on
741 which given unit occurs in insns. Zero value means that given
742 unit is not used in insns. */
743 int max_occ_cycle_num
;
744 /* The following list contains units which conflict with given
746 unit_set_el_t excl_list
;
747 /* The following list contains units which are required to
748 reservation of given unit. */
749 unit_set_el_t presence_list
;
750 /* The following list contains units which should be not present in
751 reservation for given unit. */
752 unit_set_el_t absence_list
;
753 /* The following is used only when `query_p' has nonzero value.
754 This is query number for the unit. */
757 /* The following fields are defined by automaton generator. */
759 /* The following field value is number of the automaton to which
760 given unit belongs. */
761 int corresponding_automaton_num
;
764 /* This describes define_bypass (see file rtl.def). */
770 char *bypass_guard_name
;
772 /* The following fields are defined by checker. */
774 /* output and input insns of given bypass. */
775 struct insn_reserv_decl
*out_insn_reserv
;
776 struct insn_reserv_decl
*in_insn_reserv
;
777 /* The next bypass for given output insn. */
778 struct bypass_decl
*next
;
781 /* This describes define_automaton (see file rtl.def). */
782 struct automaton_decl
786 /* The following fields are defined by automaton generator. */
788 /* The following field value is nonzero if the automaton is used in
789 an regexp definition. */
790 char automaton_is_used
;
792 /* The following fields are defined by checker. */
794 /* The following field value is the corresponding automaton. This
795 field is not NULL only if the automaton is present in unit
796 declarations and the automatic partition on automata is not
798 automaton_t corresponding_automaton
;
801 /* This describes unit relations: exclusion_set, presence_set, or
802 absence_set (see file rtl.def). */
806 int first_list_length
;
810 /* This describes define_reservation (see file rtl.def). */
816 /* The following fields are defined by checker. */
818 /* The following field value is nonzero if the unit is used in an
821 /* The following field is used to check up cycle in expression
826 /* This describes define_insn_reservartion (see file rtl.def). */
827 struct insn_reserv_decl
834 /* The following fields are defined by checker. */
836 /* The following field value is order number (0, 1, ...) of given
839 /* The following field value is list of bypasses in which given insn
841 struct bypass_decl
*bypass_list
;
843 /* The following fields are defined by automaton generator. */
845 /* The following field is the insn regexp transformed that
846 the regexp has not optional regexp, repetition regexp, and an
847 reservation name (i.e. reservation identifiers are changed by the
848 corresponding regexp) and all alternations are the topest level
849 of the regexp. The value can be NULL only if it is special
850 insn `cycle advancing'. */
851 regexp_t transformed_regexp
;
852 /* The following field value is list of arcs marked given
853 insn. The field is used in transfromation NDFA -> DFA. */
854 arc_t arcs_marked_by_insn
;
855 /* The two following fields are used during minimization of a finite state
857 /* The field value is number of equivalence class of state into
858 which arc marked by given insn enters from a state (fixed during
859 an automaton minimization). */
861 /* The field value is state_alts of arc leaving a state (fixed
862 during an automaton minimization) and marked by given insn
865 /* The following member value is the list to automata which can be
866 changed by the insn issue. */
867 automata_list_el_t important_automata_list
;
868 /* The following member is used to process insn once for output. */
872 /* This contains a declaration mentioned above. */
875 /* What node in the union? */
880 struct unit_decl unit
;
881 struct bypass_decl bypass
;
882 struct automaton_decl automaton
;
883 struct unit_rel_decl excl
;
884 struct unit_rel_decl presence
;
885 struct unit_rel_decl absence
;
886 struct reserv_decl reserv
;
887 struct insn_reserv_decl insn_reserv
;
891 /* The following structures represent parsed reservation strings. */
903 /* Cpu unit in reservation. */
907 unit_decl_t unit_decl
;
910 /* Define_reservation in a reservation. */
914 struct reserv_decl
*reserv_decl
;
917 /* Absence of reservation (represented by string `nothing'). */
918 struct nothing_regexp
920 /* This used to be empty but ISO C doesn't allow that. */
924 /* Representation of reservations separated by ',' (see file
926 struct sequence_regexp
929 regexp_t regexps
[1];
932 /* Representation of construction `repeat' (see file rtl.def). */
939 /* Representation of reservations separated by '+' (see file
944 regexp_t regexps
[1];
947 /* Representation of reservations separated by '|' (see file
952 regexp_t regexps
[1];
955 /* Representation of a reservation string. */
958 /* What node in the union? */
959 enum regexp_mode mode
;
963 struct unit_regexp unit
;
964 struct reserv_regexp reserv
;
965 struct nothing_regexp nothing
;
966 struct sequence_regexp sequence
;
967 struct repeat_regexp repeat
;
968 struct allof_regexp allof
;
969 struct oneof_regexp oneof
;
973 /* Reperesents description of pipeline hazard description based on
979 /* The following fields are defined by checker. */
981 /* The following fields values are correspondingly number of all
982 units, query units, and insns in the description. */
986 /* The following field value is max length (in cycles) of
987 reservations of insns. The field value is defined only for
989 int max_insn_reserv_cycles
;
991 /* The following fields are defined by automaton generator. */
993 /* The following field value is the first automaton. */
994 automaton_t first_automaton
;
996 /* The following field is created by pipeline hazard parser and
997 contains all declarations. We allocate additional entry for
998 special insn "cycle advancing" which is added by the automaton
1005 /* The following nodes are created in automaton checker. */
1007 /* The following nodes represent exclusion, presence, absence set for
1008 cpu units. Each element are accessed through only one excl_list,
1009 presence_list, absence_list. */
1012 unit_decl_t unit_decl
;
1013 unit_set_el_t next_unit_set_el
;
1018 /* The following nodes are created in automaton generator. */
1020 /* The following node type describes state automaton. The state may
1021 be deterministic or non-deterministic. Non-deterministic state has
1022 several component states which represent alternative cpu units
1023 reservations. The state also is used for describing a
1024 deterministic reservation of automaton insn. */
1027 /* The following member value is nonzero if there is a transition by
1030 /* The following field is list of processor unit reservations on
1032 reserv_sets_t reservs
;
1033 /* The following field is unique number of given state between other
1036 /* The following field value is automaton to which given state
1038 automaton_t automaton
;
1039 /* The following field value is the first arc output from given
1041 arc_t first_out_arc
;
1042 /* The following field is used to form NDFA. */
1043 char it_was_placed_in_stack_for_NDFA_forming
;
1044 /* The following field is used to form DFA. */
1045 char it_was_placed_in_stack_for_DFA_forming
;
1046 /* The following field is used to transform NDFA to DFA. The field
1047 value is not NULL if the state is a compound state. In this case
1048 the value of field `unit_sets_list' is NULL. All states in the
1049 list are in the hash table. The list is formed through field
1050 `next_sorted_alt_state'. */
1051 alt_state_t component_states
;
1052 /* The following field is used for passing graph of states. */
1054 /* The list of states belonging to one equivalence class is formed
1055 with the aid of the following field. */
1056 state_t next_equiv_class_state
;
1057 /* The two following fields are used during minimization of a finite
1059 int equiv_class_num_1
, equiv_class_num_2
;
1060 /* The following field is used during minimization of a finite state
1061 automaton. The field value is state corresponding to equivalence
1062 class to which given state belongs. */
1063 state_t equiv_class_state
;
1064 /* The following field value is the order number of given state.
1065 The states in final DFA is enumerated with the aid of the
1067 int order_state_num
;
1068 /* This member is used for passing states for searching minimal
1071 /* The following member is used to evaluate min issue delay of insn
1073 int min_insn_issue_delay
;
1074 /* The following member is used to evaluate max issue rate of the
1075 processor. The value of the member is maximal length of the path
1076 from given state no containing arcs marked by special insn `cycle
1078 int longest_path_length
;
1081 /* The following macro is an initial value of member
1082 `longest_path_length' of a state. */
1083 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1085 /* Automaton arc. */
1088 /* The following field refers for the state into which given arc
1091 /* The following field describes that the insn issue (with cycle
1092 advancing for special insn `cycle advancing' and without cycle
1093 advancing for others) makes transition from given state to
1094 another given state. */
1096 /* The following field value is the next arc output from the same
1099 /* List of arcs marked given insn is formed with the following
1100 field. The field is used in transfromation NDFA -> DFA. */
1101 arc_t next_arc_marked_by_insn
;
1102 /* The following field is defined if NDFA_FLAG is zero. The member
1103 value is number of alternative reservations which can be used for
1104 transition for given state by given insn. */
1108 /* The following node type describes a deterministic alternative in
1109 non-deterministic state which characterizes cpu unit reservations
1110 of automaton insn or which is part of NDFA. */
1113 /* The following field is a determinist state which characterizes
1114 unit reservations of the instruction. */
1116 /* The following field refers to the next state which characterizes
1117 unit reservations of the instruction. */
1118 alt_state_t next_alt_state
;
1119 /* The following field refers to the next state in sorted list. */
1120 alt_state_t next_sorted_alt_state
;
1123 /* The following node type describes insn of automaton. They are
1124 labels of FA arcs. */
1127 /* The following field value is the corresponding insn declaration
1129 struct insn_reserv_decl
*insn_reserv_decl
;
1130 /* The following field value is the next insn declaration for an
1133 /* The following field is states which characterize automaton unit
1134 reservations of the instruction. The value can be NULL only if it
1135 is special insn `cycle advancing'. */
1136 alt_state_t alt_states
;
1137 /* The following field is sorted list of states which characterize
1138 automaton unit reservations of the instruction. The value can be
1139 NULL only if it is special insn `cycle advancing'. */
1140 alt_state_t sorted_alt_states
;
1141 /* The following field refers the next automaton insn with
1142 the same reservations. */
1143 ainsn_t next_same_reservs_insn
;
1144 /* The following field is flag of the first automaton insn with the
1145 same reservations in the declaration list. Only arcs marked such
1146 insn is present in the automaton. This significantly decreases
1147 memory requirements especially when several automata are
1149 char first_insn_with_same_reservs
;
1150 /* The following member has nonzero value if there is arc from state of
1151 the automaton marked by the ainsn. */
1153 /* Cyclic list of insns of an equivalence class is formed with the
1154 aid of the following field. */
1155 ainsn_t next_equiv_class_insn
;
1156 /* The following field value is nonzero if the insn declaration is
1157 the first insn declaration with given equivalence number. */
1158 char first_ainsn_with_given_equialence_num
;
1159 /* The following field is number of class of equivalence of insns.
1160 It is necessary because many insns may be equivalent with the
1161 point of view of pipeline hazards. */
1162 int insn_equiv_class_num
;
1163 /* The following member value is TRUE if there is an arc in the
1164 automaton marked by the insn into another state. In other
1165 words, the insn can change the state of the automaton. */
1169 /* The folowing describes an automaton for PHR. */
1172 /* The following field value is the list of insn declarations for
1175 /* The following field value is the corresponding automaton
1176 declaration. This field is not NULL only if the automatic
1177 partition on automata is not used. */
1178 struct automaton_decl
*corresponding_automaton_decl
;
1179 /* The following field value is the next automaton. */
1180 automaton_t next_automaton
;
1181 /* The following field is start state of FA. There are not unit
1182 reservations in the state. */
1183 state_t start_state
;
1184 /* The following field value is number of equivalence classes of
1185 insns (see field `insn_equiv_class_num' in
1186 `insn_reserv_decl'). */
1187 int insn_equiv_classes_num
;
1188 /* The following field value is number of states of final DFA. */
1189 int achieved_states_num
;
1190 /* The following field value is the order number (0, 1, ...) of
1192 int automaton_order_num
;
1193 /* The following fields contain statistics information about
1194 building automaton. */
1195 int NDFA_states_num
, DFA_states_num
;
1196 /* The following field value is defined only if minimization of DFA
1198 int minimal_DFA_states_num
;
1199 int NDFA_arcs_num
, DFA_arcs_num
;
1200 /* The following field value is defined only if minimization of DFA
1202 int minimal_DFA_arcs_num
;
1203 /* The following two members refer for two table state x ainsn ->
1205 state_ainsn_table_t trans_table
;
1206 state_ainsn_table_t state_alts_table
;
1207 /* The following member value is maximal value of min issue delay
1208 for insns of the automaton. */
1210 /* Usually min issue delay is small and we can place several (2, 4,
1211 8) elements in one vector element. So the compression factor can
1212 be 1 (no compression), 2, 4, 8. */
1213 int min_issue_delay_table_compression_factor
;
1216 /* The following is the element of the list of automata. */
1217 struct automata_list_el
1219 /* The automaton itself. */
1220 automaton_t automaton
;
1221 /* The next automata set element. */
1222 automata_list_el_t next_automata_list_el
;
1225 /* The following structure describes a table state X ainsn -> int(>= 0). */
1226 struct state_ainsn_table
1228 /* Automaton to which given table belongs. */
1229 automaton_t automaton
;
1230 /* The following tree vectors for comb vector implementation of the
1232 vla_hwint_t comb_vect
;
1233 vla_hwint_t check_vect
;
1234 vla_hwint_t base_vect
;
1235 /* This is simple implementation of the table. */
1236 vla_hwint_t full_vect
;
1237 /* Minimal and maximal values of the previous vectors. */
1238 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1239 int min_base_vect_el_value
, max_base_vect_el_value
;
1242 /* Create IR structure (node). */
1249 obstack_blank (&irp
, size
);
1250 result
= obstack_base (&irp
);
1251 obstack_finish (&irp
);
1252 /* Default values of members are NULL and zero. */
1253 memset (result
, 0, size
);
1257 /* Copy IR structure (node). */
1259 copy_node (from
, size
)
1264 result
= create_node (size
);
1265 memcpy (result
, from
, size
);
1269 /* The function checks that NAME does not contain quotes (`"'). */
1271 check_name (name
, pos
)
1273 pos_t pos ATTRIBUTE_UNUSED
;
1277 for (str
= name
; *str
!= '\0'; str
++)
1279 error ("Name `%s' contains quotes", name
);
1283 /* Pointers top all declartions during IR generation are stored in the
1285 static vla_ptr_t decls
;
1287 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1288 string containing the next separated element, taking parentheses
1289 into account if PAR_FLAG has nonzero value. Advance the pointer to
1290 after the string scanned, or the end-of-string. Return NULL if at
1293 next_sep_el (pstr
, sep
, par_flag
)
1303 /* Remove leading whitespaces. */
1304 while (isspace ((int) **pstr
))
1311 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1313 if (par_flag
&& *p
== '(')
1315 else if (par_flag
&& *p
== ')')
1317 else if (pars_num
== 0 && *p
== sep
)
1319 if (pars_num
== 0 && isspace ((int) *p
))
1323 for (; n_spaces
!= 0; n_spaces
--)
1324 obstack_1grow (&irp
, p
[-n_spaces
]);
1325 obstack_1grow (&irp
, *p
);
1328 obstack_1grow (&irp
, '\0');
1329 out_str
= obstack_base (&irp
);
1330 obstack_finish (&irp
);
1339 /* Given a string and a separator, return the number of separated
1340 elements in it, taking parentheses into account if PAR_FLAG has
1341 nonzero value. Return 0 for the null string, -1 if parantheses is
1344 n_sep_els (s
, sep
, par_flag
)
1355 for (pars_num
= 0, n
= 1; *s
; s
++)
1356 if (par_flag
&& *s
== '(')
1358 else if (par_flag
&& *s
== ')')
1360 else if (pars_num
== 0 && *s
== sep
)
1363 return (pars_num
!= 0 ? -1 : n
);
1366 /* Given a string and a separator, return vector of strings which are
1367 elements in the string and number of elements through els_num.
1368 Take parentheses into account if PAR_FLAG has nonzero value.
1369 Return 0 for the null string, -1 if parantheses are not balanced. */
1371 get_str_vect (str
, els_num
, sep
, par_flag
)
1381 *els_num
= n_sep_els (str
, sep
, par_flag
);
1384 obstack_blank (&irp
, sizeof (char *) * (*els_num
));
1385 vect
= (char **) obstack_base (&irp
);
1386 obstack_finish (&irp
);
1388 for (i
= 0; i
< *els_num
; i
++)
1389 vect
[i
] = next_sep_el (pstr
, sep
, par_flag
);
1390 if (next_sep_el (pstr
, sep
, par_flag
) != NULL
)
1395 /* Process a DEFINE_CPU_UNIT.
1397 This gives information about a unit contained in CPU. We fill a
1398 struct unit_decl with information used later by `expand_automata'. */
1404 char **str_cpu_units
;
1408 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1409 if (str_cpu_units
== NULL
)
1410 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1411 for (i
= 0; i
< vect_length
; i
++)
1413 decl
= create_node (sizeof (struct decl
));
1414 decl
->mode
= dm_unit
;
1416 decl
->decl
.unit
.name
= check_name (str_cpu_units
[i
], decl
->pos
);
1417 decl
->decl
.unit
.automaton_name
= (char *) XSTR (def
, 1);
1418 decl
->decl
.unit
.query_p
= 0;
1419 VLA_PTR_ADD (decls
, decl
);
1424 /* Process a DEFINE_QUERY_CPU_UNIT.
1426 This gives information about a unit contained in CPU. We fill a
1427 struct unit_decl with information used later by `expand_automata'. */
1429 gen_query_cpu_unit (def
)
1433 char **str_cpu_units
;
1437 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1438 if (str_cpu_units
== NULL
)
1439 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1440 for (i
= 0; i
< vect_length
; i
++)
1442 decl
= create_node (sizeof (struct decl
));
1443 decl
->mode
= dm_unit
;
1445 decl
->decl
.unit
.name
= check_name (str_cpu_units
[i
], decl
->pos
);
1446 decl
->decl
.unit
.automaton_name
= (char *) XSTR (def
, 1);
1447 decl
->decl
.unit
.query_p
= 1;
1448 VLA_PTR_ADD (decls
, decl
);
1453 /* Process a DEFINE_BYPASS.
1455 This gives information about a unit contained in the CPU. We fill
1456 in a struct bypass_decl with information used later by
1457 `expand_automata'. */
1469 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', 0);
1470 if (out_insns
== NULL
)
1471 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1472 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', 0);
1473 if (in_insns
== NULL
)
1474 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1475 for (i
= 0; i
< out_length
; i
++)
1476 for (j
= 0; j
< in_length
; j
++)
1478 decl
= create_node (sizeof (struct decl
));
1479 decl
->mode
= dm_bypass
;
1481 decl
->decl
.bypass
.latency
= XINT (def
, 0);
1482 decl
->decl
.bypass
.out_insn_name
= out_insns
[i
];
1483 decl
->decl
.bypass
.in_insn_name
= in_insns
[j
];
1484 decl
->decl
.bypass
.bypass_guard_name
= (char *) XSTR (def
, 3);
1485 VLA_PTR_ADD (decls
, decl
);
1490 /* Process an EXCLUSION_SET.
1492 This gives information about a cpu unit conflicts. We fill a
1493 struct unit_rel_decl (excl) with information used later by
1494 `expand_automata'. */
1500 char **first_str_cpu_units
;
1501 char **second_str_cpu_units
;
1502 int first_vect_length
;
1507 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1508 if (first_str_cpu_units
== NULL
)
1509 fatal ("invalid first string `%s' in exclusion_set", XSTR (def
, 0));
1510 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1512 if (second_str_cpu_units
== NULL
)
1513 fatal ("invalid second string `%s' in exclusion_set", XSTR (def
, 1));
1514 length
+= first_vect_length
;
1515 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1516 decl
->mode
= dm_excl
;
1518 decl
->decl
.excl
.names_num
= length
;
1519 decl
->decl
.excl
.first_list_length
= first_vect_length
;
1520 for (i
= 0; i
< length
; i
++)
1521 if (i
< first_vect_length
)
1522 decl
->decl
.excl
.names
[i
] = first_str_cpu_units
[i
];
1524 decl
->decl
.excl
.names
[i
] = second_str_cpu_units
[i
- first_vect_length
];
1525 VLA_PTR_ADD (decls
, decl
);
1529 /* Process a PRESENCE_SET.
1531 This gives information about a cpu unit reservation requirements.
1532 We fill a struct unit_rel_decl (presence) with information used
1533 later by `expand_automata'. */
1535 gen_presence_set (def
)
1539 char **first_str_cpu_units
;
1540 char **second_str_cpu_units
;
1541 int first_vect_length
;
1546 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1547 if (first_str_cpu_units
== NULL
)
1548 fatal ("invalid first string `%s' in presence_set", XSTR (def
, 0));
1549 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1551 if (second_str_cpu_units
== NULL
)
1552 fatal ("invalid second string `%s' in presence_set", XSTR (def
, 1));
1553 length
+= first_vect_length
;
1554 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1555 decl
->mode
= dm_presence
;
1557 decl
->decl
.presence
.names_num
= length
;
1558 decl
->decl
.presence
.first_list_length
= first_vect_length
;
1559 for (i
= 0; i
< length
; i
++)
1560 if (i
< first_vect_length
)
1561 decl
->decl
.presence
.names
[i
] = first_str_cpu_units
[i
];
1563 decl
->decl
.presence
.names
[i
]
1564 = second_str_cpu_units
[i
- first_vect_length
];
1565 VLA_PTR_ADD (decls
, decl
);
1569 /* Process an ABSENCE_SET.
1571 This gives information about a cpu unit reservation requirements.
1572 We fill a struct unit_rel_decl (absence) with information used
1573 later by `expand_automata'. */
1575 gen_absence_set (def
)
1579 char **first_str_cpu_units
;
1580 char **second_str_cpu_units
;
1581 int first_vect_length
;
1586 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1587 if (first_str_cpu_units
== NULL
)
1588 fatal ("invalid first string `%s' in absence_set", XSTR (def
, 0));
1589 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1591 if (second_str_cpu_units
== NULL
)
1592 fatal ("invalid second string `%s' in absence_set", XSTR (def
, 1));
1593 length
+= first_vect_length
;
1594 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1595 decl
->mode
= dm_absence
;
1597 decl
->decl
.absence
.names_num
= length
;
1598 decl
->decl
.absence
.first_list_length
= first_vect_length
;
1599 for (i
= 0; i
< length
; i
++)
1600 if (i
< first_vect_length
)
1601 decl
->decl
.absence
.names
[i
] = first_str_cpu_units
[i
];
1603 decl
->decl
.absence
.names
[i
]
1604 = second_str_cpu_units
[i
- first_vect_length
];
1605 VLA_PTR_ADD (decls
, decl
);
1609 /* Process a DEFINE_AUTOMATON.
1611 This gives information about a finite state automaton used for
1612 recognizing pipeline hazards. We fill a struct automaton_decl
1613 with information used later by `expand_automata'. */
1619 char **str_automata
;
1623 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1624 if (str_automata
== NULL
)
1625 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1626 for (i
= 0; i
< vect_length
; i
++)
1628 decl
= create_node (sizeof (struct decl
));
1629 decl
->mode
= dm_automaton
;
1631 decl
->decl
.automaton
.name
= check_name (str_automata
[i
], decl
->pos
);
1632 VLA_PTR_ADD (decls
, decl
);
1637 /* Process an AUTOMATA_OPTION.
1639 This gives information how to generate finite state automaton used
1640 for recognizing pipeline hazards. */
1642 gen_automata_option (def
)
1645 if (strcmp ((char *) XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1646 no_minimization_flag
= 1;
1647 else if (strcmp ((char *) XSTR (def
, 0), W_OPTION
+ 1) == 0)
1649 else if (strcmp ((char *) XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1652 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1655 /* Name in reservation to denote absence reservation. */
1656 #define NOTHING_NAME "nothing"
1658 /* The following string contains original reservation string being
1660 static char *reserv_str
;
1662 /* Parse an element in STR. */
1673 if (str
[len
- 1] != ')')
1674 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1675 str
[len
- 1] = '\0';
1676 regexp
= gen_regexp_sequence (str
+ 1);
1678 else if (strcmp (str
, NOTHING_NAME
) == 0)
1680 regexp
= create_node (sizeof (struct decl
));
1681 regexp
->mode
= rm_nothing
;
1685 regexp
= create_node (sizeof (struct decl
));
1686 regexp
->mode
= rm_unit
;
1687 regexp
->regexp
.unit
.name
= str
;
1692 /* Parse construction `repeat' in STR. */
1694 gen_regexp_repeat (str
)
1703 repeat_vect
= get_str_vect (str
, &els_num
, '*', 1);
1704 if (repeat_vect
== NULL
)
1705 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1708 regexp
= gen_regexp_el (repeat_vect
[0]);
1709 for (i
= 1; i
< els_num
; i
++)
1711 repeat
= create_node (sizeof (struct regexp
));
1712 repeat
->mode
= rm_repeat
;
1713 repeat
->regexp
.repeat
.regexp
= regexp
;
1714 repeat
->regexp
.repeat
.repeat_num
= atoi (repeat_vect
[i
]);
1715 if (repeat
->regexp
.repeat
.repeat_num
<= 1)
1716 fatal ("repetition `%s' <= 1 in reservation `%s'",
1723 return gen_regexp_el (str
);
1726 /* Parse reservation STR which possibly contains separator '+'. */
1728 gen_regexp_allof (str
)
1736 allof_vect
= get_str_vect (str
, &els_num
, '+', 1);
1737 if (allof_vect
== NULL
)
1738 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1741 allof
= create_node (sizeof (struct regexp
)
1742 + sizeof (regexp_t
) * (els_num
- 1));
1743 allof
->mode
= rm_allof
;
1744 allof
->regexp
.allof
.regexps_num
= els_num
;
1745 for (i
= 0; i
< els_num
; i
++)
1746 allof
->regexp
.allof
.regexps
[i
] = gen_regexp_repeat (allof_vect
[i
]);
1750 return gen_regexp_repeat (str
);
1753 /* Parse reservation STR which possibly contains separator '|'. */
1755 gen_regexp_oneof (str
)
1763 oneof_vect
= get_str_vect (str
, &els_num
, '|', 1);
1764 if (oneof_vect
== NULL
)
1765 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1768 oneof
= create_node (sizeof (struct regexp
)
1769 + sizeof (regexp_t
) * (els_num
- 1));
1770 oneof
->mode
= rm_oneof
;
1771 oneof
->regexp
.oneof
.regexps_num
= els_num
;
1772 for (i
= 0; i
< els_num
; i
++)
1773 oneof
->regexp
.oneof
.regexps
[i
] = gen_regexp_allof (oneof_vect
[i
]);
1777 return gen_regexp_allof (str
);
1780 /* Parse reservation STR which possibly contains separator ','. */
1782 gen_regexp_sequence (str
)
1786 char **sequence_vect
;
1790 sequence_vect
= get_str_vect (str
, &els_num
, ',', 1);
1793 sequence
= create_node (sizeof (struct regexp
)
1794 + sizeof (regexp_t
) * (els_num
- 1));
1795 sequence
->mode
= rm_sequence
;
1796 sequence
->regexp
.sequence
.regexps_num
= els_num
;
1797 for (i
= 0; i
< els_num
; i
++)
1798 sequence
->regexp
.sequence
.regexps
[i
]
1799 = gen_regexp_oneof (sequence_vect
[i
]);
1803 return gen_regexp_oneof (str
);
1806 /* Parse construction reservation STR. */
1812 return gen_regexp_sequence (str
);;
1815 /* Process a DEFINE_RESERVATION.
1817 This gives information about a reservation of cpu units. We fill
1818 in a struct reserv_decl with information used later by
1819 `expand_automata'. */
1826 decl
= create_node (sizeof (struct decl
));
1827 decl
->mode
= dm_reserv
;
1829 decl
->decl
.reserv
.name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
1830 decl
->decl
.reserv
.regexp
= gen_regexp ((char *) XSTR (def
, 1));
1831 VLA_PTR_ADD (decls
, decl
);
1835 /* Process a DEFINE_INSN_RESERVATION.
1837 This gives information about the reservation of cpu units by an
1838 insn. We fill a struct insn_reserv_decl with information used
1839 later by `expand_automata'. */
1841 gen_insn_reserv (def
)
1846 decl
= create_node (sizeof (struct decl
));
1847 decl
->mode
= dm_insn_reserv
;
1849 decl
->decl
.insn_reserv
.name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
1850 decl
->decl
.insn_reserv
.default_latency
= XINT (def
, 1);
1851 decl
->decl
.insn_reserv
.condexp
= XEXP (def
, 2);
1852 decl
->decl
.insn_reserv
.regexp
= gen_regexp ((char *) XSTR (def
, 3));
1853 VLA_PTR_ADD (decls
, decl
);
1859 /* The function evaluates hash value (0..UINT_MAX) of string. */
1861 string_hash (string
)
1866 for (result
= i
= 0;*string
++ != '\0'; i
++)
1867 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
1873 /* This page contains abstract data `table of automaton declarations'.
1874 Elements of the table is nodes representing automaton declarations.
1875 Key of the table elements is name of given automaton. Rememeber
1876 that automaton names have own space. */
1878 /* The function evaluates hash value of an automaton declaration. The
1879 function is used by abstract data `hashtab'. The function returns
1880 hash value (0..UINT_MAX) of given automaton declaration. */
1882 automaton_decl_hash (automaton_decl
)
1883 const void *automaton_decl
;
1885 const decl_t decl
= (decl_t
) automaton_decl
;
1887 if (decl
->mode
== dm_automaton
&& decl
->decl
.automaton
.name
== NULL
)
1889 return string_hash (decl
->decl
.automaton
.name
);
1892 /* The function tests automaton declarations on equality of their
1893 keys. The function is used by abstract data `hashtab'. The
1894 function returns 1 if the declarations have the same key, 0
1897 automaton_decl_eq_p (automaton_decl_1
, automaton_decl_2
)
1898 const void* automaton_decl_1
;
1899 const void* automaton_decl_2
;
1901 const decl_t decl1
= (decl_t
) automaton_decl_1
;
1902 const decl_t decl2
= (decl_t
) automaton_decl_2
;
1904 if (decl1
->mode
!= dm_automaton
|| decl1
->decl
.automaton
.name
== NULL
1905 || decl2
->mode
!= dm_automaton
|| decl2
->decl
.automaton
.name
== NULL
)
1907 return strcmp (decl1
->decl
.automaton
.name
, decl2
->decl
.automaton
.name
) == 0;
1910 /* The automaton declaration table itself is represented by the
1911 following variable. */
1912 static htab_t automaton_decl_table
;
1914 /* The function inserts automaton declaration into the table. The
1915 function does nothing if an automaton declaration with the same key
1916 exists already in the table. The function returns automaton
1917 declaration node in the table with the same key as given automaton
1918 declaration node. */
1920 insert_automaton_decl (automaton_decl
)
1921 decl_t automaton_decl
;
1925 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
1926 if (*entry_ptr
== NULL
)
1927 *entry_ptr
= (void *) automaton_decl
;
1928 return (decl_t
) *entry_ptr
;
1931 /* The following variable value is node representing automaton
1932 declaration. The node used for searching automaton declaration
1934 static struct decl work_automaton_decl
;
1936 /* The function searches for automaton declaration in the table with
1937 the same key as node representing name of the automaton
1938 declaration. The function returns node found in the table, NULL if
1939 such node does not exist in the table. */
1941 find_automaton_decl (name
)
1946 work_automaton_decl
.decl
.automaton
.name
= name
;
1947 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
1948 return (decl_t
) entry
;
1951 /* The function creates empty automaton declaration table and node
1952 representing automaton declaration and used for searching automaton
1953 declaration with given name. The function must be called only once
1954 before any work with the automaton declaration table. */
1956 initiate_automaton_decl_table ()
1958 work_automaton_decl
.mode
= dm_automaton
;
1959 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
1960 automaton_decl_eq_p
, (htab_del
) 0);
1963 /* The function deletes the automaton declaration table. Only call of
1964 function `initiate_automaton_decl_table' is possible immediately
1965 after this function call. */
1967 finish_automaton_decl_table ()
1969 htab_delete (automaton_decl_table
);
1974 /* This page contains abstract data `table of insn declarations'.
1975 Elements of the table is nodes representing insn declarations. Key
1976 of the table elements is name of given insn (in corresponding
1977 define_insn_reservation). Rememeber that insn names have own
1980 /* The function evaluates hash value of an insn declaration. The
1981 function is used by abstract data `hashtab'. The function returns
1982 hash value (0..UINT_MAX) of given insn declaration. */
1984 insn_decl_hash (insn_decl
)
1985 const void *insn_decl
;
1987 const decl_t decl
= (decl_t
) insn_decl
;
1989 if (decl
->mode
!= dm_insn_reserv
|| decl
->decl
.insn_reserv
.name
== NULL
)
1991 return string_hash (decl
->decl
.insn_reserv
.name
);
1994 /* The function tests insn declarations on equality of their keys.
1995 The function is used by abstract data `hashtab'. The function
1996 returns 1 if declarations have the same key, 0 otherwise. */
1998 insn_decl_eq_p (insn_decl_1
, insn_decl_2
)
1999 const void *insn_decl_1
;
2000 const void *insn_decl_2
;
2002 const decl_t decl1
= (decl_t
) insn_decl_1
;
2003 const decl_t decl2
= (decl_t
) insn_decl_2
;
2005 if (decl1
->mode
!= dm_insn_reserv
|| decl1
->decl
.insn_reserv
.name
== NULL
2006 || decl2
->mode
!= dm_insn_reserv
|| decl2
->decl
.insn_reserv
.name
== NULL
)
2008 return strcmp (decl1
->decl
.insn_reserv
.name
,
2009 decl2
->decl
.insn_reserv
.name
) == 0;
2012 /* The insn declaration table itself is represented by the following
2013 variable. The table does not contain insn reservation
2015 static htab_t insn_decl_table
;
2017 /* The function inserts insn declaration into the table. The function
2018 does nothing if an insn declaration with the same key exists
2019 already in the table. The function returns insn declaration node
2020 in the table with the same key as given insn declaration node. */
2022 insert_insn_decl (insn_decl
)
2027 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2028 if (*entry_ptr
== NULL
)
2029 *entry_ptr
= (void *) insn_decl
;
2030 return (decl_t
) *entry_ptr
;
2033 /* The following variable value is node representing insn reservation
2034 declaration. The node used for searching insn reservation
2035 declaration with given name. */
2036 static struct decl work_insn_decl
;
2038 /* The function searches for insn reservation declaration in the table
2039 with the same key as node representing name of the insn reservation
2040 declaration. The function returns node found in the table, NULL if
2041 such node does not exist in the table. */
2043 find_insn_decl (name
)
2048 work_insn_decl
.decl
.insn_reserv
.name
= name
;
2049 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2050 return (decl_t
) entry
;
2053 /* The function creates empty insn declaration table and node
2054 representing insn declaration and used for searching insn
2055 declaration with given name. The function must be called only once
2056 before any work with the insn declaration table. */
2058 initiate_insn_decl_table ()
2060 work_insn_decl
.mode
= dm_insn_reserv
;
2061 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
2065 /* The function deletes the insn declaration table. Only call of
2066 function `initiate_insn_decl_table' is possible immediately after
2067 this function call. */
2069 finish_insn_decl_table ()
2071 htab_delete (insn_decl_table
);
2076 /* This page contains abstract data `table of declarations'. Elements
2077 of the table is nodes representing declarations (of units and
2078 reservations). Key of the table elements is names of given
2081 /* The function evaluates hash value of a declaration. The function
2082 is used by abstract data `hashtab'. The function returns hash
2083 value (0..UINT_MAX) of given declaration. */
2088 const decl_t d
= (const decl_t
) decl
;
2090 if ((d
->mode
!= dm_unit
|| d
->decl
.unit
.name
== NULL
)
2091 && (d
->mode
!= dm_reserv
|| d
->decl
.reserv
.name
== NULL
))
2093 return string_hash (d
->mode
== dm_unit
2094 ? d
->decl
.unit
.name
: d
->decl
.reserv
.name
);
2097 /* The function tests declarations on equality of their keys. The
2098 function is used by abstract data `hashtab'. The function
2099 returns 1 if the declarations have the same key, 0 otherwise. */
2101 decl_eq_p (decl_1
, decl_2
)
2105 const decl_t d1
= (const decl_t
) decl_1
;
2106 const decl_t d2
= (const decl_t
) decl_2
;
2108 if (((d1
->mode
!= dm_unit
|| d1
->decl
.unit
.name
== NULL
)
2109 && (d1
->mode
!= dm_reserv
|| d1
->decl
.reserv
.name
== NULL
))
2110 || ((d2
->mode
!= dm_unit
|| d2
->decl
.unit
.name
== NULL
)
2111 && (d2
->mode
!= dm_reserv
|| d2
->decl
.reserv
.name
== NULL
)))
2113 return strcmp ((d1
->mode
== dm_unit
2114 ? d1
->decl
.unit
.name
: d1
->decl
.reserv
.name
),
2115 (d2
->mode
== dm_unit
2116 ? d2
->decl
.unit
.name
: d2
->decl
.reserv
.name
)) == 0;
2119 /* The declaration table itself is represented by the following
2121 static htab_t decl_table
;
2123 /* The function inserts declaration into the table. The function does
2124 nothing if a declaration with the same key exists already in the
2125 table. The function returns declaration node in the table with the
2126 same key as given declaration node. */
2134 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2135 if (*entry_ptr
== NULL
)
2136 *entry_ptr
= (void *) decl
;
2137 return (decl_t
) *entry_ptr
;
2140 /* The following variable value is node representing declaration. The
2141 node used for searching declaration with given name. */
2142 static struct decl work_decl
;
2144 /* The function searches for declaration in the table with the same
2145 key as node representing name of the declaration. The function
2146 returns node found in the table, NULL if such node does not exist
2154 work_decl
.decl
.unit
.name
= name
;
2155 entry
= htab_find (decl_table
, &work_decl
);
2156 return (decl_t
) entry
;
2159 /* The function creates empty declaration table and node representing
2160 declaration and used for searching declaration with given name.
2161 The function must be called only once before any work with the
2162 declaration table. */
2164 initiate_decl_table ()
2166 work_decl
.mode
= dm_unit
;
2167 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2170 /* The function deletes the declaration table. Only call of function
2171 `initiate_declaration_table' is possible immediately after this
2174 finish_decl_table ()
2176 htab_delete (decl_table
);
2181 /* This page contains checker of pipeline hazard description. */
2183 /* Checking NAMES in an exclusion clause vector and returning formed
2184 unit_set_el_list. */
2185 static unit_set_el_t
2186 process_excls (names
, num
, excl_pos
)
2189 pos_t excl_pos ATTRIBUTE_UNUSED
;
2191 unit_set_el_t el_list
;
2192 unit_set_el_t last_el
;
2193 unit_set_el_t new_el
;
2194 decl_t decl_in_table
;
2199 for (i
= 0; i
< num
; i
++)
2201 decl_in_table
= find_decl (names
[i
]);
2202 if (decl_in_table
== NULL
)
2203 error ("unit `%s' in exclusion is not declared", names
[i
]);
2204 else if (decl_in_table
->mode
!= dm_unit
)
2205 error ("`%s' in exclusion is not unit", names
[i
]);
2208 new_el
= create_node (sizeof (struct unit_set_el
));
2209 new_el
->unit_decl
= &decl_in_table
->decl
.unit
;
2210 new_el
->next_unit_set_el
= NULL
;
2211 if (last_el
== NULL
)
2212 el_list
= last_el
= new_el
;
2215 last_el
->next_unit_set_el
= new_el
;
2216 last_el
= last_el
->next_unit_set_el
;
2223 /* The function adds each element from SOURCE_LIST to the exclusion
2224 list of the each element from DEST_LIST. Checking situation "unit
2225 excludes itself". */
2227 add_excls (dest_list
, source_list
, excl_pos
)
2228 unit_set_el_t dest_list
;
2229 unit_set_el_t source_list
;
2230 pos_t excl_pos ATTRIBUTE_UNUSED
;
2234 unit_set_el_t curr_el
;
2235 unit_set_el_t prev_el
;
2238 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2239 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2241 if (dst
->unit_decl
== src
->unit_decl
)
2243 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2246 if (dst
->unit_decl
->automaton_name
!= NULL
2247 && src
->unit_decl
->automaton_name
!= NULL
2248 && strcmp (dst
->unit_decl
->automaton_name
,
2249 src
->unit_decl
->automaton_name
) != 0)
2251 error ("units `%s' and `%s' in exclusion set belong to different automata",
2252 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2255 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2257 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2258 if (curr_el
->unit_decl
== src
->unit_decl
)
2260 if (curr_el
== NULL
)
2262 /* Element not found - insert. */
2263 copy
= copy_node (src
, sizeof (*src
));
2264 copy
->next_unit_set_el
= NULL
;
2265 if (prev_el
== NULL
)
2266 dst
->unit_decl
->excl_list
= copy
;
2268 prev_el
->next_unit_set_el
= copy
;
2273 /* Checking NAMES in an presence clause vector and returning formed
2274 unit_set_el_list. The function is called only after processing all
2276 static unit_set_el_t
2277 process_presence_absence (names
, num
, req_pos
, presence_p
)
2280 pos_t req_pos ATTRIBUTE_UNUSED
;
2283 unit_set_el_t el_list
;
2284 unit_set_el_t last_el
;
2285 unit_set_el_t new_el
;
2286 decl_t decl_in_table
;
2291 for (i
= 0; i
< num
; i
++)
2293 decl_in_table
= find_decl (names
[i
]);
2294 if (decl_in_table
== NULL
)
2296 ? "unit `%s' in presence set is not declared"
2297 : "unit `%s' in absence set is not declared"), names
[i
]);
2298 else if (decl_in_table
->mode
!= dm_unit
)
2300 ? "`%s' in presence set is not unit"
2301 : "`%s' in absence set is not unit"), names
[i
]);
2304 new_el
= create_node (sizeof (struct unit_set_el
));
2305 new_el
->unit_decl
= &decl_in_table
->decl
.unit
;
2306 new_el
->next_unit_set_el
= NULL
;
2307 if (last_el
== NULL
)
2308 el_list
= last_el
= new_el
;
2311 last_el
->next_unit_set_el
= new_el
;
2312 last_el
= last_el
->next_unit_set_el
;
2319 /* The function adds each element from SOURCE_LIST to presence (if
2320 PRESENCE_P) or absence list of the each element from DEST_LIST.
2321 Checking situations "unit requires own presence", "unit requires
2322 own absence", and "unit excludes and requires presence of ...".
2323 Remember that we process absence sets only after all presence
2326 add_presence_absence (dest_list
, source_list
, req_pos
, presence_p
)
2327 unit_set_el_t dest_list
;
2328 unit_set_el_t source_list
;
2329 pos_t req_pos ATTRIBUTE_UNUSED
;
2334 unit_set_el_t curr_el
;
2335 unit_set_el_t prev_el
;
2338 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2339 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2341 if (dst
->unit_decl
== src
->unit_decl
)
2344 ? "unit `%s' requires own presence"
2345 : "unit `%s' requires own absence"), src
->unit_decl
->name
);
2348 if (dst
->unit_decl
->automaton_name
!= NULL
2349 && src
->unit_decl
->automaton_name
!= NULL
2350 && strcmp (dst
->unit_decl
->automaton_name
,
2351 src
->unit_decl
->automaton_name
) != 0)
2354 ? "units `%s' and `%s' in presence set belong to different automata"
2355 : "units `%s' and `%s' in absence set belong to different automata"),
2356 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2359 for (curr_el
= (presence_p
2360 ? dst
->unit_decl
->presence_list
2361 : dst
->unit_decl
->absence_list
), prev_el
= NULL
;
2363 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2364 if (curr_el
->unit_decl
== src
->unit_decl
)
2366 if (curr_el
== NULL
)
2368 /* Element not found - insert if there is no error. */
2369 int no_error_flag
= 1;
2372 for (curr_el
= dst
->unit_decl
->excl_list
;
2374 curr_el
= curr_el
->next_unit_set_el
)
2376 if (src
->unit_decl
== curr_el
->unit_decl
)
2381 ("unit `%s' excludes and requires presence of `%s'",
2382 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2387 ("unit `%s' excludes and requires presence of `%s'",
2388 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2392 for (curr_el
= dst
->unit_decl
->presence_list
;
2394 curr_el
= curr_el
->next_unit_set_el
)
2396 if (src
->unit_decl
== curr_el
->unit_decl
)
2401 ("unit `%s' requires absence and presence of `%s'",
2402 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2407 ("unit `%s' requires absence and presence of `%s'",
2408 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2413 copy
= copy_node (src
, sizeof (*src
));
2414 copy
->next_unit_set_el
= NULL
;
2415 if (prev_el
== NULL
)
2418 dst
->unit_decl
->presence_list
= copy
;
2420 dst
->unit_decl
->absence_list
= copy
;
2423 prev_el
->next_unit_set_el
= copy
;
2429 /* The function searches for bypass with given IN_INSN_RESERV in given
2431 static struct bypass_decl
*
2432 find_bypass (bypass_list
, in_insn_reserv
)
2433 struct bypass_decl
*bypass_list
;
2434 struct insn_reserv_decl
*in_insn_reserv
;
2436 struct bypass_decl
*bypass
;
2438 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2439 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2444 /* The function processes pipeline description declarations, checks
2445 their correctness, and forms exclusion/presence/absence sets. */
2450 decl_t automaton_decl
;
2451 decl_t decl_in_table
;
2452 decl_t out_insn_reserv
;
2453 decl_t in_insn_reserv
;
2454 struct bypass_decl
*bypass
;
2455 int automaton_presence
;
2458 /* Checking repeated automata declarations. */
2459 automaton_presence
= 0;
2460 for (i
= 0; i
< description
->decls_num
; i
++)
2462 decl
= description
->decls
[i
];
2463 if (decl
->mode
== dm_automaton
)
2465 automaton_presence
= 1;
2466 decl_in_table
= insert_automaton_decl (decl
);
2467 if (decl_in_table
!= decl
)
2470 error ("repeated declaration of automaton `%s'",
2471 decl
->decl
.automaton
.name
);
2473 warning ("repeated declaration of automaton `%s'",
2474 decl
->decl
.automaton
.name
);
2478 /* Checking undeclared automata, repeated declarations (except for
2479 automata) and correctness of their attributes (insn latency times
2481 for (i
= 0; i
< description
->decls_num
; i
++)
2483 decl
= description
->decls
[i
];
2484 if (decl
->mode
== dm_insn_reserv
)
2486 decl
->decl
.insn_reserv
.condexp
2487 = check_attr_test (decl
->decl
.insn_reserv
.condexp
, 0, 0);
2488 if (decl
->decl
.insn_reserv
.default_latency
< 0)
2489 error ("define_insn_reservation `%s' has negative latency time",
2490 decl
->decl
.insn_reserv
.name
);
2491 decl
->decl
.insn_reserv
.insn_num
= description
->insns_num
;
2492 description
->insns_num
++;
2493 decl_in_table
= insert_insn_decl (decl
);
2494 if (decl_in_table
!= decl
)
2495 error ("`%s' is already used as insn reservation name",
2496 decl
->decl
.insn_reserv
.name
);
2498 else if (decl
->mode
== dm_bypass
)
2500 if (decl
->decl
.bypass
.latency
< 0)
2501 error ("define_bypass `%s - %s' has negative latency time",
2502 decl
->decl
.bypass
.out_insn_name
,
2503 decl
->decl
.bypass
.in_insn_name
);
2505 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2507 if (decl
->mode
== dm_unit
)
2509 decl
->decl
.unit
.automaton_decl
= NULL
;
2510 if (decl
->decl
.unit
.automaton_name
!= NULL
)
2513 = find_automaton_decl (decl
->decl
.unit
.automaton_name
);
2514 if (automaton_decl
== NULL
)
2515 error ("automaton `%s' is not declared",
2516 decl
->decl
.unit
.automaton_name
);
2519 automaton_decl
->decl
.automaton
.automaton_is_used
= 1;
2520 decl
->decl
.unit
.automaton_decl
2521 = &automaton_decl
->decl
.automaton
;
2524 else if (automaton_presence
)
2525 error ("define_unit `%s' without automaton when one defined",
2526 decl
->decl
.unit
.name
);
2527 decl
->decl
.unit
.unit_num
= description
->units_num
;
2528 description
->units_num
++;
2529 if (strcmp (decl
->decl
.unit
.name
, NOTHING_NAME
) == 0)
2531 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2534 decl_in_table
= find_decl (decl
->decl
.unit
.name
);
2538 if (strcmp (decl
->decl
.reserv
.name
, NOTHING_NAME
) == 0)
2540 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2543 decl_in_table
= find_decl (decl
->decl
.reserv
.name
);
2545 if (decl_in_table
== NULL
)
2546 decl_in_table
= insert_decl (decl
);
2549 if (decl
->mode
== dm_unit
)
2550 error ("repeated declaration of unit `%s'",
2551 decl
->decl
.unit
.name
);
2553 error ("repeated declaration of reservation `%s'",
2554 decl
->decl
.reserv
.name
);
2558 /* Check bypasses and form list of bypasses for each (output)
2560 for (i
= 0; i
< description
->decls_num
; i
++)
2562 decl
= description
->decls
[i
];
2563 if (decl
->mode
== dm_bypass
)
2565 out_insn_reserv
= find_insn_decl (decl
->decl
.bypass
.out_insn_name
);
2566 in_insn_reserv
= find_insn_decl (decl
->decl
.bypass
.in_insn_name
);
2567 if (out_insn_reserv
== NULL
)
2568 error ("there is no insn reservation `%s'",
2569 decl
->decl
.bypass
.out_insn_name
);
2570 else if (in_insn_reserv
== NULL
)
2571 error ("there is no insn reservation `%s'",
2572 decl
->decl
.bypass
.in_insn_name
);
2575 decl
->decl
.bypass
.out_insn_reserv
2576 = &out_insn_reserv
->decl
.insn_reserv
;
2577 decl
->decl
.bypass
.in_insn_reserv
2578 = &in_insn_reserv
->decl
.insn_reserv
;
2580 = find_bypass (out_insn_reserv
->decl
.insn_reserv
.bypass_list
,
2581 decl
->decl
.bypass
.in_insn_reserv
);
2584 if (decl
->decl
.bypass
.latency
== bypass
->latency
)
2588 ("the same bypass `%s - %s' is already defined",
2589 decl
->decl
.bypass
.out_insn_name
,
2590 decl
->decl
.bypass
.in_insn_name
);
2593 ("the same bypass `%s - %s' is already defined",
2594 decl
->decl
.bypass
.out_insn_name
,
2595 decl
->decl
.bypass
.in_insn_name
);
2598 error ("bypass `%s - %s' is already defined",
2599 decl
->decl
.bypass
.out_insn_name
,
2600 decl
->decl
.bypass
.in_insn_name
);
2604 decl
->decl
.bypass
.next
2605 = out_insn_reserv
->decl
.insn_reserv
.bypass_list
;
2606 out_insn_reserv
->decl
.insn_reserv
.bypass_list
2607 = &decl
->decl
.bypass
;
2613 /* Check exclusion set declarations and form exclussion sets. */
2614 for (i
= 0; i
< description
->decls_num
; i
++)
2616 decl
= description
->decls
[i
];
2617 if (decl
->mode
== dm_excl
)
2619 unit_set_el_t unit_set_el_list
;
2620 unit_set_el_t unit_set_el_list_2
;
2623 = process_excls (decl
->decl
.excl
.names
,
2624 decl
->decl
.excl
.first_list_length
, decl
->pos
);
2626 = process_excls (&decl
->decl
.excl
.names
2627 [decl
->decl
.excl
.first_list_length
],
2628 decl
->decl
.excl
.names_num
2629 - decl
->decl
.excl
.first_list_length
,
2631 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2632 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2636 /* Check presence set declarations and form presence sets. */
2637 for (i
= 0; i
< description
->decls_num
; i
++)
2639 decl
= description
->decls
[i
];
2640 if (decl
->mode
== dm_presence
)
2642 unit_set_el_t unit_set_el_list
;
2643 unit_set_el_t unit_set_el_list_2
;
2646 = process_presence_absence
2647 (decl
->decl
.presence
.names
,
2648 decl
->decl
.presence
.first_list_length
, decl
->pos
, 1);
2650 = process_presence_absence
2651 (&decl
->decl
.presence
.names
2652 [decl
->decl
.presence
.first_list_length
],
2653 decl
->decl
.presence
.names_num
2654 - decl
->decl
.presence
.first_list_length
,
2656 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2661 /* Check absence set declarations and form absence sets. */
2662 for (i
= 0; i
< description
->decls_num
; i
++)
2664 decl
= description
->decls
[i
];
2665 if (decl
->mode
== dm_absence
)
2667 unit_set_el_t unit_set_el_list
;
2668 unit_set_el_t unit_set_el_list_2
;
2671 = process_presence_absence
2672 (decl
->decl
.presence
.names
,
2673 decl
->decl
.presence
.first_list_length
, decl
->pos
, 0);
2675 = process_presence_absence
2676 (&decl
->decl
.presence
.names
2677 [decl
->decl
.presence
.first_list_length
],
2678 decl
->decl
.presence
.names_num
2679 - decl
->decl
.presence
.first_list_length
,
2681 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2687 /* The following function checks that declared automaton is used. If
2688 the automaton is not used, the function fixes error/warning. The
2689 following function must be called only after `process_decls'. */
2691 check_automaton_usage ()
2696 for (i
= 0; i
< description
->decls_num
; i
++)
2698 decl
= description
->decls
[i
];
2699 if (decl
->mode
== dm_automaton
2700 && !decl
->decl
.automaton
.automaton_is_used
)
2703 error ("automaton `%s' is not used", decl
->decl
.automaton
.name
);
2705 warning ("automaton `%s' is not used", decl
->decl
.automaton
.name
);
2710 /* The following recursive function processes all regexp in order to
2711 fix usage of units or reservations and to fix errors of undeclared
2712 name. The function may change unit_regexp onto reserv_regexp.
2713 Remember that reserv_regexp does not exist before the function
2716 process_regexp (regexp
)
2719 decl_t decl_in_table
;
2720 regexp_t new_regexp
;
2723 if (regexp
->mode
== rm_unit
)
2725 decl_in_table
= find_decl (regexp
->regexp
.unit
.name
);
2726 if (decl_in_table
== NULL
)
2727 error ("undeclared unit or reservation `%s'",
2728 regexp
->regexp
.unit
.name
);
2729 else if (decl_in_table
->mode
== dm_unit
)
2731 decl_in_table
->decl
.unit
.unit_is_used
= 1;
2732 regexp
->regexp
.unit
.unit_decl
= &decl_in_table
->decl
.unit
;
2734 else if (decl_in_table
->mode
== dm_reserv
)
2736 decl_in_table
->decl
.reserv
.reserv_is_used
= 1;
2737 new_regexp
= create_node (sizeof (struct regexp
));
2738 new_regexp
->mode
= rm_reserv
;
2739 new_regexp
->pos
= regexp
->pos
;
2740 new_regexp
->regexp
.reserv
.name
= regexp
->regexp
.unit
.name
;
2741 new_regexp
->regexp
.reserv
.reserv_decl
= &decl_in_table
->decl
.reserv
;
2742 regexp
= new_regexp
;
2747 else if (regexp
->mode
== rm_sequence
)
2748 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2749 regexp
->regexp
.sequence
.regexps
[i
]
2750 = process_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
2751 else if (regexp
->mode
== rm_allof
)
2752 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2753 regexp
->regexp
.allof
.regexps
[i
]
2754 = process_regexp (regexp
->regexp
.allof
.regexps
[i
]);
2755 else if (regexp
->mode
== rm_oneof
)
2756 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2757 regexp
->regexp
.oneof
.regexps
[i
]
2758 = process_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
2759 else if (regexp
->mode
== rm_repeat
)
2760 regexp
->regexp
.repeat
.regexp
2761 = process_regexp (regexp
->regexp
.repeat
.regexp
);
2762 else if (regexp
->mode
!= rm_nothing
)
2767 /* The following function processes regexp of define_reservation and
2768 define_insn_reservation with the aid of function
2769 `process_regexp'. */
2771 process_regexp_decls ()
2776 for (i
= 0; i
< description
->decls_num
; i
++)
2778 decl
= description
->decls
[i
];
2779 if (decl
->mode
== dm_reserv
)
2780 decl
->decl
.reserv
.regexp
= process_regexp (decl
->decl
.reserv
.regexp
);
2781 else if (decl
->mode
== dm_insn_reserv
)
2782 decl
->decl
.insn_reserv
.regexp
2783 = process_regexp (decl
->decl
.insn_reserv
.regexp
);
2787 /* The following function checks that declared unit is used. If the
2788 unit is not used, the function fixes errors/warnings. The
2789 following function must be called only after `process_decls',
2790 `process_regexp_decls'. */
2797 for (i
= 0; i
< description
->decls_num
; i
++)
2799 decl
= description
->decls
[i
];
2800 if (decl
->mode
== dm_unit
&& !decl
->decl
.unit
.unit_is_used
)
2803 error ("unit `%s' is not used", decl
->decl
.unit
.name
);
2805 warning ("unit `%s' is not used", decl
->decl
.unit
.name
);
2807 else if (decl
->mode
== dm_reserv
&& !decl
->decl
.reserv
.reserv_is_used
)
2810 error ("reservation `%s' is not used", decl
->decl
.reserv
.name
);
2812 warning ("reservation `%s' is not used", decl
->decl
.reserv
.name
);
2817 /* The following variable value is number of reservation being
2818 processed on loop recognition. */
2819 static int curr_loop_pass_num
;
2821 /* The following recursive function returns nonzero value if REGEXP
2822 contains given decl or reservations in given regexp refers for
2825 loop_in_regexp (regexp
, start_decl
)
2833 if (regexp
->mode
== rm_unit
)
2835 else if (regexp
->mode
== rm_reserv
)
2837 if (start_decl
->mode
== dm_reserv
2838 && regexp
->regexp
.reserv
.reserv_decl
== &start_decl
->decl
.reserv
)
2840 else if (regexp
->regexp
.reserv
.reserv_decl
->loop_pass_num
2841 == curr_loop_pass_num
)
2842 /* declaration has been processed. */
2846 regexp
->regexp
.reserv
.reserv_decl
->loop_pass_num
2847 = curr_loop_pass_num
;
2848 return loop_in_regexp (regexp
->regexp
.reserv
.reserv_decl
->regexp
,
2852 else if (regexp
->mode
== rm_sequence
)
2854 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2855 if (loop_in_regexp (regexp
->regexp
.sequence
.regexps
[i
], start_decl
))
2859 else if (regexp
->mode
== rm_allof
)
2861 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2862 if (loop_in_regexp (regexp
->regexp
.allof
.regexps
[i
], start_decl
))
2866 else if (regexp
->mode
== rm_oneof
)
2868 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2869 if (loop_in_regexp (regexp
->regexp
.oneof
.regexps
[i
], start_decl
))
2873 else if (regexp
->mode
== rm_repeat
)
2874 return loop_in_regexp (regexp
->regexp
.repeat
.regexp
, start_decl
);
2877 if (regexp
->mode
!= rm_nothing
)
2883 /* The following function fixes errors "cycle in definition ...". The
2884 function uses function `loop_in_regexp' for that. */
2886 check_loops_in_regexps ()
2891 for (i
= 0; i
< description
->decls_num
; i
++)
2893 decl
= description
->decls
[i
];
2894 if (decl
->mode
== dm_reserv
)
2895 decl
->decl
.reserv
.loop_pass_num
= 0;
2897 for (i
= 0; i
< description
->decls_num
; i
++)
2899 decl
= description
->decls
[i
];
2900 curr_loop_pass_num
= i
;
2902 if (decl
->mode
== dm_reserv
)
2904 decl
->decl
.reserv
.loop_pass_num
= curr_loop_pass_num
;
2905 if (loop_in_regexp (decl
->decl
.reserv
.regexp
, decl
))
2907 if (decl
->decl
.reserv
.regexp
== NULL
)
2909 error ("cycle in definition of reservation `%s'",
2910 decl
->decl
.reserv
.name
);
2916 /* The function recursively processes IR of reservation and defines
2917 max and min cycle for reservation of unit and for result in the
2920 process_regexp_cycles (regexp
, start_cycle
)
2926 if (regexp
->mode
== rm_unit
)
2928 if (regexp
->regexp
.unit
.unit_decl
->max_occ_cycle_num
< start_cycle
)
2929 regexp
->regexp
.unit
.unit_decl
->max_occ_cycle_num
= start_cycle
;
2932 else if (regexp
->mode
== rm_reserv
)
2933 return process_regexp_cycles (regexp
->regexp
.reserv
.reserv_decl
->regexp
,
2935 else if (regexp
->mode
== rm_repeat
)
2937 for (i
= 0; i
< regexp
->regexp
.repeat
.repeat_num
; i
++)
2938 start_cycle
= process_regexp_cycles (regexp
->regexp
.repeat
.regexp
,
2942 else if (regexp
->mode
== rm_sequence
)
2944 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2946 = process_regexp_cycles (regexp
->regexp
.sequence
.regexps
[i
],
2950 else if (regexp
->mode
== rm_allof
)
2952 int finish_cycle
= 0;
2955 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2957 cycle
= process_regexp_cycles (regexp
->regexp
.allof
.regexps
[i
],
2959 if (finish_cycle
< cycle
)
2960 finish_cycle
= cycle
;
2962 return finish_cycle
;
2964 else if (regexp
->mode
== rm_oneof
)
2966 int finish_cycle
= 0;
2969 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2971 cycle
= process_regexp_cycles (regexp
->regexp
.oneof
.regexps
[i
],
2973 if (finish_cycle
< cycle
)
2974 finish_cycle
= cycle
;
2976 return finish_cycle
;
2980 if (regexp
->mode
!= rm_nothing
)
2986 /* The following function is called only for correct program. The
2987 function defines max reservation of insns in cycles. */
2989 evaluate_max_reserv_cycles ()
2991 int max_insn_cycles_num
;
2995 description
->max_insn_reserv_cycles
= 0;
2996 for (i
= 0; i
< description
->decls_num
; i
++)
2998 decl
= description
->decls
[i
];
2999 if (decl
->mode
== dm_insn_reserv
)
3002 = process_regexp_cycles (decl
->decl
.insn_reserv
.regexp
, 0);
3003 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3004 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3007 description
->max_insn_reserv_cycles
++;
3010 /* The following function calls functions for checking all
3013 check_all_description ()
3016 check_automaton_usage ();
3017 process_regexp_decls ();
3019 check_loops_in_regexps ();
3021 evaluate_max_reserv_cycles ();
3026 /* The page contains abstract data `ticker'. This data is used to
3027 report time of different phases of building automata. It is
3028 possibly to write a description for which automata will be built
3029 during several minutes even on fast machine. */
3031 /* The following function creates ticker and makes it active. */
3037 ticker
.modified_creation_time
= get_run_time ();
3038 ticker
.incremented_off_time
= 0;
3042 /* The following function switches off given ticker. */
3047 if (ticker
->incremented_off_time
== 0)
3048 ticker
->incremented_off_time
= get_run_time () + 1;
3051 /* The following function switches on given ticker. */
3056 if (ticker
->incremented_off_time
!= 0)
3058 ticker
->modified_creation_time
3059 += get_run_time () - ticker
->incremented_off_time
+ 1;
3060 ticker
->incremented_off_time
= 0;
3064 /* The following function returns current time in milliseconds since
3065 the moment when given ticker was created. */
3067 active_time (ticker
)
3070 if (ticker
.incremented_off_time
!= 0)
3071 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3073 return get_run_time () - ticker
.modified_creation_time
;
3076 /* The following function returns string representation of active time
3077 of given ticker. The result is string representation of seconds
3078 with accuracy of 1/100 second. Only result of the last call of the
3079 function exists. Therefore the following code is not correct
3081 printf ("parser time: %s\ngeneration time: %s\n",
3082 active_time_string (parser_ticker),
3083 active_time_string (generation_ticker));
3085 Correct code has to be the following
3087 printf ("parser time: %s\n", active_time_string (parser_ticker));
3088 printf ("generation time: %s\n",
3089 active_time_string (generation_ticker));
3093 print_active_time (f
, ticker
)
3099 msecs
= active_time (ticker
);
3100 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3105 /* The following variable value is number of automaton which are
3106 really being created. This value is defined on the base of
3107 argument of option `-split'. If the variable has zero value the
3108 number of automata is defined by the constructions `%automaton'.
3109 This case occures when option `-split' is absent or has zero
3110 argument. If constructions `define_automaton' is absent only one
3111 automaton is created. */
3112 static int automata_num
;
3114 /* The following variable values are times of
3115 o transformation of regular expressions
3116 o building NDFA (DFA if !ndfa_flag)
3117 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3119 o building insn equivalence classes
3122 static ticker_t transform_time
;
3123 static ticker_t NDFA_time
;
3124 static ticker_t NDFA_to_DFA_time
;
3125 static ticker_t minimize_time
;
3126 static ticker_t equiv_time
;
3127 static ticker_t automaton_generation_time
;
3128 static ticker_t output_time
;
3130 /* The following variable values are times of
3133 all pipeline hazard translator work */
3134 static ticker_t check_time
;
3135 static ticker_t generation_time
;
3136 static ticker_t all_time
;
3140 /* Pseudo insn decl which denotes advancing cycle. */
3141 static decl_t advance_cycle_insn_decl
;
3143 add_advance_cycle_insn_decl ()
3145 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3146 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3147 advance_cycle_insn_decl
->pos
= no_pos
;
3148 advance_cycle_insn_decl
->decl
.insn_reserv
.regexp
= NULL
;
3149 advance_cycle_insn_decl
->decl
.insn_reserv
.name
= (char *) "$advance_cycle";
3150 advance_cycle_insn_decl
->decl
.insn_reserv
.insn_num
= description
->insns_num
;
3151 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3152 description
->decls_num
++;
3153 description
->insns_num
++;
3158 /* Abstract data `alternative states' which reperesents
3159 nondeterministic nature of the description (see comments for
3160 structures alt_state and state). */
3162 /* List of free states. */
3163 static alt_state_t first_free_alt_state
;
3166 /* The following variables is maximal number of allocated nodes
3168 static int allocated_alt_states_num
= 0;
3171 /* The following function returns free node alt_state. It may be new
3172 allocated node or node freed eralier. */
3174 get_free_alt_state ()
3178 if (first_free_alt_state
!= NULL
)
3180 result
= first_free_alt_state
;
3181 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3186 allocated_alt_states_num
++;
3188 result
= create_node (sizeof (struct alt_state
));
3190 result
->state
= NULL
;
3191 result
->next_alt_state
= NULL
;
3192 result
->next_sorted_alt_state
= NULL
;
3196 /* The function frees node ALT_STATE. */
3198 free_alt_state (alt_state
)
3199 alt_state_t alt_state
;
3201 if (alt_state
== NULL
)
3203 alt_state
->next_alt_state
= first_free_alt_state
;
3204 first_free_alt_state
= alt_state
;
3207 /* The function frees list started with node ALT_STATE_LIST. */
3209 free_alt_states (alt_states_list
)
3210 alt_state_t alt_states_list
;
3212 alt_state_t curr_alt_state
;
3213 alt_state_t next_alt_state
;
3215 for (curr_alt_state
= alt_states_list
;
3216 curr_alt_state
!= NULL
;
3217 curr_alt_state
= next_alt_state
)
3219 next_alt_state
= curr_alt_state
->next_alt_state
;
3220 free_alt_state (curr_alt_state
);
3224 /* The function compares unique numbers of alt states. */
3226 alt_state_cmp (alt_state_ptr_1
, alt_state_ptr_2
)
3227 const void *alt_state_ptr_1
;
3228 const void *alt_state_ptr_2
;
3230 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3231 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3233 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3234 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3240 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3241 states from the list. The comparison key is alt state unique
3244 uniq_sort_alt_states (alt_states_list
)
3245 alt_state_t alt_states_list
;
3247 alt_state_t curr_alt_state
;
3248 vla_ptr_t alt_states
;
3250 size_t prev_unique_state_ind
;
3252 alt_state_t
*result_ptr
;
3254 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3255 for (curr_alt_state
= alt_states_list
;
3256 curr_alt_state
!= NULL
;
3257 curr_alt_state
= curr_alt_state
->next_alt_state
)
3258 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3259 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3260 sizeof (alt_state_t
), alt_state_cmp
);
3261 if (VLA_PTR_LENGTH (alt_states
) == 0)
3265 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3266 prev_unique_state_ind
= 0;
3267 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3268 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3270 prev_unique_state_ind
++;
3271 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3274 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3275 free_alt_state (result_ptr
[i
]);
3277 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3278 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3279 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3280 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3281 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3282 result
= *result_ptr
;
3284 VLA_PTR_DELETE (alt_states
);
3288 /* The function checks equality of alt state lists. Remember that the
3289 lists must be already sorted by the previous function. */
3291 alt_states_eq (alt_states_1
, alt_states_2
)
3292 alt_state_t alt_states_1
;
3293 alt_state_t alt_states_2
;
3295 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3296 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3298 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3299 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3301 return alt_states_1
== alt_states_2
;
3304 /* Initialization of the abstract data. */
3306 initiate_alt_states ()
3308 first_free_alt_state
= NULL
;
3311 /* Finishing work with the abstract data. */
3313 finish_alt_states ()
3319 /* The page contains macros for work with bits strings. We could use
3320 standard gcc bitmap or sbitmap but it would result in difficulties
3321 of building canadian cross. */
3323 /* Set bit number bitno in the bit string. The macro is not side
3325 #define SET_BIT(bitstring, bitno) \
3326 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3328 /* Test if bit number bitno in the bitstring is set. The macro is not
3329 side effect proof. */
3330 #define TEST_BIT(bitstring, bitno) \
3331 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3335 /* This page contains abstract data `state'. */
3337 /* Maximal length of reservations in cycles (>= 1). */
3338 static int max_cycles_num
;
3340 /* Number of set elements (see type set_el_t) needed for
3341 representation of one cycle reservation. It is depended on units
3343 static int els_in_cycle_reserv
;
3345 /* Number of set elements (see type set_el_t) needed for
3346 representation of maximal length reservation. Deterministic
3347 reservation is stored as set (bit string) of length equal to the
3348 variable value * number of bits in set_el_t. */
3349 static int els_in_reservs
;
3351 /* VLA for representation of array of pointers to unit
3353 static vla_ptr_t units_container
;
3355 /* The start address of the array. */
3356 static unit_decl_t
*units_array
;
3358 /* Empty reservation of maximal length. */
3359 static reserv_sets_t empty_reserv
;
3361 /* The state table itself is represented by the following variable. */
3362 static htab_t state_table
;
3364 /* VLA for representation of array of pointers to free nodes
3366 static vla_ptr_t free_states
;
3368 static int curr_unique_state_num
;
3371 /* The following variables is maximal number of allocated nodes
3373 static int allocated_states_num
= 0;
3376 /* Allocate new reservation set. */
3377 static reserv_sets_t
3378 alloc_empty_reserv_sets ()
3380 reserv_sets_t result
;
3382 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3383 result
= (reserv_sets_t
) obstack_base (&irp
);
3384 obstack_finish (&irp
);
3385 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3389 /* Hash value of reservation set. */
3391 reserv_sets_hash_value (reservs
)
3392 reserv_sets_t reservs
;
3394 set_el_t hash_value
;
3397 set_el_t
*reserv_ptr
;
3400 reservs_num
= els_in_reservs
;
3401 reserv_ptr
= reservs
;
3403 while (reservs_num
!= 0)
3406 hash_value
+= ((*reserv_ptr
>> i
)
3407 | (*reserv_ptr
<< (sizeof (set_el_t
) * CHAR_BIT
- i
)));
3409 if (i
== sizeof (set_el_t
) * CHAR_BIT
)
3413 if (sizeof (set_el_t
) <= sizeof (unsigned))
3416 for (i
= sizeof (set_el_t
); i
> 0; i
-= sizeof (unsigned) - 1)
3418 result
+= (unsigned) hash_value
;
3419 hash_value
>>= (sizeof (unsigned) - 1) * CHAR_BIT
;
3424 /* Comparison of given reservation sets. */
3426 reserv_sets_cmp (reservs_1
, reservs_2
)
3427 reserv_sets_t reservs_1
;
3428 reserv_sets_t reservs_2
;
3431 set_el_t
*reserv_ptr_1
;
3432 set_el_t
*reserv_ptr_2
;
3434 if (reservs_1
== NULL
|| reservs_2
== NULL
)
3436 reservs_num
= els_in_reservs
;
3437 reserv_ptr_1
= reservs_1
;
3438 reserv_ptr_2
= reservs_2
;
3439 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3445 if (reservs_num
== 0)
3447 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3453 /* The function checks equality of the reservation sets. */
3455 reserv_sets_eq (reservs_1
, reservs_2
)
3456 reserv_sets_t reservs_1
;
3457 reserv_sets_t reservs_2
;
3459 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3462 /* Set up in the reservation set that unit with UNIT_NUM is used on
3465 set_unit_reserv (reservs
, cycle_num
, unit_num
)
3466 reserv_sets_t reservs
;
3470 if (cycle_num
>= max_cycles_num
)
3472 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3473 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3476 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3477 used on CYCLE_NUM. */
3479 test_unit_reserv (reservs
, cycle_num
, unit_num
)
3480 reserv_sets_t reservs
;
3484 if (cycle_num
>= max_cycles_num
)
3486 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3487 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3490 /* The function checks that the reservation set represents no one unit
3493 it_is_empty_reserv_sets (operand
)
3494 reserv_sets_t operand
;
3496 set_el_t
*reserv_ptr
;
3499 if (operand
== NULL
)
3501 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3503 reserv_ptr
++, reservs_num
--)
3504 if (*reserv_ptr
!= 0)
3509 /* The function checks that the reservation sets are intersected,
3510 i.e. there is a unit reservation on a cycle in both reservation
3513 reserv_sets_are_intersected (operand_1
, operand_2
)
3514 reserv_sets_t operand_1
;
3515 reserv_sets_t operand_2
;
3519 set_el_t
*cycle_ptr_1
;
3520 set_el_t
*cycle_ptr_2
;
3523 if (operand_1
== NULL
|| operand_2
== NULL
)
3525 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3526 el_ptr_1
< operand_1
+ els_in_reservs
;
3527 el_ptr_1
++, el_ptr_2
++)
3528 if (*el_ptr_1
& *el_ptr_2
)
3530 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3531 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3532 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3534 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3535 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3536 el_ptr_1
++, el_ptr_2
++)
3537 if (*el_ptr_1
& *el_ptr_2
)
3540 for (el_ptr_1
= cycle_ptr_1
,
3541 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 1);
3542 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3543 el_ptr_1
++, el_ptr_2
++)
3544 if (*el_ptr_1
& *el_ptr_2
)
3546 else if (*el_ptr_2
!= 0)
3548 if (nonzero_p
&& el_ptr_1
>= cycle_ptr_1
+ els_in_cycle_reserv
)
3550 for (el_ptr_1
= cycle_ptr_1
,
3551 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 0);
3552 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3553 el_ptr_1
++, el_ptr_2
++)
3554 /* It looks like code for exclusion but exclusion set is
3555 made as symmetric relation preliminary. */
3556 if (*el_ptr_1
& *el_ptr_2
)
3562 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3563 cpu cycle. The remaining bits of OPERAND (representing the last
3564 cycle unit reservations) are not chenged. */
3566 reserv_sets_shift (result
, operand
)
3567 reserv_sets_t result
;
3568 reserv_sets_t operand
;
3572 if (result
== NULL
|| operand
== NULL
|| result
== operand
)
3574 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3575 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3578 /* OR of the reservation sets. */
3580 reserv_sets_or (result
, operand_1
, operand_2
)
3581 reserv_sets_t result
;
3582 reserv_sets_t operand_1
;
3583 reserv_sets_t operand_2
;
3587 set_el_t
*result_set_el_ptr
;
3589 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3591 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3592 el_ptr_1
< operand_1
+ els_in_reservs
;
3593 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3594 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3597 /* AND of the reservation sets. */
3599 reserv_sets_and (result
, operand_1
, operand_2
)
3600 reserv_sets_t result
;
3601 reserv_sets_t operand_1
;
3602 reserv_sets_t operand_2
;
3606 set_el_t
*result_set_el_ptr
;
3608 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3610 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3611 el_ptr_1
< operand_1
+ els_in_reservs
;
3612 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3613 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3616 /* The function outputs string representation of units reservation on
3617 cycle START_CYCLE in the reservation set. The function uses repeat
3618 construction if REPETITION_NUM > 1. */
3620 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
)
3622 reserv_sets_t reservs
;
3627 int reserved_units_num
;
3629 reserved_units_num
= 0;
3630 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3631 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3632 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3633 reserved_units_num
++;
3634 if (repetition_num
<= 0)
3636 if (repetition_num
!= 1 && reserved_units_num
> 1)
3638 reserved_units_num
= 0;
3640 unit_num
< description
->units_num
;
3642 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3643 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3645 if (reserved_units_num
!= 0)
3647 reserved_units_num
++;
3648 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3650 if (reserved_units_num
== 0)
3651 fprintf (f
, NOTHING_NAME
);
3652 if (repetition_num
<= 0)
3654 if (reserved_units_num
> 1)
3656 if (repetition_num
!= 1)
3657 fprintf (f
, "*%d", repetition_num
);
3660 /* The function outputs string representation of units reservation in
3661 the reservation set. */
3663 output_reserv_sets (f
, reservs
)
3665 reserv_sets_t reservs
;
3667 int start_cycle
= 0;
3672 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
3673 if (repetition_num
== 0)
3676 start_cycle
= cycle
;
3679 ((char *) reservs
+ start_cycle
* els_in_cycle_reserv
3680 * sizeof (set_el_t
),
3681 (char *) reservs
+ cycle
* els_in_cycle_reserv
3682 * sizeof (set_el_t
),
3683 els_in_cycle_reserv
* sizeof (set_el_t
)) == 0)
3687 if (start_cycle
!= 0)
3689 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3691 start_cycle
= cycle
;
3693 if (start_cycle
< max_cycles_num
)
3695 if (start_cycle
!= 0)
3697 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3701 /* The following function returns free node state for AUTOMATON. It
3702 may be new allocated node or node freed eralier. The function also
3703 allocates reservation set if WITH_RESERVS has nonzero value. */
3705 get_free_state (with_reservs
, automaton
)
3707 automaton_t automaton
;
3711 if (max_cycles_num
<= 0 || automaton
== NULL
)
3713 if (VLA_PTR_LENGTH (free_states
) != 0)
3715 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
3716 VLA_PTR_SHORTEN (free_states
, 1);
3717 result
->automaton
= automaton
;
3718 result
->first_out_arc
= NULL
;
3719 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
3720 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
3721 result
->component_states
= NULL
;
3722 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3727 allocated_states_num
++;
3729 result
= create_node (sizeof (struct state
));
3730 result
->automaton
= automaton
;
3731 result
->first_out_arc
= NULL
;
3732 result
->unique_num
= curr_unique_state_num
;
3733 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3734 curr_unique_state_num
++;
3738 if (result
->reservs
== NULL
)
3739 result
->reservs
= alloc_empty_reserv_sets ();
3741 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
3746 /* The function frees node STATE. */
3751 free_alt_states (state
->component_states
);
3752 VLA_PTR_ADD (free_states
, state
);
3755 /* Hash value of STATE. If STATE represents deterministic state it is
3756 simply hash value of the corresponding reservation set. Otherwise
3757 it is formed from hash values of the component deterministic
3758 states. One more key is order number of state automaton. */
3763 unsigned int hash_value
;
3764 alt_state_t alt_state
;
3766 if (((state_t
) state
)->component_states
== NULL
)
3767 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
3771 for (alt_state
= ((state_t
) state
)->component_states
;
3773 alt_state
= alt_state
->next_sorted_alt_state
)
3774 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
3775 | (hash_value
<< CHAR_BIT
))
3776 + alt_state
->state
->unique_num
);
3778 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
3779 | (hash_value
<< CHAR_BIT
))
3780 + ((state_t
) state
)->automaton
->automaton_order_num
);
3784 /* Return nonzero value if the states are the same. */
3786 state_eq_p (state_1
, state_2
)
3787 const void *state_1
;
3788 const void *state_2
;
3790 alt_state_t alt_state_1
;
3791 alt_state_t alt_state_2
;
3793 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
3795 else if (((state_t
) state_1
)->component_states
== NULL
3796 && ((state_t
) state_2
)->component_states
== NULL
)
3797 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
3798 ((state_t
) state_2
)->reservs
);
3799 else if (((state_t
) state_1
)->component_states
!= NULL
3800 && ((state_t
) state_2
)->component_states
!= NULL
)
3802 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
3803 alt_state_2
= ((state_t
) state_2
)->component_states
;
3804 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
3805 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
3806 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
3807 /* All state in the list must be already in the hash table.
3808 Also the lists must be sorted. */
3809 if (alt_state_1
->state
!= alt_state_2
->state
)
3811 return alt_state_1
== alt_state_2
;
3817 /* Insert STATE into the state table. */
3819 insert_state (state
)
3824 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
3825 if (*entry_ptr
== NULL
)
3826 *entry_ptr
= (void *) state
;
3827 return (state_t
) *entry_ptr
;
3830 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3831 deterministic STATE. */
3833 set_state_reserv (state
, cycle_num
, unit_num
)
3838 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
3841 /* Return nonzero value if the deterministic states contains a
3842 reservation of the same cpu unit on the same cpu cycle. */
3844 intersected_state_reservs_p (state1
, state2
)
3848 if (state1
->automaton
!= state2
->automaton
)
3850 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
3853 /* Return deterministic state (inserted into the table) which
3854 representing the automaton state whic is union of reservations of
3855 deterministic states. */
3857 states_union (state1
, state2
)
3862 state_t state_in_table
;
3864 if (state1
->automaton
!= state2
->automaton
)
3866 result
= get_free_state (1, state1
->automaton
);
3867 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
3868 state_in_table
= insert_state (result
);
3869 if (result
!= state_in_table
)
3871 free_state (result
);
3872 result
= state_in_table
;
3877 /* Return deterministic state (inserted into the table) which
3878 represent the automaton state is obtained from deterministic STATE
3879 by advancing cpu cycle. */
3885 state_t state_in_table
;
3887 result
= get_free_state (1, state
->automaton
);
3888 reserv_sets_shift (result
->reservs
, state
->reservs
);
3889 state_in_table
= insert_state (result
);
3890 if (result
!= state_in_table
)
3892 free_state (result
);
3893 result
= state_in_table
;
3898 /* Initialization of the abstract data. */
3905 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
3907 = (description
->decls_num
&& description
->units_num
3908 ? VLA_PTR_BEGIN (units_container
) : NULL
);
3909 for (i
= 0; i
< description
->decls_num
; i
++)
3911 decl
= description
->decls
[i
];
3912 if (decl
->mode
== dm_unit
)
3913 units_array
[decl
->decl
.unit
.unit_num
] = &decl
->decl
.unit
;
3915 max_cycles_num
= description
->max_insn_reserv_cycles
;
3917 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
3918 / (sizeof (set_el_t
) * CHAR_BIT
));
3919 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
3920 curr_unique_state_num
= 0;
3921 initiate_alt_states ();
3922 VLA_PTR_CREATE (free_states
, 1500, "free states");
3923 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
3924 empty_reserv
= alloc_empty_reserv_sets ();
3927 /* Finisging work with the abstract data. */
3931 VLA_PTR_DELETE (units_container
);
3932 htab_delete (state_table
);
3933 VLA_PTR_DELETE (free_states
);
3934 finish_alt_states ();
3939 /* Abstract data `arcs'. */
3941 /* List of free arcs. */
3942 static arc_t first_free_arc
;
3945 /* The following variables is maximal number of allocated nodes
3947 static int allocated_arcs_num
= 0;
3950 /* The function frees node ARC. */
3955 arc
->next_out_arc
= first_free_arc
;
3956 first_free_arc
= arc
;
3959 /* The function removes and frees ARC staring from FROM_STATE. */
3961 remove_arc (from_state
, arc
)
3970 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
3972 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
3973 if (curr_arc
== arc
)
3975 if (curr_arc
== NULL
)
3977 if (prev_arc
== NULL
)
3978 from_state
->first_out_arc
= arc
->next_out_arc
;
3980 prev_arc
->next_out_arc
= arc
->next_out_arc
;
3984 /* The functions returns arc with given characteristics (or NULL if
3985 the arc does not exist). */
3987 find_arc (from_state
, to_state
, insn
)
3994 for (arc
= first_out_arc (from_state
); arc
!= NULL
; arc
= next_out_arc (arc
))
3995 if (arc
->to_state
== to_state
&& arc
->insn
== insn
)
4000 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4001 and with given STATE_ALTS. The function returns added arc (or
4002 already existing arc). */
4004 add_arc (from_state
, to_state
, ainsn
, state_alts
)
4012 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4013 if (new_arc
!= NULL
)
4015 if (first_free_arc
== NULL
)
4018 allocated_arcs_num
++;
4020 new_arc
= create_node (sizeof (struct arc
));
4021 new_arc
->to_state
= NULL
;
4022 new_arc
->insn
= NULL
;
4023 new_arc
->next_out_arc
= NULL
;
4027 new_arc
= first_free_arc
;
4028 first_free_arc
= first_free_arc
->next_out_arc
;
4030 new_arc
->to_state
= to_state
;
4031 new_arc
->insn
= ainsn
;
4032 ainsn
->arc_exists_p
= 1;
4033 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4034 from_state
->first_out_arc
= new_arc
;
4035 new_arc
->next_arc_marked_by_insn
= NULL
;
4036 new_arc
->state_alts
= state_alts
;
4040 /* The function returns the first arc starting from STATE. */
4042 first_out_arc (state
)
4045 return state
->first_out_arc
;
4048 /* The function returns next out arc after ARC. */
4053 return arc
->next_out_arc
;
4056 /* Initialization of the abstract data. */
4060 first_free_arc
= NULL
;
4063 /* Finishing work with the abstract data. */
4071 /* Abstract data `automata lists'. */
4073 /* List of free states. */
4074 static automata_list_el_t first_free_automata_list_el
;
4076 /* The list being formed. */
4077 static automata_list_el_t current_automata_list
;
4079 /* Hash table of automata lists. */
4080 static htab_t automata_list_table
;
4082 /* The following function returns free automata list el. It may be
4083 new allocated node or node freed earlier. */
4084 static automata_list_el_t
4085 get_free_automata_list_el ()
4087 automata_list_el_t result
;
4089 if (first_free_automata_list_el
!= NULL
)
4091 result
= first_free_automata_list_el
;
4092 first_free_automata_list_el
4093 = first_free_automata_list_el
->next_automata_list_el
;
4096 result
= create_node (sizeof (struct automata_list_el
));
4097 result
->automaton
= NULL
;
4098 result
->next_automata_list_el
= NULL
;
4102 /* The function frees node AUTOMATA_LIST_EL. */
4104 free_automata_list_el (automata_list_el
)
4105 automata_list_el_t automata_list_el
;
4107 if (automata_list_el
== NULL
)
4109 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4110 first_free_automata_list_el
= automata_list_el
;
4113 /* The function frees list AUTOMATA_LIST. */
4115 free_automata_list (automata_list
)
4116 automata_list_el_t automata_list
;
4118 automata_list_el_t curr_automata_list_el
;
4119 automata_list_el_t next_automata_list_el
;
4121 for (curr_automata_list_el
= automata_list
;
4122 curr_automata_list_el
!= NULL
;
4123 curr_automata_list_el
= next_automata_list_el
)
4125 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4126 free_automata_list_el (curr_automata_list_el
);
4130 /* Hash value of AUTOMATA_LIST. */
4132 automata_list_hash (automata_list
)
4133 const void *automata_list
;
4135 unsigned int hash_value
;
4136 automata_list_el_t curr_automata_list_el
;
4139 for (curr_automata_list_el
= (automata_list_el_t
) automata_list
;
4140 curr_automata_list_el
!= NULL
;
4141 curr_automata_list_el
= curr_automata_list_el
->next_automata_list_el
)
4142 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4143 | (hash_value
<< CHAR_BIT
))
4144 + curr_automata_list_el
->automaton
->automaton_order_num
);
4148 /* Return nonzero value if the automata_lists are the same. */
4150 automata_list_eq_p (automata_list_1
, automata_list_2
)
4151 const void *automata_list_1
;
4152 const void *automata_list_2
;
4154 automata_list_el_t automata_list_el_1
;
4155 automata_list_el_t automata_list_el_2
;
4157 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4158 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4159 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4160 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4161 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4162 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4164 return automata_list_el_1
== automata_list_el_2
;
4167 /* Initialization of the abstract data. */
4169 initiate_automata_lists ()
4171 first_free_automata_list_el
= NULL
;
4172 automata_list_table
= htab_create (1500, automata_list_hash
,
4173 automata_list_eq_p
, (htab_del
) 0);
4176 /* The following function starts new automata list and makes it the
4179 automata_list_start ()
4181 current_automata_list
= NULL
;
4184 /* The following function adds AUTOMATON to the current list. */
4186 automata_list_add (automaton
)
4187 automaton_t automaton
;
4189 automata_list_el_t el
;
4191 el
= get_free_automata_list_el ();
4192 el
->automaton
= automaton
;
4193 el
->next_automata_list_el
= current_automata_list
;
4194 current_automata_list
= el
;
4197 /* The following function finishes forming the current list, inserts
4198 it into the table and returns it. */
4199 static automata_list_el_t
4200 automata_list_finish ()
4204 if (current_automata_list
== NULL
)
4206 entry_ptr
= htab_find_slot (automata_list_table
,
4207 (void *) current_automata_list
, 1);
4208 if (*entry_ptr
== NULL
)
4209 *entry_ptr
= (void *) current_automata_list
;
4211 free_automata_list (current_automata_list
);
4212 current_automata_list
= NULL
;
4213 return (automata_list_el_t
) *entry_ptr
;
4216 /* Finishing work with the abstract data. */
4218 finish_automata_lists ()
4220 htab_delete (automata_list_table
);
4225 /* The page contains abstract data for work with exclusion sets (see
4226 exclusion_set in file rtl.def). */
4228 /* The following variable refers to an exclusion set returned by
4229 get_excl_set. This is bit string of length equal to cpu units
4230 number. If exclusion set for given unit contains 1 for a unit,
4231 then simultaneous reservation of the units is prohibited. */
4232 static reserv_sets_t excl_set
;
4234 /* The array contains exclusion sets for each unit. */
4235 static reserv_sets_t
*unit_excl_set_table
;
4237 /* The following function forms the array containing exclusion sets
4240 initiate_excl_sets ()
4243 reserv_sets_t unit_excl_set
;
4247 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4248 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4249 obstack_finish (&irp
);
4250 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4251 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4252 obstack_finish (&irp
);
4253 /* Evaluate unit exclusion sets. */
4254 for (i
= 0; i
< description
->decls_num
; i
++)
4256 decl
= description
->decls
[i
];
4257 if (decl
->mode
== dm_unit
)
4259 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4260 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4261 obstack_finish (&irp
);
4262 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4263 for (el
= decl
->decl
.unit
.excl_list
;
4265 el
= el
->next_unit_set_el
)
4266 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4267 unit_excl_set_table
[decl
->decl
.unit
.unit_num
] = unit_excl_set
;
4272 /* The function sets up and return EXCL_SET which is union of
4273 exclusion sets for each unit in IN_SET. */
4274 static reserv_sets_t
4275 get_excl_set (in_set
)
4276 reserv_sets_t in_set
;
4284 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4285 memset (excl_set
, 0, chars_num
);
4286 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4287 if (((unsigned char *) in_set
) [excl_char_num
])
4288 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4289 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4291 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4292 if (start_unit_num
>= description
->units_num
)
4294 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4297 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4305 /* The page contains abstract data for work with presence/absence sets
4306 (see presence_set/absence_set in file rtl.def). */
4308 /* The following variables refer to correspondingly an presence and an
4309 absence set returned by get_presence_absence_set. This is bit
4310 string of length equal to cpu units number. */
4311 static reserv_sets_t presence_set
, absence_set
;
4313 /* The following arrays contain correspondingly presence and absence
4314 sets for each unit. */
4315 static reserv_sets_t
*unit_presence_set_table
, *unit_absence_set_table
;
4317 /* The following function forms the array containing presence and
4318 absence sets for each unit */
4320 initiate_presence_absence_sets ()
4323 reserv_sets_t unit_set
;
4327 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4328 presence_set
= (reserv_sets_t
) obstack_base (&irp
);
4329 obstack_finish (&irp
);
4330 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4331 unit_presence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4332 obstack_finish (&irp
);
4333 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4334 absence_set
= (reserv_sets_t
) obstack_base (&irp
);
4335 obstack_finish (&irp
);
4336 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4337 unit_absence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4338 obstack_finish (&irp
);
4339 /* Evaluate unit presence/absence sets. */
4340 for (i
= 0; i
< description
->decls_num
; i
++)
4342 decl
= description
->decls
[i
];
4343 if (decl
->mode
== dm_unit
)
4345 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4346 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4347 obstack_finish (&irp
);
4348 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4349 for (el
= decl
->decl
.unit
.presence_list
;
4351 el
= el
->next_unit_set_el
)
4352 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4353 unit_presence_set_table
[decl
->decl
.unit
.unit_num
] = unit_set
;
4355 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4356 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4357 obstack_finish (&irp
);
4358 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4359 for (el
= decl
->decl
.unit
.absence_list
;
4361 el
= el
->next_unit_set_el
)
4362 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4363 unit_absence_set_table
[decl
->decl
.unit
.unit_num
] = unit_set
;
4368 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4369 ABSENCE_SET which is union of corresponding sets for each unit in
4371 static reserv_sets_t
4372 get_presence_absence_set (in_set
, presence_p
)
4373 reserv_sets_t in_set
;
4382 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4384 memset (presence_set
, 0, chars_num
);
4386 memset (absence_set
, 0, chars_num
);
4387 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4388 if (((unsigned char *) in_set
) [char_num
])
4389 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4390 if ((((unsigned char *) in_set
) [char_num
] >> i
) & 1)
4392 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4393 if (start_unit_num
>= description
->units_num
)
4394 return (presence_p
? presence_set
: absence_set
);
4395 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4397 presence_set
[unit_num
]
4398 |= unit_presence_set_table
[start_unit_num
] [unit_num
];
4400 absence_set
[unit_num
]
4401 |= unit_absence_set_table
[start_unit_num
] [unit_num
];
4403 return (presence_p
? presence_set
: absence_set
);
4408 /* This page contains code for transformation of original reservations
4409 described in .md file. The main goal of transformations is
4410 simplifying reservation and lifting up all `|' on the top of IR
4411 reservation representation. */
4414 /* The following function makes copy of IR representation of
4415 reservation. The function also substitutes all reservations
4416 defined by define_reservation by corresponding value during making
4419 copy_insn_regexp (regexp
)
4425 if (regexp
->mode
== rm_reserv
)
4426 result
= copy_insn_regexp (regexp
->regexp
.reserv
.reserv_decl
->regexp
);
4427 else if (regexp
->mode
== rm_unit
)
4428 result
= copy_node (regexp
, sizeof (struct regexp
));
4429 else if (regexp
->mode
== rm_repeat
)
4431 result
= copy_node (regexp
, sizeof (struct regexp
));
4432 result
->regexp
.repeat
.regexp
4433 = copy_insn_regexp (regexp
->regexp
.repeat
.regexp
);
4435 else if (regexp
->mode
== rm_sequence
)
4437 result
= copy_node (regexp
,
4438 sizeof (struct regexp
) + sizeof (regexp_t
)
4439 * (regexp
->regexp
.sequence
.regexps_num
- 1));
4440 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4441 result
->regexp
.sequence
.regexps
[i
]
4442 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4444 else if (regexp
->mode
== rm_allof
)
4446 result
= copy_node (regexp
,
4447 sizeof (struct regexp
) + sizeof (regexp_t
)
4448 * (regexp
->regexp
.allof
.regexps_num
- 1));
4449 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4450 result
->regexp
.allof
.regexps
[i
]
4451 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4453 else if (regexp
->mode
== rm_oneof
)
4455 result
= copy_node (regexp
,
4456 sizeof (struct regexp
) + sizeof (regexp_t
)
4457 * (regexp
->regexp
.oneof
.regexps_num
- 1));
4458 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4459 result
->regexp
.oneof
.regexps
[i
]
4460 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4464 if (regexp
->mode
!= rm_nothing
)
4466 result
= copy_node (regexp
, sizeof (struct regexp
));
4471 /* The following variable is set up 1 if a transformation has been
4473 static int regexp_transformed_p
;
4475 /* The function makes transformation
4478 transform_1 (regexp
)
4486 if (regexp
->mode
== rm_repeat
)
4488 repeat_num
= regexp
->regexp
.repeat
.repeat_num
;
4489 if (repeat_num
<= 1)
4491 operand
= regexp
->regexp
.repeat
.regexp
;
4493 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4494 * (repeat_num
- 1));
4495 regexp
->mode
= rm_sequence
;
4497 regexp
->regexp
.sequence
.regexps_num
= repeat_num
;
4498 for (i
= 0; i
< repeat_num
; i
++)
4499 regexp
->regexp
.sequence
.regexps
[i
] = copy_insn_regexp (operand
);
4500 regexp_transformed_p
= 1;
4505 /* The function makes transformations
4506 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4507 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4508 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4510 transform_2 (regexp
)
4513 if (regexp
->mode
== rm_sequence
)
4520 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4521 if (regexp
->regexp
.sequence
.regexps
[i
]->mode
== rm_sequence
)
4524 sequence
= regexp
->regexp
.sequence
.regexps
[i
];
4527 if (i
< regexp
->regexp
.sequence
.regexps_num
)
4529 if (sequence
->regexp
.sequence
.regexps_num
<= 1
4530 || regexp
->regexp
.sequence
.regexps_num
<= 1)
4532 result
= create_node (sizeof (struct regexp
)
4534 * (regexp
->regexp
.sequence
.regexps_num
4535 + sequence
->regexp
.sequence
.regexps_num
4537 result
->mode
= rm_sequence
;
4538 result
->pos
= regexp
->pos
;
4539 result
->regexp
.sequence
.regexps_num
4540 = (regexp
->regexp
.sequence
.regexps_num
4541 + sequence
->regexp
.sequence
.regexps_num
- 1);
4542 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4543 if (i
< sequence_index
)
4544 result
->regexp
.sequence
.regexps
[i
]
4545 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4546 else if (i
> sequence_index
)
4547 result
->regexp
.sequence
.regexps
4548 [i
+ sequence
->regexp
.sequence
.regexps_num
- 1]
4549 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4551 for (j
= 0; j
< sequence
->regexp
.sequence
.regexps_num
; j
++)
4552 result
->regexp
.sequence
.regexps
[i
+ j
]
4553 = copy_insn_regexp (sequence
->regexp
.sequence
.regexps
[j
]);
4554 regexp_transformed_p
= 1;
4558 else if (regexp
->mode
== rm_allof
)
4565 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4566 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_allof
)
4569 allof
= regexp
->regexp
.allof
.regexps
[i
];
4572 if (i
< regexp
->regexp
.allof
.regexps_num
)
4574 if (allof
->regexp
.allof
.regexps_num
<= 1
4575 || regexp
->regexp
.allof
.regexps_num
<= 1)
4577 result
= create_node (sizeof (struct regexp
)
4579 * (regexp
->regexp
.allof
.regexps_num
4580 + allof
->regexp
.allof
.regexps_num
- 2));
4581 result
->mode
= rm_allof
;
4582 result
->pos
= regexp
->pos
;
4583 result
->regexp
.allof
.regexps_num
4584 = (regexp
->regexp
.allof
.regexps_num
4585 + allof
->regexp
.allof
.regexps_num
- 1);
4586 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4587 if (i
< allof_index
)
4588 result
->regexp
.allof
.regexps
[i
]
4589 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4590 else if (i
> allof_index
)
4591 result
->regexp
.allof
.regexps
4592 [i
+ allof
->regexp
.allof
.regexps_num
- 1]
4593 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4595 for (j
= 0; j
< allof
->regexp
.allof
.regexps_num
; j
++)
4596 result
->regexp
.allof
.regexps
[i
+ j
]
4597 = copy_insn_regexp (allof
->regexp
.allof
.regexps
[j
]);
4598 regexp_transformed_p
= 1;
4602 else if (regexp
->mode
== rm_oneof
)
4609 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4610 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
4613 oneof
= regexp
->regexp
.oneof
.regexps
[i
];
4616 if (i
< regexp
->regexp
.oneof
.regexps_num
)
4618 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4619 || regexp
->regexp
.oneof
.regexps_num
<= 1)
4621 result
= create_node (sizeof (struct regexp
)
4623 * (regexp
->regexp
.oneof
.regexps_num
4624 + oneof
->regexp
.oneof
.regexps_num
- 2));
4625 result
->mode
= rm_oneof
;
4626 result
->pos
= regexp
->pos
;
4627 result
->regexp
.oneof
.regexps_num
4628 = (regexp
->regexp
.oneof
.regexps_num
4629 + oneof
->regexp
.oneof
.regexps_num
- 1);
4630 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4631 if (i
< oneof_index
)
4632 result
->regexp
.oneof
.regexps
[i
]
4633 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4634 else if (i
> oneof_index
)
4635 result
->regexp
.oneof
.regexps
4636 [i
+ oneof
->regexp
.oneof
.regexps_num
- 1]
4637 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4639 for (j
= 0; j
< oneof
->regexp
.oneof
.regexps_num
; j
++)
4640 result
->regexp
.oneof
.regexps
[i
+ j
]
4641 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[j
]);
4642 regexp_transformed_p
= 1;
4649 /* The function makes transformations
4650 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4651 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4652 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4653 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
4655 transform_3 (regexp
)
4658 if (regexp
->mode
== rm_sequence
)
4666 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4667 if (regexp
->regexp
.sequence
.regexps
[i
]->mode
== rm_oneof
)
4670 oneof
= regexp
->regexp
.sequence
.regexps
[i
];
4673 if (i
< regexp
->regexp
.sequence
.regexps_num
)
4675 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4676 || regexp
->regexp
.sequence
.regexps_num
<= 1)
4678 result
= create_node (sizeof (struct regexp
)
4680 * (oneof
->regexp
.oneof
.regexps_num
- 1));
4681 result
->mode
= rm_oneof
;
4682 result
->pos
= regexp
->pos
;
4683 result
->regexp
.oneof
.regexps_num
= oneof
->regexp
.oneof
.regexps_num
;
4684 for (i
= 0; i
< result
->regexp
.oneof
.regexps_num
; i
++)
4687 = create_node (sizeof (struct regexp
)
4689 * (regexp
->regexp
.sequence
.regexps_num
- 1));
4690 sequence
->mode
= rm_sequence
;
4691 sequence
->pos
= regexp
->pos
;
4692 sequence
->regexp
.sequence
.regexps_num
4693 = regexp
->regexp
.sequence
.regexps_num
;
4694 result
->regexp
.oneof
.regexps
[i
] = sequence
;
4695 for (j
= 0; j
< sequence
->regexp
.sequence
.regexps_num
; j
++)
4696 if (j
!= oneof_index
)
4697 sequence
->regexp
.sequence
.regexps
[j
]
4698 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[j
]);
4700 sequence
->regexp
.sequence
.regexps
[j
]
4701 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[i
]);
4703 regexp_transformed_p
= 1;
4707 else if (regexp
->mode
== rm_allof
)
4709 regexp_t oneof
, seq
;
4710 int oneof_index
, max_seq_length
, allof_length
;
4712 regexp_t allof
, allof_op
;
4715 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4716 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_oneof
)
4719 oneof
= regexp
->regexp
.allof
.regexps
[i
];
4722 if (i
< regexp
->regexp
.allof
.regexps_num
)
4724 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4725 || regexp
->regexp
.allof
.regexps_num
<= 1)
4727 result
= create_node (sizeof (struct regexp
)
4729 * (oneof
->regexp
.oneof
.regexps_num
- 1));
4730 result
->mode
= rm_oneof
;
4731 result
->pos
= regexp
->pos
;
4732 result
->regexp
.oneof
.regexps_num
= oneof
->regexp
.oneof
.regexps_num
;
4733 for (i
= 0; i
< result
->regexp
.oneof
.regexps_num
; i
++)
4736 = create_node (sizeof (struct regexp
)
4738 * (regexp
->regexp
.allof
.regexps_num
- 1));
4739 allof
->mode
= rm_allof
;
4740 allof
->pos
= regexp
->pos
;
4741 allof
->regexp
.allof
.regexps_num
4742 = regexp
->regexp
.allof
.regexps_num
;
4743 result
->regexp
.oneof
.regexps
[i
] = allof
;
4744 for (j
= 0; j
< allof
->regexp
.allof
.regexps_num
; j
++)
4745 if (j
!= oneof_index
)
4746 allof
->regexp
.allof
.regexps
[j
]
4747 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[j
]);
4749 allof
->regexp
.allof
.regexps
[j
]
4750 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[i
]);
4752 regexp_transformed_p
= 1;
4756 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4757 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_sequence
)
4759 seq
= regexp
->regexp
.allof
.regexps
[i
];
4760 if (max_seq_length
< seq
->regexp
.sequence
.regexps_num
)
4761 max_seq_length
= seq
->regexp
.sequence
.regexps_num
;
4763 else if (regexp
->regexp
.allof
.regexps
[i
]->mode
!= rm_unit
)
4768 if (max_seq_length
!= 0)
4770 if (max_seq_length
== 1 || regexp
->regexp
.allof
.regexps_num
<= 1)
4772 result
= create_node (sizeof (struct regexp
)
4773 + sizeof (regexp_t
) * (max_seq_length
- 1));
4774 result
->mode
= rm_sequence
;
4775 result
->pos
= regexp
->pos
;
4776 result
->regexp
.sequence
.regexps_num
= max_seq_length
;
4777 for (i
= 0; i
< max_seq_length
; i
++)
4780 for (j
= 0; j
< regexp
->regexp
.allof
.regexps_num
; j
++)
4781 if (regexp
->regexp
.allof
.regexps
[j
]->mode
== rm_sequence
4782 && (i
< (regexp
->regexp
.allof
.regexps
[j
]
4783 ->regexp
.sequence
.regexps_num
)))
4785 allof_op
= (regexp
->regexp
.allof
.regexps
[j
]
4786 ->regexp
.sequence
.regexps
[i
]);
4790 && regexp
->regexp
.allof
.regexps
[j
]->mode
== rm_unit
)
4792 allof_op
= regexp
->regexp
.allof
.regexps
[j
];
4795 if (allof_length
== 1)
4796 result
->regexp
.sequence
.regexps
[i
] = allof_op
;
4799 allof
= create_node (sizeof (struct regexp
)
4801 * (allof_length
- 1));
4802 allof
->mode
= rm_allof
;
4803 allof
->pos
= regexp
->pos
;
4804 allof
->regexp
.allof
.regexps_num
= allof_length
;
4805 result
->regexp
.sequence
.regexps
[i
] = allof
;
4807 for (j
= 0; j
< regexp
->regexp
.allof
.regexps_num
; j
++)
4808 if (regexp
->regexp
.allof
.regexps
[j
]->mode
== rm_sequence
4809 && (i
< (regexp
->regexp
.allof
.regexps
[j
]
4810 ->regexp
.sequence
.regexps_num
)))
4812 allof_op
= (regexp
->regexp
.allof
.regexps
[j
]
4813 ->regexp
.sequence
.regexps
[i
]);
4814 allof
->regexp
.allof
.regexps
[allof_length
] = allof_op
;
4819 && (regexp
->regexp
.allof
.regexps
[j
]->mode
4822 allof_op
= regexp
->regexp
.allof
.regexps
[j
];
4823 allof
->regexp
.allof
.regexps
[allof_length
] = allof_op
;
4828 regexp_transformed_p
= 1;
4835 /* The function traverses IR of reservation and applies transformations
4836 implemented by FUNC. */
4838 regexp_transform_func (regexp
, func
)
4840 regexp_t (*func
) PARAMS ((regexp_t regexp
));
4844 if (regexp
->mode
== rm_sequence
)
4845 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4846 regexp
->regexp
.sequence
.regexps
[i
]
4847 = regexp_transform_func (regexp
->regexp
.sequence
.regexps
[i
], func
);
4848 else if (regexp
->mode
== rm_allof
)
4849 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4850 regexp
->regexp
.allof
.regexps
[i
]
4851 = regexp_transform_func (regexp
->regexp
.allof
.regexps
[i
], func
);
4852 else if (regexp
->mode
== rm_oneof
)
4853 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4854 regexp
->regexp
.oneof
.regexps
[i
]
4855 = regexp_transform_func (regexp
->regexp
.oneof
.regexps
[i
], func
);
4856 else if (regexp
->mode
== rm_repeat
)
4857 regexp
->regexp
.repeat
.regexp
4858 = regexp_transform_func (regexp
->regexp
.repeat
.regexp
, func
);
4859 else if (regexp
->mode
!= rm_nothing
&& regexp
->mode
!= rm_unit
)
4861 return (*func
) (regexp
);
4864 /* The function applies all transformations for IR representation of
4865 reservation REGEXP. */
4867 transform_regexp (regexp
)
4870 regexp
= regexp_transform_func (regexp
, transform_1
);
4873 regexp_transformed_p
= 0;
4874 regexp
= regexp_transform_func (regexp
, transform_2
);
4875 regexp
= regexp_transform_func (regexp
, transform_3
);
4877 while (regexp_transformed_p
);
4881 /* The function applys all transformations for reservations of all
4882 insn declarations. */
4884 transform_insn_regexps ()
4889 transform_time
= create_ticker ();
4890 add_advance_cycle_insn_decl ();
4891 fprintf (stderr
, "Reservation transformation...");
4893 for (i
= 0; i
< description
->decls_num
; i
++)
4895 decl
= description
->decls
[i
];
4896 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
4897 decl
->decl
.insn_reserv
.transformed_regexp
4898 = transform_regexp (copy_insn_regexp
4899 (decl
->decl
.insn_reserv
.regexp
));
4901 fprintf (stderr
, "done\n");
4902 ticker_off (&transform_time
);
4908 /* The following variable is an array indexed by cycle. Each element
4909 contains cyclic list of units which should be in the same cycle. */
4910 static unit_decl_t
*the_same_automaton_lists
;
4912 /* The function processes all alternative reservations on CYCLE in
4913 given REGEXP to check the UNIT is not reserved on the all
4914 alternatives. If it is true, the unit should be in the same
4915 automaton with other analogous units reserved on CYCLE in given
4918 process_unit_to_form_the_same_automaton_unit_lists (unit
, regexp
, cycle
)
4924 regexp_t seq
, allof
;
4925 unit_decl_t unit_decl
, last
;
4927 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
4929 unit_decl
= unit
->regexp
.unit
.unit_decl
;
4930 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
4932 seq
= regexp
->regexp
.oneof
.regexps
[i
];
4933 if (seq
->mode
== rm_sequence
)
4935 if (cycle
>= seq
->regexp
.sequence
.regexps_num
)
4937 allof
= seq
->regexp
.sequence
.regexps
[cycle
];
4938 if (allof
->mode
== rm_allof
)
4940 for (k
= 0; k
< allof
->regexp
.allof
.regexps_num
; k
++)
4941 if (allof
->regexp
.allof
.regexps
[k
]->mode
== rm_unit
4942 && (allof
->regexp
.allof
.regexps
[k
]->regexp
.unit
.unit_decl
4945 if (k
>= allof
->regexp
.allof
.regexps_num
)
4948 else if (allof
->mode
== rm_unit
4949 && allof
->regexp
.unit
.unit_decl
!= unit_decl
)
4952 else if (cycle
!= 0)
4954 else if (seq
->mode
== rm_allof
)
4956 for (k
= 0; k
< seq
->regexp
.allof
.regexps_num
; k
++)
4957 if (seq
->regexp
.allof
.regexps
[k
]->mode
== rm_unit
4958 && (seq
->regexp
.allof
.regexps
[k
]->regexp
.unit
.unit_decl
4961 if (k
>= seq
->regexp
.allof
.regexps_num
)
4964 else if (seq
->mode
== rm_unit
&& seq
->regexp
.unit
.unit_decl
!= unit_decl
)
4969 if (the_same_automaton_lists
[cycle
] == NULL
)
4970 the_same_automaton_lists
[cycle
] = unit_decl
;
4973 for (last
= the_same_automaton_lists
[cycle
];;)
4975 if (last
== unit_decl
)
4977 if (last
->the_same_automaton_unit
4978 == the_same_automaton_lists
[cycle
])
4980 last
= last
->the_same_automaton_unit
;
4982 last
->the_same_automaton_unit
= unit_decl
->the_same_automaton_unit
;
4983 unit_decl
->the_same_automaton_unit
4984 = the_same_automaton_lists
[cycle
];
4989 /* The function processes given REGEXP to find units which should be
4990 in the same automaton. */
4992 form_the_same_automaton_unit_lists_from_regexp (regexp
)
4996 regexp_t seq
, allof
, unit
;
4998 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5000 for (i
= 0; i
< description
->max_insn_reserv_cycles
; i
++)
5001 the_same_automaton_lists
[i
] = NULL
;
5002 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
5004 seq
= regexp
->regexp
.oneof
.regexps
[i
];
5005 if (seq
->mode
== rm_sequence
)
5006 for (j
= 0; j
< seq
->regexp
.sequence
.regexps_num
; j
++)
5008 allof
= seq
->regexp
.sequence
.regexps
[j
];
5009 if (allof
->mode
== rm_allof
)
5010 for (k
= 0; k
< allof
->regexp
.allof
.regexps_num
; k
++)
5012 unit
= allof
->regexp
.allof
.regexps
[k
];
5013 if (unit
->mode
== rm_unit
)
5014 process_unit_to_form_the_same_automaton_unit_lists
5016 else if (unit
->mode
!= rm_nothing
)
5019 else if (allof
->mode
== rm_unit
)
5020 process_unit_to_form_the_same_automaton_unit_lists
5022 else if (allof
->mode
!= rm_nothing
)
5025 else if (seq
->mode
== rm_allof
)
5026 for (k
= 0; k
< seq
->regexp
.allof
.regexps_num
; k
++)
5028 unit
= seq
->regexp
.allof
.regexps
[k
];
5029 if (unit
->mode
== rm_unit
)
5030 process_unit_to_form_the_same_automaton_unit_lists
5032 else if (unit
->mode
!= rm_nothing
)
5035 else if (seq
->mode
== rm_unit
)
5036 process_unit_to_form_the_same_automaton_unit_lists (seq
, regexp
, 0);
5037 else if (seq
->mode
!= rm_nothing
)
5042 /* The function initializes data to search for units which should be
5043 in the same automaton and call function
5044 `form_the_same_automaton_unit_lists_from_regexp' for each insn
5045 reservation regexp. */
5047 form_the_same_automaton_unit_lists ()
5052 the_same_automaton_lists
5053 = (unit_decl_t
*) xmalloc (description
->max_insn_reserv_cycles
5054 * sizeof (unit_decl_t
));
5055 for (i
= 0; i
< description
->decls_num
; i
++)
5057 decl
= description
->decls
[i
];
5058 if (decl
->mode
== dm_unit
)
5060 decl
->decl
.unit
.the_same_automaton_message_reported_p
= FALSE
;
5061 decl
->decl
.unit
.the_same_automaton_unit
= &decl
->decl
.unit
;
5064 for (i
= 0; i
< description
->decls_num
; i
++)
5066 decl
= description
->decls
[i
];
5067 if (decl
->mode
== dm_insn_reserv
)
5068 form_the_same_automaton_unit_lists_from_regexp
5069 (decl
->decl
.insn_reserv
.transformed_regexp
);
5071 free (the_same_automaton_lists
);
5074 /* The function finds units which should be in the same automaton and,
5075 if they are not, reports about it. */
5077 check_unit_distributions_to_automata ()
5080 unit_decl_t start_unit_decl
, unit_decl
;
5083 form_the_same_automaton_unit_lists ();
5084 for (i
= 0; i
< description
->decls_num
; i
++)
5086 decl
= description
->decls
[i
];
5087 if (decl
->mode
== dm_unit
)
5089 start_unit_decl
= &decl
->decl
.unit
;
5090 if (!start_unit_decl
->the_same_automaton_message_reported_p
)
5091 for (unit_decl
= start_unit_decl
->the_same_automaton_unit
;
5092 unit_decl
!= start_unit_decl
;
5093 unit_decl
= unit_decl
->the_same_automaton_unit
)
5094 if (start_unit_decl
->automaton_decl
!= unit_decl
->automaton_decl
)
5096 error ("Units `%s' and `%s' should be in the same automaton",
5097 start_unit_decl
->name
, unit_decl
->name
);
5098 unit_decl
->the_same_automaton_message_reported_p
= TRUE
;
5106 /* The page contains code for building alt_states (see comments for
5107 IR) describing all possible insns reservations of an automaton. */
5109 /* Current state being formed for which the current alt_state
5111 static state_t state_being_formed
;
5113 /* Current alt_state being formed. */
5114 static alt_state_t alt_state_being_formed
;
5116 /* This recursive function processes `,' and units in reservation
5117 REGEXP for forming alt_states of AUTOMATON. It is believed that
5118 CURR_CYCLE is start cycle of all reservation REGEXP. */
5120 process_seq_for_forming_states (regexp
, automaton
, curr_cycle
)
5122 automaton_t automaton
;
5129 else if (regexp
->mode
== rm_unit
)
5131 if (regexp
->regexp
.unit
.unit_decl
->corresponding_automaton_num
5132 == automaton
->automaton_order_num
)
5133 set_state_reserv (state_being_formed
, curr_cycle
,
5134 regexp
->regexp
.unit
.unit_decl
->unit_num
);
5137 else if (regexp
->mode
== rm_sequence
)
5139 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
5141 = process_seq_for_forming_states
5142 (regexp
->regexp
.sequence
.regexps
[i
], automaton
, curr_cycle
) + 1;
5145 else if (regexp
->mode
== rm_allof
)
5147 int finish_cycle
= 0;
5150 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
5153 = process_seq_for_forming_states (regexp
->regexp
.allof
.regexps
[i
],
5154 automaton
, curr_cycle
);
5155 if (finish_cycle
< cycle
)
5156 finish_cycle
= cycle
;
5158 return finish_cycle
;
5162 if (regexp
->mode
!= rm_nothing
)
5168 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5169 inserts alt_state into the table. */
5171 finish_forming_alt_state (alt_state
, automaton
)
5172 alt_state_t alt_state
;
5173 automaton_t automaton ATTRIBUTE_UNUSED
;
5175 state_t state_in_table
;
5176 state_t corresponding_state
;
5178 corresponding_state
= alt_state
->state
;
5179 state_in_table
= insert_state (corresponding_state
);
5180 if (state_in_table
!= corresponding_state
)
5182 free_state (corresponding_state
);
5183 alt_state
->state
= state_in_table
;
5187 /* The following variable value is current automaton insn for whose
5188 reservation the alt states are created. */
5189 static ainsn_t curr_ainsn
;
5191 /* This recursive function processes `|' in reservation REGEXP for
5192 forming alt_states of AUTOMATON. List of the alt states should
5193 have the same order as in the description. */
5195 process_alts_for_forming_states (regexp
, automaton
, inside_oneof_p
)
5197 automaton_t automaton
;
5202 if (regexp
->mode
!= rm_oneof
)
5204 alt_state_being_formed
= get_free_alt_state ();
5205 state_being_formed
= get_free_state (1, automaton
);
5206 alt_state_being_formed
->state
= state_being_formed
;
5207 /* We inserts in reverse order but we process alternatives also
5208 in reverse order. So we have the same order of alternative
5209 as in the description. */
5210 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5211 curr_ainsn
->alt_states
= alt_state_being_formed
;
5212 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5213 finish_forming_alt_state (alt_state_being_formed
, automaton
);
5219 /* We processes it in reverse order to get list with the same
5220 order as in the description. See also the previous
5222 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
5223 process_alts_for_forming_states (regexp
->regexp
.oneof
.regexps
[i
],
5228 /* Create nodes alt_state for all AUTOMATON insns. */
5230 create_alt_states (automaton
)
5231 automaton_t automaton
;
5233 struct insn_reserv_decl
*reserv_decl
;
5235 for (curr_ainsn
= automaton
->ainsn_list
;
5237 curr_ainsn
= curr_ainsn
->next_ainsn
)
5239 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5240 if (reserv_decl
!= &advance_cycle_insn_decl
->decl
.insn_reserv
)
5242 curr_ainsn
->alt_states
= NULL
;
5243 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5245 curr_ainsn
->sorted_alt_states
5246 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5253 /* The page contains major code for building DFA(s) for fast pipeline
5254 hazards recognition. */
5256 /* The function forms list of ainsns of AUTOMATON with the same
5259 form_ainsn_with_same_reservs (automaton
)
5260 automaton_t automaton
;
5264 vla_ptr_t first_insns
;
5265 vla_ptr_t last_insns
;
5267 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5268 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5269 for (curr_ainsn
= automaton
->ainsn_list
;
5271 curr_ainsn
= curr_ainsn
->next_ainsn
)
5272 if (curr_ainsn
->insn_reserv_decl
5273 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
5275 curr_ainsn
->next_same_reservs_insn
= NULL
;
5276 curr_ainsn
->first_insn_with_same_reservs
= 1;
5280 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5282 (curr_ainsn
->sorted_alt_states
,
5283 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5285 curr_ainsn
->next_same_reservs_insn
= NULL
;
5286 if (i
< VLA_PTR_LENGTH (first_insns
))
5288 curr_ainsn
->first_insn_with_same_reservs
= 0;
5289 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5291 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5295 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5296 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5297 curr_ainsn
->first_insn_with_same_reservs
= 1;
5300 VLA_PTR_DELETE (first_insns
);
5301 VLA_PTR_DELETE (last_insns
);
5304 /* The following function creates all states of nondeterministic (if
5305 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5307 make_automaton (automaton
)
5308 automaton_t automaton
;
5311 struct insn_reserv_decl
*insn_reserv_decl
;
5312 alt_state_t alt_state
;
5314 state_t start_state
;
5316 ainsn_t advance_cycle_ainsn
;
5318 vla_ptr_t state_stack
;
5320 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5321 /* Create the start state (empty state). */
5322 start_state
= insert_state (get_free_state (1, automaton
));
5323 automaton
->start_state
= start_state
;
5324 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5325 VLA_PTR_ADD (state_stack
, start_state
);
5326 while (VLA_PTR_LENGTH (state_stack
) != 0)
5328 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5329 VLA_PTR_SHORTEN (state_stack
, 1);
5330 advance_cycle_ainsn
= NULL
;
5331 for (ainsn
= automaton
->ainsn_list
;
5333 ainsn
= ainsn
->next_ainsn
)
5334 if (ainsn
->first_insn_with_same_reservs
)
5336 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5337 if (insn_reserv_decl
!= &advance_cycle_insn_decl
->decl
.insn_reserv
)
5339 /* We process alt_states in the same order as they are
5340 present in the description. */
5342 for (alt_state
= ainsn
->alt_states
;
5344 alt_state
= alt_state
->next_alt_state
)
5346 state2
= alt_state
->state
;
5347 if (!intersected_state_reservs_p (state
, state2
))
5349 state2
= states_union (state
, state2
);
5350 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5352 state2
->it_was_placed_in_stack_for_NDFA_forming
5354 VLA_PTR_ADD (state_stack
, state2
);
5356 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5361 if (!ndfa_flag
&& added_arc
!= NULL
)
5363 added_arc
->state_alts
= 0;
5364 for (alt_state
= ainsn
->alt_states
;
5366 alt_state
= alt_state
->next_alt_state
)
5368 state2
= alt_state
->state
;
5369 if (!intersected_state_reservs_p (state
, state2
))
5370 added_arc
->state_alts
++;
5375 advance_cycle_ainsn
= ainsn
;
5377 /* Add transition to advance cycle. */
5378 state2
= state_shift (state
);
5379 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5381 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5382 VLA_PTR_ADD (state_stack
, state2
);
5384 if (advance_cycle_ainsn
== NULL
)
5386 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5388 VLA_PTR_DELETE (state_stack
);
5391 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5393 form_arcs_marked_by_insn (state
)
5400 for (i
= 0; i
< description
->decls_num
; i
++)
5402 decl
= description
->decls
[i
];
5403 if (decl
->mode
== dm_insn_reserv
)
5404 decl
->decl
.insn_reserv
.arcs_marked_by_insn
= NULL
;
5406 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5408 if (arc
->insn
== NULL
)
5410 arc
->next_arc_marked_by_insn
5411 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5412 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5416 /* The function creates composed state (see comments for IR) from
5417 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5418 same insn. If the composed state is not in STATE_STACK yet, it is
5419 popped to STATE_STACK. */
5421 create_composed_state (original_state
, arcs_marked_by_insn
, state_stack
)
5422 state_t original_state
;
5423 arc_t arcs_marked_by_insn
;
5424 vla_ptr_t
*state_stack
;
5427 alt_state_t curr_alt_state
;
5428 alt_state_t new_alt_state
;
5431 state_t state_in_table
;
5433 alt_state_t canonical_alt_states_list
;
5436 if (arcs_marked_by_insn
== NULL
)
5438 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5439 state
= arcs_marked_by_insn
->to_state
;
5444 /* Create composed state. */
5445 state
= get_free_state (0, arcs_marked_by_insn
->to_state
->automaton
);
5446 curr_alt_state
= NULL
;
5447 for (curr_arc
= arcs_marked_by_insn
;
5449 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5451 new_alt_state
= get_free_alt_state ();
5452 new_alt_state
->next_alt_state
= curr_alt_state
;
5453 new_alt_state
->state
= curr_arc
->to_state
;
5454 if (curr_arc
->to_state
->component_states
!= NULL
)
5456 curr_alt_state
= new_alt_state
;
5458 /* There are not identical sets in the alt state list. */
5459 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5460 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5463 state
= canonical_alt_states_list
->state
;
5464 free_state (temp_state
);
5468 state
->component_states
= canonical_alt_states_list
;
5469 state_in_table
= insert_state (state
);
5470 if (state_in_table
!= state
)
5472 if (!state_in_table
->it_was_placed_in_stack_for_DFA_forming
)
5475 state
= state_in_table
;
5479 if (state
->it_was_placed_in_stack_for_DFA_forming
)
5481 for (curr_alt_state
= state
->component_states
;
5482 curr_alt_state
!= NULL
;
5483 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
5484 for (curr_arc
= first_out_arc (curr_alt_state
->state
);
5486 curr_arc
= next_out_arc (curr_arc
))
5487 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5489 arcs_marked_by_insn
->to_state
= state
;
5490 for (alts_number
= 0,
5491 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5493 curr_arc
= next_arc
)
5495 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5496 remove_arc (original_state
, curr_arc
);
5499 arcs_marked_by_insn
->state_alts
= alts_number
;
5502 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5504 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5505 VLA_PTR_ADD (*state_stack
, state
);
5509 /* The function transformes nondeterminstic AUTOMATON into
5512 NDFA_to_DFA (automaton
)
5513 automaton_t automaton
;
5515 state_t start_state
;
5518 vla_ptr_t state_stack
;
5521 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5522 /* Create the start state (empty state). */
5523 start_state
= automaton
->start_state
;
5524 start_state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5525 VLA_PTR_ADD (state_stack
, start_state
);
5526 while (VLA_PTR_LENGTH (state_stack
) != 0)
5528 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5529 VLA_PTR_SHORTEN (state_stack
, 1);
5530 form_arcs_marked_by_insn (state
);
5531 for (i
= 0; i
< description
->decls_num
; i
++)
5533 decl
= description
->decls
[i
];
5534 if (decl
->mode
== dm_insn_reserv
)
5535 create_composed_state
5536 (state
, decl
->decl
.insn_reserv
.arcs_marked_by_insn
,
5540 VLA_PTR_DELETE (state_stack
);
5543 /* The following variable value is current number (1, 2, ...) of passing
5545 static int curr_state_graph_pass_num
;
5547 /* This recursive function passes all states achieved from START_STATE
5548 and applies APPLIED_FUNC to them. */
5550 pass_state_graph (start_state
, applied_func
)
5551 state_t start_state
;
5552 void (*applied_func
) PARAMS ((state_t state
));
5556 if (start_state
->pass_num
== curr_state_graph_pass_num
)
5558 start_state
->pass_num
= curr_state_graph_pass_num
;
5559 (*applied_func
) (start_state
);
5560 for (arc
= first_out_arc (start_state
);
5562 arc
= next_out_arc (arc
))
5563 pass_state_graph (arc
->to_state
, applied_func
);
5566 /* This recursive function passes all states of AUTOMATON and applies
5567 APPLIED_FUNC to them. */
5569 pass_states (automaton
, applied_func
)
5570 automaton_t automaton
;
5571 void (*applied_func
) PARAMS ((state_t state
));
5573 curr_state_graph_pass_num
++;
5574 pass_state_graph (automaton
->start_state
, applied_func
);
5577 /* The function initializes code for passing of all states. */
5579 initiate_pass_states ()
5581 curr_state_graph_pass_num
= 0;
5584 /* The following vla is used for storing pointers to all achieved
5586 static vla_ptr_t all_achieved_states
;
5588 /* This function is called by function pass_states to add an achieved
5591 add_achieved_state (state
)
5594 VLA_PTR_ADD (all_achieved_states
, state
);
5597 /* The function sets up equivalence numbers of insns which mark all
5598 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5599 nonzero value) or by equiv_class_num_2 of the destination state.
5600 The function returns number of out arcs of STATE. */
5602 set_out_arc_insns_equiv_num (state
, odd_iteration_flag
)
5604 int odd_iteration_flag
;
5606 int state_out_arcs_num
;
5609 state_out_arcs_num
= 0;
5610 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5612 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
!= 0
5613 || arc
->insn
->insn_reserv_decl
->state_alts
!= 0)
5615 state_out_arcs_num
++;
5616 arc
->insn
->insn_reserv_decl
->equiv_class_num
5617 = (odd_iteration_flag
5618 ? arc
->to_state
->equiv_class_num_1
5619 : arc
->to_state
->equiv_class_num_2
);
5620 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
5621 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
== 0
5622 || arc
->insn
->insn_reserv_decl
->state_alts
<= 0)
5625 return state_out_arcs_num
;
5628 /* The function clears equivalence numbers and alt_states in all insns
5629 which mark all out arcs of STATE. */
5631 clear_arc_insns_equiv_num (state
)
5636 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5638 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
5639 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
5643 /* The function copies pointers to equivalent states from vla FROM
5646 copy_equiv_class (to
, from
)
5648 const vla_ptr_t
*from
;
5652 VLA_PTR_NULLIFY (*to
);
5653 for (class_ptr
= VLA_PTR_BEGIN (*from
);
5654 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
5656 VLA_PTR_ADD (*to
, *class_ptr
);
5659 /* The function returns nonzero value if STATE is not equivalent to
5660 another state from the same current partition on equivalence
5661 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5662 output arcs. Iteration of making equivalence partition is defined
5663 by ODD_ITERATION_FLAG. */
5665 state_is_differed (state
, original_state_out_arcs_num
, odd_iteration_flag
)
5667 int original_state_out_arcs_num
;
5668 int odd_iteration_flag
;
5671 int state_out_arcs_num
;
5673 state_out_arcs_num
= 0;
5674 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5676 state_out_arcs_num
++;
5677 if ((odd_iteration_flag
5678 ? arc
->to_state
->equiv_class_num_1
5679 : arc
->to_state
->equiv_class_num_2
)
5680 != arc
->insn
->insn_reserv_decl
->equiv_class_num
5681 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
5684 return state_out_arcs_num
!= original_state_out_arcs_num
;
5687 /* The function makes initial partition of STATES on equivalent
5690 init_equiv_class (states
, states_num
)
5695 state_t result_equiv_class
;
5697 result_equiv_class
= NULL
;
5698 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
5700 (*state_ptr
)->equiv_class_num_1
= 1;
5701 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
5702 result_equiv_class
= *state_ptr
;
5704 return result_equiv_class
;
5707 /* The function processes equivalence class given by its pointer
5708 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5709 are not equvalent states, the function partitions the class
5710 removing nonequivalent states and placing them in
5711 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5712 assigns it to the state equivalence number. If the class has been
5713 partitioned, the function returns nonzero value. */
5715 partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5716 next_iteration_classes
, new_equiv_class_num_ptr
)
5717 state_t
*equiv_class_ptr
;
5718 int odd_iteration_flag
;
5719 vla_ptr_t
*next_iteration_classes
;
5720 int *new_equiv_class_num_ptr
;
5722 state_t new_equiv_class
;
5724 state_t first_state
;
5731 if (*equiv_class_ptr
== NULL
)
5733 for (first_state
= *equiv_class_ptr
;
5734 first_state
!= NULL
;
5735 first_state
= new_equiv_class
)
5737 new_equiv_class
= NULL
;
5738 if (first_state
->next_equiv_class_state
!= NULL
)
5740 /* There are more one states in the class equivalence. */
5741 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
5742 odd_iteration_flag
);
5743 for (prev_state
= first_state
,
5744 curr_state
= first_state
->next_equiv_class_state
;
5746 curr_state
= next_state
)
5748 next_state
= curr_state
->next_equiv_class_state
;
5749 if (state_is_differed (curr_state
, out_arcs_num
,
5750 odd_iteration_flag
))
5752 /* Remove curr state from the class equivalence. */
5753 prev_state
->next_equiv_class_state
= next_state
;
5754 /* Add curr state to the new class equivalence. */
5755 curr_state
->next_equiv_class_state
= new_equiv_class
;
5756 if (new_equiv_class
== NULL
)
5757 (*new_equiv_class_num_ptr
)++;
5758 if (odd_iteration_flag
)
5759 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
5761 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
5762 new_equiv_class
= curr_state
;
5766 prev_state
= curr_state
;
5768 clear_arc_insns_equiv_num (first_state
);
5770 if (new_equiv_class
!= NULL
)
5771 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
5776 /* The function finds equivalent states of AUTOMATON. */
5778 evaluate_equiv_classes (automaton
, equiv_classes
)
5779 automaton_t automaton
;
5780 vla_ptr_t
*equiv_classes
;
5782 state_t new_equiv_class
;
5783 int new_equiv_class_num
;
5784 int odd_iteration_flag
;
5786 vla_ptr_t next_iteration_classes
;
5787 state_t
*equiv_class_ptr
;
5790 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
5791 pass_states (automaton
, add_achieved_state
);
5792 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
5793 VLA_PTR_LENGTH (all_achieved_states
));
5794 odd_iteration_flag
= 0;
5795 new_equiv_class_num
= 1;
5796 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
5797 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
5800 odd_iteration_flag
= !odd_iteration_flag
;
5802 copy_equiv_class (equiv_classes
, &next_iteration_classes
);
5803 /* Transfer equiv numbers for the next iteration. */
5804 for (state_ptr
= VLA_PTR_BEGIN (all_achieved_states
);
5805 state_ptr
<= (state_t
*) VLA_PTR_LAST (all_achieved_states
);
5807 if (odd_iteration_flag
)
5808 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
5810 (*state_ptr
)->equiv_class_num_1
= (*state_ptr
)->equiv_class_num_2
;
5811 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5812 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5814 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5815 &next_iteration_classes
,
5816 &new_equiv_class_num
))
5819 while (!finish_flag
);
5820 VLA_PTR_DELETE (next_iteration_classes
);
5821 VLA_PTR_DELETE (all_achieved_states
);
5824 /* The function merges equivalent states of AUTOMATON. */
5826 merge_states (automaton
, equiv_classes
)
5827 automaton_t automaton
;
5828 vla_ptr_t
*equiv_classes
;
5830 state_t
*equiv_class_ptr
;
5833 state_t first_class_state
;
5834 alt_state_t alt_states
;
5835 alt_state_t new_alt_state
;
5839 /* Create states corresponding to equivalence classes containing two
5841 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5842 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5844 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
5846 /* There are more one states in the class equivalence. */
5847 /* Create new compound state. */
5848 new_state
= get_free_state (0, automaton
);
5850 first_class_state
= *equiv_class_ptr
;
5851 for (curr_state
= first_class_state
;
5853 curr_state
= curr_state
->next_equiv_class_state
)
5855 curr_state
->equiv_class_state
= new_state
;
5856 new_alt_state
= get_free_alt_state ();
5857 new_alt_state
->state
= curr_state
;
5858 new_alt_state
->next_sorted_alt_state
= alt_states
;
5859 alt_states
= new_alt_state
;
5861 new_state
->component_states
= alt_states
;
5864 (*equiv_class_ptr
)->equiv_class_state
= *equiv_class_ptr
;
5865 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5866 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5868 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
5870 first_class_state
= *equiv_class_ptr
;
5871 /* Create new arcs output from the state corresponding to
5873 for (curr_arc
= first_out_arc (first_class_state
);
5875 curr_arc
= next_out_arc (curr_arc
))
5876 add_arc (first_class_state
->equiv_class_state
,
5877 curr_arc
->to_state
->equiv_class_state
,
5878 curr_arc
->insn
, curr_arc
->state_alts
);
5879 /* Delete output arcs from states of given class equivalence. */
5880 for (curr_state
= first_class_state
;
5882 curr_state
= curr_state
->next_equiv_class_state
)
5884 if (automaton
->start_state
== curr_state
)
5885 automaton
->start_state
= curr_state
->equiv_class_state
;
5886 /* Delete the state and its output arcs. */
5887 for (curr_arc
= first_out_arc (curr_state
);
5889 curr_arc
= next_arc
)
5891 next_arc
= next_out_arc (curr_arc
);
5892 free_arc (curr_arc
);
5898 /* Change `to_state' of arcs output from the state of given
5899 equivalence class. */
5900 for (curr_arc
= first_out_arc (*equiv_class_ptr
);
5902 curr_arc
= next_out_arc (curr_arc
))
5903 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
5907 /* The function sets up new_cycle_p for states if there is arc to the
5908 state marked by advance_cycle_insn_decl. */
5910 set_new_cycle_flags (state
)
5915 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5916 if (arc
->insn
->insn_reserv_decl
5917 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
5918 arc
->to_state
->new_cycle_p
= 1;
5921 /* The top level function for minimization of deterministic
5924 minimize_DFA (automaton
)
5925 automaton_t automaton
;
5927 vla_ptr_t equiv_classes
;
5929 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
5930 evaluate_equiv_classes (automaton
, &equiv_classes
);
5931 merge_states (automaton
, &equiv_classes
);
5932 pass_states (automaton
, set_new_cycle_flags
);
5933 VLA_PTR_DELETE (equiv_classes
);
5936 /* Values of two variables are counted number of states and arcs in an
5938 static int curr_counted_states_num
;
5939 static int curr_counted_arcs_num
;
5941 /* The function is called by function `pass_states' to count states
5942 and arcs of an automaton. */
5944 incr_states_and_arcs_nums (state
)
5949 curr_counted_states_num
++;
5950 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5951 curr_counted_arcs_num
++;
5954 /* The function counts states and arcs of AUTOMATON. */
5956 count_states_and_arcs (automaton
, states_num
, arcs_num
)
5957 automaton_t automaton
;
5961 curr_counted_states_num
= 0;
5962 curr_counted_arcs_num
= 0;
5963 pass_states (automaton
, incr_states_and_arcs_nums
);
5964 *states_num
= curr_counted_states_num
;
5965 *arcs_num
= curr_counted_arcs_num
;
5968 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5969 recognition after checking and simplifying IR of the
5972 build_automaton (automaton
)
5973 automaton_t automaton
;
5978 ticker_on (&NDFA_time
);
5979 make_automaton (automaton
);
5980 ticker_off (&NDFA_time
);
5981 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5982 automaton
->NDFA_states_num
= states_num
;
5983 automaton
->NDFA_arcs_num
= arcs_num
;
5984 ticker_on (&NDFA_to_DFA_time
);
5985 NDFA_to_DFA (automaton
);
5986 ticker_off (&NDFA_to_DFA_time
);
5987 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5988 automaton
->DFA_states_num
= states_num
;
5989 automaton
->DFA_arcs_num
= arcs_num
;
5990 if (!no_minimization_flag
)
5992 ticker_on (&minimize_time
);
5993 minimize_DFA (automaton
);
5994 ticker_off (&minimize_time
);
5995 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5996 automaton
->minimal_DFA_states_num
= states_num
;
5997 automaton
->minimal_DFA_arcs_num
= arcs_num
;
6003 /* The page contains code for enumeration of all states of an automaton. */
6005 /* Variable used for enumeration of all states of an automaton. Its
6006 value is current number of automaton states. */
6007 static int curr_state_order_num
;
6009 /* The function is called by function `pass_states' for enumerating
6012 set_order_state_num (state
)
6015 state
->order_state_num
= curr_state_order_num
;
6016 curr_state_order_num
++;
6019 /* The function enumerates all states of AUTOMATON. */
6021 enumerate_states (automaton
)
6022 automaton_t automaton
;
6024 curr_state_order_num
= 0;
6025 pass_states (automaton
, set_order_state_num
);
6026 automaton
->achieved_states_num
= curr_state_order_num
;
6031 /* The page contains code for finding equivalent automaton insns
6034 /* The function inserts AINSN into cyclic list
6035 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6037 insert_ainsn_into_equiv_class (ainsn
, cyclic_equiv_class_insn_list
)
6039 ainsn_t cyclic_equiv_class_insn_list
;
6041 if (cyclic_equiv_class_insn_list
== NULL
)
6042 ainsn
->next_equiv_class_insn
= ainsn
;
6045 ainsn
->next_equiv_class_insn
6046 = cyclic_equiv_class_insn_list
->next_equiv_class_insn
;
6047 cyclic_equiv_class_insn_list
->next_equiv_class_insn
= ainsn
;
6052 /* The function deletes equiv_class_insn into cyclic list of
6053 equivalent ainsns. */
6055 delete_ainsn_from_equiv_class (equiv_class_insn
)
6056 ainsn_t equiv_class_insn
;
6058 ainsn_t curr_equiv_class_insn
;
6059 ainsn_t prev_equiv_class_insn
;
6061 prev_equiv_class_insn
= equiv_class_insn
;
6062 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
6063 curr_equiv_class_insn
!= equiv_class_insn
;
6064 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
6065 prev_equiv_class_insn
= curr_equiv_class_insn
;
6066 if (prev_equiv_class_insn
!= equiv_class_insn
)
6067 prev_equiv_class_insn
->next_equiv_class_insn
6068 = equiv_class_insn
->next_equiv_class_insn
;
6071 /* The function processes AINSN of a state in order to find equivalent
6072 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6075 process_insn_equiv_class (ainsn
, insn_arcs_array
)
6077 arc_t
*insn_arcs_array
;
6081 ainsn_t cyclic_insn_list
;
6084 if (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
] == NULL
)
6087 /* New class of ainsns which are not equivalent to given ainsn. */
6088 cyclic_insn_list
= NULL
;
6091 next_insn
= curr_insn
->next_equiv_class_insn
;
6092 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6094 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6097 delete_ainsn_from_equiv_class (curr_insn
);
6098 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6101 curr_insn
= next_insn
;
6103 while (curr_insn
!= ainsn
);
6106 /* The function processes STATE in order to find equivalent ainsns. */
6108 process_state_for_insn_equiv_partition (state
)
6112 arc_t
*insn_arcs_array
;
6114 vla_ptr_t insn_arcs_vect
;
6116 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6117 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6118 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6119 /* Process insns of the arcs. */
6120 for (i
= 0; i
< description
->insns_num
; i
++)
6121 insn_arcs_array
[i
] = NULL
;
6122 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6123 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6124 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6125 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6126 VLA_PTR_DELETE (insn_arcs_vect
);
6129 /* The function searches for equivalent ainsns of AUTOMATON. */
6131 set_insn_equiv_classes (automaton
)
6132 automaton_t automaton
;
6137 ainsn_t cyclic_insn_list
;
6138 ainsn_t insn_with_same_reservs
;
6139 int equiv_classes_num
;
6141 /* All insns are included in one equivalence class. */
6142 cyclic_insn_list
= NULL
;
6143 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6144 if (ainsn
->first_insn_with_same_reservs
)
6145 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
6147 /* Process insns in order to make equivalence partition. */
6148 pass_states (automaton
, process_state_for_insn_equiv_partition
);
6149 /* Enumerate equiv classes. */
6150 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6151 /* Set undefined value. */
6152 ainsn
->insn_equiv_class_num
= -1;
6153 equiv_classes_num
= 0;
6154 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6155 if (ainsn
->insn_equiv_class_num
< 0)
6158 if (!first_insn
->first_insn_with_same_reservs
)
6160 first_insn
->first_ainsn_with_given_equialence_num
= 1;
6161 curr_insn
= first_insn
;
6164 for (insn_with_same_reservs
= curr_insn
;
6165 insn_with_same_reservs
!= NULL
;
6166 insn_with_same_reservs
6167 = insn_with_same_reservs
->next_same_reservs_insn
)
6168 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6169 curr_insn
= curr_insn
->next_equiv_class_insn
;
6171 while (curr_insn
!= first_insn
);
6172 equiv_classes_num
++;
6174 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6179 /* This page contains code for creating DFA(s) and calls functions
6183 /* The following value is used to prevent floating point overflow for
6184 estimating an automaton bound. The value should be less DBL_MAX on
6185 the host machine. We use here approximate minimum of maximal
6186 double floating point value required by ANSI C standard. It
6187 will work for non ANSI sun compiler too. */
6189 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6191 /* The function estimate size of the single DFA used by PHR (pipeline
6192 hazards recognizer). */
6194 estimate_one_automaton_bound ()
6197 double one_automaton_estimation_bound
;
6201 one_automaton_estimation_bound
= 1.0;
6202 for (i
= 0; i
< description
->decls_num
; i
++)
6204 decl
= description
->decls
[i
];
6205 if (decl
->mode
== dm_unit
)
6207 root_value
= exp (log (decl
->decl
.unit
.max_occ_cycle_num
+ 1.0)
6209 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6210 > one_automaton_estimation_bound
)
6211 one_automaton_estimation_bound
*= root_value
;
6214 return one_automaton_estimation_bound
;
6217 /* The function compares unit declarations acoording to their maximal
6218 cycle in reservations. */
6220 compare_max_occ_cycle_nums (unit_decl_1
, unit_decl_2
)
6221 const void *unit_decl_1
;
6222 const void *unit_decl_2
;
6224 if (((*(decl_t
*) unit_decl_1
)->decl
.unit
.max_occ_cycle_num
)
6225 < ((*(decl_t
*) unit_decl_2
)->decl
.unit
.max_occ_cycle_num
))
6227 else if (((*(decl_t
*) unit_decl_1
)->decl
.unit
.max_occ_cycle_num
)
6228 == ((*(decl_t
*) unit_decl_2
)->decl
.unit
.max_occ_cycle_num
))
6234 /* The function makes heuristic assigning automata to units. Actually
6235 efficacy of the algorithm has been checked yet??? */
6237 units_to_automata_heuristic_distr ()
6239 double estimation_bound
;
6241 decl_t
*unit_decl_ptr
;
6245 vla_ptr_t unit_decls
;
6248 if (description
->units_num
== 0)
6250 estimation_bound
= estimate_one_automaton_bound ();
6251 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6252 for (i
= 0; i
< description
->decls_num
; i
++)
6254 decl
= description
->decls
[i
];
6255 if (decl
->mode
== dm_unit
)
6256 VLA_PTR_ADD (unit_decls
, decl
);
6258 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6259 sizeof (decl_t
), compare_max_occ_cycle_nums
);
6261 unit_decl_ptr
= VLA_PTR_BEGIN (unit_decls
);
6262 bound_value
= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6263 (*unit_decl_ptr
)->decl
.unit
.corresponding_automaton_num
= automaton_num
;
6264 for (unit_decl_ptr
++;
6265 unit_decl_ptr
<= (decl_t
*) VLA_PTR_LAST (unit_decls
);
6269 = ((decl_t
*) VLA_PTR_LAST (unit_decls
) - unit_decl_ptr
+ 1);
6270 if (automata_num
- automaton_num
- 1 > rest_units_num
)
6272 if (automaton_num
< automata_num
- 1
6273 && ((automata_num
- automaton_num
- 1 == rest_units_num
)
6276 / ((*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
)))))
6278 bound_value
= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6282 bound_value
*= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6283 (*unit_decl_ptr
)->decl
.unit
.corresponding_automaton_num
= automaton_num
;
6285 if (automaton_num
!= automata_num
- 1)
6287 VLA_PTR_DELETE (unit_decls
);
6290 /* The functions creates automaton insns for each automata. Automaton
6291 insn is simply insn for given automaton which makes reservation
6292 only of units of the automaton. */
6297 ainsn_t first_ainsn
;
6304 for (i
= 0; i
< description
->decls_num
; i
++)
6306 decl
= description
->decls
[i
];
6307 if (decl
->mode
== dm_insn_reserv
)
6309 curr_ainsn
= create_node (sizeof (struct ainsn
));
6310 curr_ainsn
->insn_reserv_decl
= &decl
->decl
.insn_reserv
;
6311 curr_ainsn
->important_p
= FALSE
;
6312 curr_ainsn
->next_ainsn
= NULL
;
6313 if (prev_ainsn
== NULL
)
6314 first_ainsn
= curr_ainsn
;
6316 prev_ainsn
->next_ainsn
= curr_ainsn
;
6317 prev_ainsn
= curr_ainsn
;
6323 /* The function assigns automata to units according to constructions
6324 `define_automaton' in the description. */
6326 units_to_automata_distr ()
6331 for (i
= 0; i
< description
->decls_num
; i
++)
6333 decl
= description
->decls
[i
];
6334 if (decl
->mode
== dm_unit
)
6336 if (decl
->decl
.unit
.automaton_decl
== NULL
6337 || (decl
->decl
.unit
.automaton_decl
->corresponding_automaton
6339 /* Distribute to the first automaton. */
6340 decl
->decl
.unit
.corresponding_automaton_num
= 0;
6342 decl
->decl
.unit
.corresponding_automaton_num
6343 = (decl
->decl
.unit
.automaton_decl
6344 ->corresponding_automaton
->automaton_order_num
);
6349 /* The function creates DFA(s) for fast pipeline hazards recognition
6350 after checking and simplifying IR of the description. */
6354 automaton_t curr_automaton
;
6355 automaton_t prev_automaton
;
6357 int curr_automaton_num
;
6360 if (automata_num
!= 0)
6362 units_to_automata_heuristic_distr ();
6363 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6364 curr_automaton_num
< automata_num
;
6365 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6367 curr_automaton
= create_node (sizeof (struct automaton
));
6368 curr_automaton
->ainsn_list
= create_ainsns ();
6369 curr_automaton
->corresponding_automaton_decl
= NULL
;
6370 curr_automaton
->next_automaton
= NULL
;
6371 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6372 if (prev_automaton
== NULL
)
6373 description
->first_automaton
= curr_automaton
;
6375 prev_automaton
->next_automaton
= curr_automaton
;
6380 curr_automaton_num
= 0;
6381 prev_automaton
= NULL
;
6382 for (i
= 0; i
< description
->decls_num
; i
++)
6384 decl
= description
->decls
[i
];
6385 if (decl
->mode
== dm_automaton
6386 && decl
->decl
.automaton
.automaton_is_used
)
6388 curr_automaton
= create_node (sizeof (struct automaton
));
6389 curr_automaton
->ainsn_list
= create_ainsns ();
6390 curr_automaton
->corresponding_automaton_decl
6391 = &decl
->decl
.automaton
;
6392 curr_automaton
->next_automaton
= NULL
;
6393 decl
->decl
.automaton
.corresponding_automaton
= curr_automaton
;
6394 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6395 if (prev_automaton
== NULL
)
6396 description
->first_automaton
= curr_automaton
;
6398 prev_automaton
->next_automaton
= curr_automaton
;
6399 curr_automaton_num
++;
6400 prev_automaton
= curr_automaton
;
6403 if (curr_automaton_num
== 0)
6405 curr_automaton
= create_node (sizeof (struct automaton
));
6406 curr_automaton
->ainsn_list
= create_ainsns ();
6407 curr_automaton
->corresponding_automaton_decl
= NULL
;
6408 curr_automaton
->next_automaton
= NULL
;
6409 description
->first_automaton
= curr_automaton
;
6411 units_to_automata_distr ();
6413 NDFA_time
= create_ticker ();
6414 ticker_off (&NDFA_time
);
6415 NDFA_to_DFA_time
= create_ticker ();
6416 ticker_off (&NDFA_to_DFA_time
);
6417 minimize_time
= create_ticker ();
6418 ticker_off (&minimize_time
);
6419 equiv_time
= create_ticker ();
6420 ticker_off (&equiv_time
);
6421 for (curr_automaton
= description
->first_automaton
;
6422 curr_automaton
!= NULL
;
6423 curr_automaton
= curr_automaton
->next_automaton
)
6425 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6426 fprintf (stderr
, "Create anonymous automaton ...");
6428 fprintf (stderr
, "Create automaton `%s'...",
6429 curr_automaton
->corresponding_automaton_decl
->name
);
6430 create_alt_states (curr_automaton
);
6431 form_ainsn_with_same_reservs (curr_automaton
);
6432 build_automaton (curr_automaton
);
6433 enumerate_states (curr_automaton
);
6434 ticker_on (&equiv_time
);
6435 set_insn_equiv_classes (curr_automaton
);
6436 ticker_off (&equiv_time
);
6437 fprintf (stderr
, "done\n");
6443 /* This page contains code for forming string representation of
6444 regexp. The representation is formed on IR obstack. So you should
6445 not work with IR obstack between regexp_representation and
6446 finish_regexp_representation calls. */
6448 /* This recursive function forms string representation of regexp
6449 (without tailing '\0'). */
6451 form_regexp (regexp
)
6456 if (regexp
->mode
== rm_unit
|| regexp
->mode
== rm_reserv
)
6458 const char *name
= (regexp
->mode
== rm_unit
6459 ? regexp
->regexp
.unit
.name
6460 : regexp
->regexp
.reserv
.name
);
6462 obstack_grow (&irp
, name
, strlen (name
));
6464 else if (regexp
->mode
== rm_sequence
)
6465 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
6468 obstack_1grow (&irp
, ',');
6469 form_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
6471 else if (regexp
->mode
== rm_allof
)
6473 obstack_1grow (&irp
, '(');
6474 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
6477 obstack_1grow (&irp
, '+');
6478 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_sequence
6479 || regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
6480 obstack_1grow (&irp
, '(');
6481 form_regexp (regexp
->regexp
.allof
.regexps
[i
]);
6482 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_sequence
6483 || regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
6484 obstack_1grow (&irp
, ')');
6486 obstack_1grow (&irp
, ')');
6488 else if (regexp
->mode
== rm_oneof
)
6489 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
6492 obstack_1grow (&irp
, '|');
6493 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_sequence
)
6494 obstack_1grow (&irp
, '(');
6495 form_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
6496 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_sequence
)
6497 obstack_1grow (&irp
, ')');
6499 else if (regexp
->mode
== rm_repeat
)
6503 if (regexp
->regexp
.repeat
.regexp
->mode
== rm_sequence
6504 || regexp
->regexp
.repeat
.regexp
->mode
== rm_allof
6505 || regexp
->regexp
.repeat
.regexp
->mode
== rm_oneof
)
6506 obstack_1grow (&irp
, '(');
6507 form_regexp (regexp
->regexp
.repeat
.regexp
);
6508 if (regexp
->regexp
.repeat
.regexp
->mode
== rm_sequence
6509 || regexp
->regexp
.repeat
.regexp
->mode
== rm_allof
6510 || regexp
->regexp
.repeat
.regexp
->mode
== rm_oneof
)
6511 obstack_1grow (&irp
, ')');
6512 sprintf (digits
, "*%d", regexp
->regexp
.repeat
.repeat_num
);
6513 obstack_grow (&irp
, digits
, strlen (digits
));
6515 else if (regexp
->mode
== rm_nothing
)
6516 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
6521 /* The function returns string representation of REGEXP on IR
6524 regexp_representation (regexp
)
6527 form_regexp (regexp
);
6528 obstack_1grow (&irp
, '\0');
6529 return obstack_base (&irp
);
6532 /* The function frees memory allocated for last formed string
6533 representation of regexp. */
6535 finish_regexp_representation ()
6537 int length
= obstack_object_size (&irp
);
6539 obstack_blank_fast (&irp
, -length
);
6544 /* This page contains code for output PHR (pipeline hazards recognizer). */
6546 /* The function outputs minimal C type which is sufficient for
6547 representation numbers in range min_range_value and
6548 max_range_value. Because host machine and build machine may be
6549 different, we use here minimal values required by ANSI C standard
6550 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6554 output_range_type (f
, min_range_value
, max_range_value
)
6556 long int min_range_value
;
6557 long int max_range_value
;
6559 if (min_range_value
>= 0 && max_range_value
<= 255)
6560 fprintf (f
, "unsigned char");
6561 else if (min_range_value
>= -127 && max_range_value
<= 127)
6562 fprintf (f
, "signed char");
6563 else if (min_range_value
>= 0 && max_range_value
<= 65535)
6564 fprintf (f
, "unsigned short");
6565 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
6566 fprintf (f
, "short");
6571 /* The following macro value is used as value of member
6572 `longest_path_length' of state when we are processing path and the
6573 state on the path. */
6575 #define ON_THE_PATH -2
6577 /* The following recursive function searches for the length of the
6578 longest path starting from STATE which does not contain cycles and
6579 `cycle advance' arcs. */
6582 longest_path_length (state
)
6588 if (state
->longest_path_length
== ON_THE_PATH
)
6589 /* We don't expect the path cycle here. Our graph may contain
6590 only cycles with one state on the path not containing `cycle
6591 advance' arcs -- see comment below. */
6593 else if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
6594 /* We alreday visited the state. */
6595 return state
->longest_path_length
;
6598 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6599 /* Ignore cycles containing one state and `cycle advance' arcs. */
6600 if (arc
->to_state
!= state
6601 && (arc
->insn
->insn_reserv_decl
6602 != &advance_cycle_insn_decl
->decl
.insn_reserv
))
6604 length
= longest_path_length (arc
->to_state
);
6605 if (length
> result
)
6608 state
->longest_path_length
= result
+ 1;
6612 /* The following variable value is value of the corresponding global
6613 variable in the automaton based pipeline interface. */
6615 static int max_dfa_issue_rate
;
6617 /* The following function processes the longest path length staring
6618 from STATE to find MAX_DFA_ISSUE_RATE. */
6621 process_state_longest_path_length (state
)
6626 value
= longest_path_length (state
);
6627 if (value
> max_dfa_issue_rate
)
6628 max_dfa_issue_rate
= value
;
6631 /* The following nacro value is name of the corresponding global
6632 variable in the automaton based pipeline interface. */
6634 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6636 /* The following function calculates value of the the corresponding
6637 global variable and outputs its declaration. */
6640 output_dfa_max_issue_rate ()
6642 automaton_t automaton
;
6644 if (UNDEFINED_LONGEST_PATH_LENGTH
== ON_THE_PATH
|| ON_THE_PATH
>= 0)
6646 max_dfa_issue_rate
= 0;
6647 for (automaton
= description
->first_automaton
;
6649 automaton
= automaton
->next_automaton
)
6650 pass_states (automaton
, process_state_longest_path_length
);
6651 fprintf (output_file
, "\nint %s = %d;\n",
6652 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
6655 /* The function outputs all initialization values of VECT with length
6658 output_vect (vect
, vect_length
)
6665 if (vect_length
== 0)
6666 fprintf (output_file
,
6667 "0 /* This is dummy el because the vect is empty */");
6672 fprintf (output_file
, "%5ld", (long) *vect
);
6674 if (els_on_line
== 10)
6677 fprintf (output_file
, ",\n");
6679 else if (vect_length
!= 0)
6680 fprintf (output_file
, ", ");
6684 while (vect_length
!= 0);
6688 /* The following is name of the structure which represents DFA(s) for
6690 #define CHIP_NAME "DFA_chip"
6692 /* The following is name of member which represents state of a DFA for
6695 output_chip_member_name (f
, automaton
)
6697 automaton_t automaton
;
6699 if (automaton
->corresponding_automaton_decl
== NULL
)
6700 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
6702 fprintf (f
, "%s_automaton_state",
6703 automaton
->corresponding_automaton_decl
->name
);
6706 /* The following is name of temporary variable which stores state of a
6709 output_temp_chip_member_name (f
, automaton
)
6711 automaton_t automaton
;
6714 output_chip_member_name (f
, automaton
);
6717 /* This is name of macro value which is code of pseudo_insn
6718 representing advancing cpu cycle. Its value is used as internal
6719 code unknown insn. */
6720 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6722 /* Output name of translate vector for given automaton. */
6724 output_translate_vect_name (f
, automaton
)
6726 automaton_t automaton
;
6728 if (automaton
->corresponding_automaton_decl
== NULL
)
6729 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
6731 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
6734 /* Output name for simple transition table representation. */
6736 output_trans_full_vect_name (f
, automaton
)
6738 automaton_t automaton
;
6740 if (automaton
->corresponding_automaton_decl
== NULL
)
6741 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6743 fprintf (f
, "%s_transitions",
6744 automaton
->corresponding_automaton_decl
->name
);
6747 /* Output name of comb vector of the transition table for given
6750 output_trans_comb_vect_name (f
, automaton
)
6752 automaton_t automaton
;
6754 if (automaton
->corresponding_automaton_decl
== NULL
)
6755 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6757 fprintf (f
, "%s_transitions",
6758 automaton
->corresponding_automaton_decl
->name
);
6761 /* Output name of check vector of the transition table for given
6764 output_trans_check_vect_name (f
, automaton
)
6766 automaton_t automaton
;
6768 if (automaton
->corresponding_automaton_decl
== NULL
)
6769 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
6771 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
6774 /* Output name of base vector of the transition table for given
6777 output_trans_base_vect_name (f
, automaton
)
6779 automaton_t automaton
;
6781 if (automaton
->corresponding_automaton_decl
== NULL
)
6782 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
6784 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
6787 /* Output name for simple alternatives number representation. */
6789 output_state_alts_full_vect_name (f
, automaton
)
6791 automaton_t automaton
;
6793 if (automaton
->corresponding_automaton_decl
== NULL
)
6794 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
6796 fprintf (f
, "%s_state_alts",
6797 automaton
->corresponding_automaton_decl
->name
);
6800 /* Output name of comb vector of the alternatives number table for given
6803 output_state_alts_comb_vect_name (f
, automaton
)
6805 automaton_t automaton
;
6807 if (automaton
->corresponding_automaton_decl
== NULL
)
6808 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
6810 fprintf (f
, "%s_state_alts",
6811 automaton
->corresponding_automaton_decl
->name
);
6814 /* Output name of check vector of the alternatives number table for given
6817 output_state_alts_check_vect_name (f
, automaton
)
6819 automaton_t automaton
;
6821 if (automaton
->corresponding_automaton_decl
== NULL
)
6822 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
6824 fprintf (f
, "%s_check_state_alts",
6825 automaton
->corresponding_automaton_decl
->name
);
6828 /* Output name of base vector of the alternatives number table for given
6831 output_state_alts_base_vect_name (f
, automaton
)
6833 automaton_t automaton
;
6835 if (automaton
->corresponding_automaton_decl
== NULL
)
6836 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
6838 fprintf (f
, "%s_base_state_alts",
6839 automaton
->corresponding_automaton_decl
->name
);
6842 /* Output name of simple min issue delay table representation. */
6844 output_min_issue_delay_vect_name (f
, automaton
)
6846 automaton_t automaton
;
6848 if (automaton
->corresponding_automaton_decl
== NULL
)
6849 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
6851 fprintf (f
, "%s_min_issue_delay",
6852 automaton
->corresponding_automaton_decl
->name
);
6855 /* Output name of deadlock vector for given automaton. */
6857 output_dead_lock_vect_name (f
, automaton
)
6859 automaton_t automaton
;
6861 if (automaton
->corresponding_automaton_decl
== NULL
)
6862 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
6864 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
6867 /* Output name of reserved units table for AUTOMATON into file F. */
6869 output_reserved_units_table_name (f
, automaton
)
6871 automaton_t automaton
;
6873 if (automaton
->corresponding_automaton_decl
== NULL
)
6874 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
6876 fprintf (f
, "%s_reserved_units",
6877 automaton
->corresponding_automaton_decl
->name
);
6880 /* Name of the PHR interface macro. */
6881 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6883 /* Name of the PHR interface macro. */
6884 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6886 /* Names of an internal functions: */
6887 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6889 /* This is external type of DFA(s) state. */
6890 #define STATE_TYPE_NAME "state_t"
6892 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6894 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6896 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6898 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6900 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6902 /* Name of cache of insn dfa codes. */
6903 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6905 /* Name of length of cache of insn dfa codes. */
6906 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6908 /* Names of the PHR interface functions: */
6909 #define SIZE_FUNC_NAME "state_size"
6911 #define TRANSITION_FUNC_NAME "state_transition"
6913 #define STATE_ALTS_FUNC_NAME "state_alts"
6915 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6917 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6919 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6921 #define RESET_FUNC_NAME "state_reset"
6923 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6925 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6927 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6929 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6931 #define DFA_START_FUNC_NAME "dfa_start"
6933 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6935 /* Names of parameters of the PHR interface functions. */
6936 #define STATE_NAME "state"
6938 #define INSN_PARAMETER_NAME "insn"
6940 #define INSN2_PARAMETER_NAME "insn2"
6942 #define CHIP_PARAMETER_NAME "chip"
6944 #define FILE_PARAMETER_NAME "f"
6946 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6948 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6950 /* Names of the variables whose values are internal insn code of rtx
6952 #define INTERNAL_INSN_CODE_NAME "insn_code"
6954 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6956 /* Names of temporary variables in some functions. */
6957 #define TEMPORARY_VARIABLE_NAME "temp"
6959 #define I_VARIABLE_NAME "i"
6961 /* Name of result variable in some functions. */
6962 #define RESULT_VARIABLE_NAME "res"
6964 /* Name of function (attribute) to translate insn into number of insn
6965 alternatives reservation. */
6966 #define INSN_ALTS_FUNC_NAME "insn_alts"
6968 /* Name of function (attribute) to translate insn into internal insn
6970 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6972 /* Name of function (attribute) to translate insn into internal insn
6973 code with caching. */
6974 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6976 /* Name of function (attribute) to translate insn into internal insn
6978 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6980 /* Name of function (attribute) to translate insn into internal insn
6982 #define BYPASS_P_FUNC_NAME "bypass_p"
6984 /* Output C type which is used for representation of codes of states
6987 output_state_member_type (f
, automaton
)
6989 automaton_t automaton
;
6991 output_range_type (f
, 0, automaton
->achieved_states_num
);
6994 /* Output definition of the structure representing current DFA(s)
6997 output_chip_definitions ()
6999 automaton_t automaton
;
7001 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
7002 for (automaton
= description
->first_automaton
;
7004 automaton
= automaton
->next_automaton
)
7006 fprintf (output_file
, " ");
7007 output_state_member_type (output_file
, automaton
);
7008 fprintf (output_file
, " ");
7009 output_chip_member_name (output_file
, automaton
);
7010 fprintf (output_file
, ";\n");
7012 fprintf (output_file
, "};\n\n");
7014 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
7019 /* The function outputs translate vector of internal insn code into
7020 insn equivalence class number. The equivalence class number is
7021 used to access to table and vectors reprewsenting DFA(s). */
7023 output_translate_vect (automaton
)
7024 automaton_t automaton
;
7028 vla_hwint_t translate_vect
;
7030 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
7031 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
7032 for (insn_value
= 0; insn_value
<= description
->insns_num
; insn_value
++)
7033 /* Undefined value */
7034 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
7035 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7036 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
7037 = ainsn
->insn_equiv_class_num
;
7038 fprintf (output_file
,
7039 "/* Vector translating external insn codes to internal ones.*/\n");
7040 fprintf (output_file
, "static const ");
7041 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
7042 fprintf (output_file
, " ");
7043 output_translate_vect_name (output_file
, automaton
);
7044 fprintf (output_file
, "[] = {\n");
7045 output_vect (VLA_HWINT_BEGIN (translate_vect
),
7046 VLA_HWINT_LENGTH (translate_vect
));
7047 fprintf (output_file
, "};\n\n");
7048 VLA_HWINT_DELETE (translate_vect
);
7051 /* The value in a table state x ainsn -> something which represents
7053 static int undefined_vect_el_value
;
7055 /* The following function returns nonzero value if the best
7056 representation of the table is comb vector. */
7059 state_ainsn_table_t tab
;
7061 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
7062 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
7065 /* The following function creates new table for AUTOMATON. */
7066 static state_ainsn_table_t
7067 create_state_ainsn_table (automaton
)
7068 automaton_t automaton
;
7070 state_ainsn_table_t tab
;
7071 int full_vect_length
;
7074 tab
= create_node (sizeof (struct state_ainsn_table
));
7075 tab
->automaton
= automaton
;
7076 VLA_HWINT_CREATE (tab
->comb_vect
, 10000, "comb vector");
7077 VLA_HWINT_CREATE (tab
->check_vect
, 10000, "check vector");
7078 VLA_HWINT_CREATE (tab
->base_vect
, 1000, "base vector");
7079 VLA_HWINT_EXPAND (tab
->base_vect
, automaton
->achieved_states_num
);
7080 VLA_HWINT_CREATE (tab
->full_vect
, 10000, "full vector");
7081 full_vect_length
= (automaton
->insn_equiv_classes_num
7082 * automaton
->achieved_states_num
);
7083 VLA_HWINT_EXPAND (tab
->full_vect
, full_vect_length
);
7084 for (i
= 0; i
< full_vect_length
; i
++)
7085 VLA_HWINT (tab
->full_vect
, i
) = undefined_vect_el_value
;
7086 tab
->min_base_vect_el_value
= 0;
7087 tab
->max_base_vect_el_value
= 0;
7088 tab
->min_comb_vect_el_value
= 0;
7089 tab
->max_comb_vect_el_value
= 0;
7093 /* The following function outputs the best C representation of the
7094 table TAB of given TABLE_NAME. */
7096 output_state_ainsn_table (tab
, table_name
, output_full_vect_name_func
,
7097 output_comb_vect_name_func
,
7098 output_check_vect_name_func
,
7099 output_base_vect_name_func
)
7100 state_ainsn_table_t tab
;
7102 void (*output_full_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7103 void (*output_comb_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7104 void (*output_check_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7105 void (*output_base_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7107 if (!comb_vect_p (tab
))
7109 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7110 fprintf (output_file
, "static const ");
7111 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7112 tab
->max_comb_vect_el_value
);
7113 fprintf (output_file
, " ");
7114 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7115 fprintf (output_file
, "[] = {\n");
7116 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7117 VLA_HWINT_LENGTH (tab
->full_vect
));
7118 fprintf (output_file
, "};\n\n");
7122 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7123 fprintf (output_file
, "static const ");
7124 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7125 tab
->max_comb_vect_el_value
);
7126 fprintf (output_file
, " ");
7127 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7128 fprintf (output_file
, "[] = {\n");
7129 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7130 VLA_HWINT_LENGTH (tab
->comb_vect
));
7131 fprintf (output_file
, "};\n\n");
7132 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7133 fprintf (output_file
, "static const ");
7134 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7135 fprintf (output_file
, " ");
7136 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7137 fprintf (output_file
, "[] = {\n");
7138 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7139 VLA_HWINT_LENGTH (tab
->check_vect
));
7140 fprintf (output_file
, "};\n\n");
7141 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7142 fprintf (output_file
, "static const ");
7143 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7144 tab
->max_base_vect_el_value
);
7145 fprintf (output_file
, " ");
7146 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7147 fprintf (output_file
, "[] = {\n");
7148 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7149 VLA_HWINT_LENGTH (tab
->base_vect
));
7150 fprintf (output_file
, "};\n\n");
7154 /* The following function adds vector with length VECT_LENGTH and
7155 elements pointed by VECT to table TAB as its line with number
7158 add_vect (tab
, vect_num
, vect
, vect_length
)
7159 state_ainsn_table_t tab
;
7164 int real_vect_length
;
7165 vect_el_t
*comb_vect_start
;
7166 vect_el_t
*check_vect_start
;
7167 int comb_vect_index
;
7168 int comb_vect_els_num
;
7170 int first_unempty_vect_index
;
7171 int additional_els_num
;
7176 if (vect_length
== 0)
7178 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7179 if (vect
[vect_length
- 1] == undefined_vect_el_value
)
7181 /* Form full vector in the table: */
7182 for (i
= 0; i
< vect_length
; i
++)
7183 VLA_HWINT (tab
->full_vect
,
7184 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
7186 /* Form comb vector in the table: */
7187 if (VLA_HWINT_LENGTH (tab
->comb_vect
) != VLA_HWINT_LENGTH (tab
->check_vect
))
7189 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7190 comb_vect_els_num
= VLA_HWINT_LENGTH (tab
->comb_vect
);
7191 for (first_unempty_vect_index
= 0;
7192 first_unempty_vect_index
< vect_length
;
7193 first_unempty_vect_index
++)
7194 if (vect
[first_unempty_vect_index
] != undefined_vect_el_value
)
7196 /* Search for the place in comb vect for the inserted vect. */
7197 for (comb_vect_index
= 0;
7198 comb_vect_index
< comb_vect_els_num
;
7201 for (vect_index
= first_unempty_vect_index
;
7202 vect_index
< vect_length
7203 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7205 if (vect
[vect_index
] != undefined_vect_el_value
7206 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7207 != undefined_vect_el_value
))
7209 if (vect_index
>= vect_length
7210 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7213 /* Slot was found. */
7214 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7215 if (additional_els_num
< 0)
7216 additional_els_num
= 0;
7217 /* Expand comb and check vectors. */
7218 vect_el
= undefined_vect_el_value
;
7219 no_state_value
= tab
->automaton
->achieved_states_num
;
7220 while (additional_els_num
> 0)
7222 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7223 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7224 additional_els_num
--;
7226 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7227 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7228 if (VLA_HWINT_LENGTH (tab
->comb_vect
)
7229 < (size_t) (comb_vect_index
+ real_vect_length
))
7231 /* Fill comb and check vectors. */
7232 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7233 if (vect
[vect_index
] != undefined_vect_el_value
)
7235 if (comb_vect_start
[comb_vect_index
+ vect_index
]
7236 != undefined_vect_el_value
)
7238 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7239 if (vect
[vect_index
] < 0)
7241 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7242 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7243 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7244 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7245 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7247 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7248 tab
->max_base_vect_el_value
= comb_vect_index
;
7249 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7250 tab
->min_base_vect_el_value
= comb_vect_index
;
7251 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7254 /* Return number of out arcs of STATE. */
7256 out_state_arcs_num (state
)
7263 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7265 if (arc
->insn
== NULL
)
7267 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7273 /* Compare number of possible transitions from the states. */
7275 compare_transition_els_num (state_ptr_1
, state_ptr_2
)
7276 const void *state_ptr_1
;
7277 const void *state_ptr_2
;
7279 int transition_els_num_1
;
7280 int transition_els_num_2
;
7282 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7283 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7284 if (transition_els_num_1
< transition_els_num_2
)
7286 else if (transition_els_num_1
== transition_els_num_2
)
7292 /* The function adds element EL_VALUE to vector VECT for a table state
7295 add_vect_el (vect
, ainsn
, el_value
)
7300 int equiv_class_num
;
7305 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7306 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7307 vect_index
<= equiv_class_num
;
7309 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7310 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7313 /* This is for forming vector of states of an automaton. */
7314 static vla_ptr_t output_states_vect
;
7316 /* The function is called by function pass_states. The function adds
7317 STATE to `output_states_vect'. */
7319 add_states_vect_el (state
)
7322 VLA_PTR_ADD (output_states_vect
, state
);
7325 /* Form and output vectors (comb, check, base or full vector)
7326 representing transition table of AUTOMATON. */
7328 output_trans_table (automaton
)
7329 automaton_t automaton
;
7333 vla_hwint_t transition_vect
;
7335 undefined_vect_el_value
= automaton
->achieved_states_num
;
7336 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7337 /* Create vect of pointers to states ordered by num of transitions
7338 from the state (state with the maximum num is the first). */
7339 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7340 pass_states (automaton
, add_states_vect_el
);
7341 qsort (VLA_PTR_BEGIN (output_states_vect
),
7342 VLA_PTR_LENGTH (output_states_vect
),
7343 sizeof (state_t
), compare_transition_els_num
);
7344 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7345 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7346 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7349 VLA_HWINT_NULLIFY (transition_vect
);
7350 for (arc
= first_out_arc (*state_ptr
);
7352 arc
= next_out_arc (arc
))
7354 if (arc
->insn
== NULL
)
7356 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7357 add_vect_el (&transition_vect
, arc
->insn
,
7358 arc
->to_state
->order_state_num
);
7360 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7361 VLA_HWINT_BEGIN (transition_vect
),
7362 VLA_HWINT_LENGTH (transition_vect
));
7364 output_state_ainsn_table
7365 (automaton
->trans_table
, (char *) "state transitions",
7366 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7367 output_trans_check_vect_name
, output_trans_base_vect_name
);
7368 VLA_PTR_DELETE (output_states_vect
);
7369 VLA_HWINT_DELETE (transition_vect
);
7372 /* Form and output vectors (comb, check, base or simple vect)
7373 representing alts number table of AUTOMATON. The table is state x
7374 ainsn -> number of possible alternative reservations by the
7377 output_state_alts_table (automaton
)
7378 automaton_t automaton
;
7382 vla_hwint_t state_alts_vect
;
7384 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7385 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7386 /* Create vect of pointers to states ordered by num of transitions
7387 from the state (state with the maximum num is the first). */
7388 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7389 pass_states (automaton
, add_states_vect_el
);
7390 qsort (VLA_PTR_BEGIN (output_states_vect
),
7391 VLA_PTR_LENGTH (output_states_vect
),
7392 sizeof (state_t
), compare_transition_els_num
);
7393 /* Create base, comb, and check vectors. */
7394 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7395 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7396 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7399 VLA_HWINT_NULLIFY (state_alts_vect
);
7400 for (arc
= first_out_arc (*state_ptr
);
7402 arc
= next_out_arc (arc
))
7404 if (arc
->insn
== NULL
)
7406 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7407 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7409 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7410 VLA_HWINT_BEGIN (state_alts_vect
),
7411 VLA_HWINT_LENGTH (state_alts_vect
));
7413 output_state_ainsn_table
7414 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7415 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7416 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7417 VLA_PTR_DELETE (output_states_vect
);
7418 VLA_HWINT_DELETE (state_alts_vect
);
7421 /* The current number of passing states to find minimal issue delay
7422 value for an ainsn and state. */
7423 static int curr_state_pass_num
;
7426 /* This recursive function passes states to find minimal issue delay
7427 value for AINSN. The state being visited is STATE. The function
7428 returns minimal issue delay value for AINSN in STATE or -1 if we
7429 enter into a loop. */
7431 min_issue_delay_pass_states (state
, ainsn
)
7436 int min_insn_issue_delay
, insn_issue_delay
;
7438 if (state
->state_pass_num
== curr_state_pass_num
7439 || state
->min_insn_issue_delay
!= -1)
7440 /* We've entered into a loop or already have the correct value for
7441 given state and ainsn. */
7442 return state
->min_insn_issue_delay
;
7443 state
->state_pass_num
= curr_state_pass_num
;
7444 min_insn_issue_delay
= -1;
7445 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7446 if (arc
->insn
== ainsn
)
7448 min_insn_issue_delay
= 0;
7453 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7454 if (insn_issue_delay
!= -1)
7456 if (arc
->insn
->insn_reserv_decl
7457 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
7459 if (min_insn_issue_delay
== -1
7460 || min_insn_issue_delay
> insn_issue_delay
)
7462 min_insn_issue_delay
= insn_issue_delay
;
7463 if (insn_issue_delay
== 0)
7468 return min_insn_issue_delay
;
7471 /* The function searches minimal issue delay value for AINSN in STATE.
7472 The function can return negative value if we can not issue AINSN. We
7473 will report about it later. */
7475 min_issue_delay (state
, ainsn
)
7479 curr_state_pass_num
++;
7480 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7481 return state
->min_insn_issue_delay
;
7484 /* The function initiates code for finding minimal issue delay values.
7485 It should be called only once. */
7487 initiate_min_issue_delay_pass_states ()
7489 curr_state_pass_num
= 0;
7492 /* Form and output vectors representing minimal issue delay table of
7493 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7496 output_min_issue_delay_table (automaton
)
7497 automaton_t automaton
;
7499 vla_hwint_t min_issue_delay_vect
;
7500 vla_hwint_t compressed_min_issue_delay_vect
;
7501 vect_el_t min_delay
;
7506 /* Create vect of pointers to states ordered by num of transitions
7507 from the state (state with the maximum num is the first). */
7508 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7509 pass_states (automaton
, add_states_vect_el
);
7510 VLA_HWINT_CREATE (min_issue_delay_vect
, 1500, "min issue delay vector");
7511 VLA_HWINT_EXPAND (min_issue_delay_vect
,
7512 VLA_HWINT_LENGTH (output_states_vect
)
7513 * automaton
->insn_equiv_classes_num
);
7515 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
7516 * automaton
->insn_equiv_classes_num
);
7518 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
7519 automaton
->max_min_delay
= 0;
7520 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7521 if (ainsn
->first_ainsn_with_given_equialence_num
)
7523 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7524 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7526 (*state_ptr
)->min_insn_issue_delay
= -1;
7527 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7528 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7531 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
7532 if (automaton
->max_min_delay
< min_delay
)
7533 automaton
->max_min_delay
= min_delay
;
7534 VLA_HWINT (min_issue_delay_vect
,
7535 (*state_ptr
)->order_state_num
7536 * automaton
->insn_equiv_classes_num
7537 + ainsn
->insn_equiv_class_num
) = min_delay
;
7540 fprintf (output_file
, "/* Vector of min issue delay of insns.*/\n");
7541 fprintf (output_file
, "static const ");
7542 output_range_type (output_file
, 0, automaton
->max_min_delay
);
7543 fprintf (output_file
, " ");
7544 output_min_issue_delay_vect_name (output_file
, automaton
);
7545 fprintf (output_file
, "[] = {\n");
7546 /* Compress the vector */
7547 if (automaton
->max_min_delay
< 2)
7548 automaton
->min_issue_delay_table_compression_factor
= 8;
7549 else if (automaton
->max_min_delay
< 4)
7550 automaton
->min_issue_delay_table_compression_factor
= 4;
7551 else if (automaton
->max_min_delay
< 16)
7552 automaton
->min_issue_delay_table_compression_factor
= 2;
7554 automaton
->min_issue_delay_table_compression_factor
= 1;
7555 VLA_HWINT_CREATE (compressed_min_issue_delay_vect
, 1500,
7556 "compressed min issue delay vector");
7557 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect
,
7558 (VLA_HWINT_LENGTH (min_issue_delay_vect
)
7559 + automaton
->min_issue_delay_table_compression_factor
7561 / automaton
->min_issue_delay_table_compression_factor
);
7563 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
7565 VLA_HWINT (compressed_min_issue_delay_vect
, i
) = 0;
7566 for (i
= 0; i
< (int) VLA_HWINT_LENGTH (min_issue_delay_vect
); i
++)
7567 VLA_HWINT (compressed_min_issue_delay_vect
,
7568 i
/ automaton
->min_issue_delay_table_compression_factor
)
7569 |= (VLA_HWINT (min_issue_delay_vect
, i
)
7570 << (8 - (i
% automaton
->min_issue_delay_table_compression_factor
7572 * (8 / automaton
->min_issue_delay_table_compression_factor
)));
7573 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect
),
7574 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
));
7575 fprintf (output_file
, "};\n\n");
7576 VLA_PTR_DELETE (output_states_vect
);
7577 VLA_HWINT_DELETE (min_issue_delay_vect
);
7578 VLA_HWINT_DELETE (compressed_min_issue_delay_vect
);
7582 /* Number of states which contains transition only by advancing cpu
7584 static int locked_states_num
;
7587 /* Form and output vector representing the locked states of
7590 output_dead_lock_vect (automaton
)
7591 automaton_t automaton
;
7595 vla_hwint_t dead_lock_vect
;
7597 /* Create vect of pointers to states ordered by num of
7598 transitions from the state (state with the maximum num is the
7600 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7601 pass_states (automaton
, add_states_vect_el
);
7602 VLA_HWINT_CREATE (dead_lock_vect
, 1500, "is dead locked vector");
7603 VLA_HWINT_EXPAND (dead_lock_vect
, VLA_HWINT_LENGTH (output_states_vect
));
7604 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7605 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7608 arc
= first_out_arc (*state_ptr
);
7611 VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
)
7612 = (next_out_arc (arc
) == NULL
7613 && (arc
->insn
->insn_reserv_decl
7614 == &advance_cycle_insn_decl
->decl
.insn_reserv
) ? 1 : 0);
7616 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
7617 locked_states_num
++;
7620 fprintf (output_file
, "/* Vector for locked state flags. */\n");
7621 fprintf (output_file
, "static const ");
7622 output_range_type (output_file
, 0, 1);
7623 fprintf (output_file
, " ");
7624 output_dead_lock_vect_name (output_file
, automaton
);
7625 fprintf (output_file
, "[] = {\n");
7626 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
7627 VLA_HWINT_LENGTH (dead_lock_vect
));
7628 fprintf (output_file
, "};\n\n");
7629 VLA_HWINT_DELETE (dead_lock_vect
);
7630 VLA_PTR_DELETE (output_states_vect
);
7633 /* Form and output vector representing reserved units of the states of
7636 output_reserved_units_table (automaton
)
7637 automaton_t automaton
;
7639 state_t
*curr_state_ptr
;
7640 vla_hwint_t reserved_units_table
;
7641 size_t state_byte_size
;
7644 /* Create vect of pointers to states. */
7645 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7646 pass_states (automaton
, add_states_vect_el
);
7647 /* Create vector. */
7648 VLA_HWINT_CREATE (reserved_units_table
, 1500, "reserved units vector");
7649 state_byte_size
= (description
->query_units_num
+ 7) / 8;
7650 VLA_HWINT_EXPAND (reserved_units_table
,
7651 VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7653 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7655 VLA_HWINT (reserved_units_table
, i
) = 0;
7656 for (curr_state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7657 curr_state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7660 for (i
= 0; i
< description
->units_num
; i
++)
7661 if (units_array
[i
]->query_p
)
7663 if (test_unit_reserv ((*curr_state_ptr
)->reservs
, 0, i
))
7664 VLA_HWINT (reserved_units_table
,
7665 (*curr_state_ptr
)->order_state_num
* state_byte_size
7666 + units_array
[i
]->query_num
/ 8)
7667 += (1 << (units_array
[i
]->query_num
% 8));
7670 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
7671 fprintf (output_file
, "static const ");
7672 output_range_type (output_file
, 0, 255);
7673 fprintf (output_file
, " ");
7674 output_reserved_units_table_name (output_file
, automaton
);
7675 fprintf (output_file
, "[] = {\n");
7676 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
7677 VLA_HWINT_LENGTH (reserved_units_table
));
7678 fprintf (output_file
, "};\n\n");
7679 VLA_HWINT_DELETE (reserved_units_table
);
7680 VLA_PTR_DELETE (output_states_vect
);
7683 /* The function outputs all tables representing DFA(s) used for fast
7684 pipeline hazards recognition. */
7688 automaton_t automaton
;
7691 locked_states_num
= 0;
7693 initiate_min_issue_delay_pass_states ();
7694 for (automaton
= description
->first_automaton
;
7696 automaton
= automaton
->next_automaton
)
7698 output_translate_vect (automaton
);
7699 output_trans_table (automaton
);
7700 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
7701 output_state_alts_table (automaton
);
7702 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7703 AUTOMATON_STATE_ALTS_MACRO_NAME
);
7704 output_min_issue_delay_table (automaton
);
7705 output_dead_lock_vect (automaton
);
7706 if (no_minimization_flag
)
7708 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
7709 output_reserved_units_table (automaton
);
7710 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7711 CPU_UNITS_QUERY_MACRO_NAME
);
7714 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
7715 advance_cycle_insn_decl
->decl
.insn_reserv
.insn_num
);
7718 /* The function outputs definition and value of PHR interface variable
7719 `max_insn_queue_index' */
7721 output_max_insn_queue_index_def ()
7725 for (i
= 0; (1 << i
) <= description
->max_insn_reserv_cycles
; i
++)
7729 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
7733 /* The function outputs switch cases for insn reseravtions using
7734 function *output_automata_list_code. */
7736 output_insn_code_cases (output_automata_list_code
)
7737 void (*output_automata_list_code
) (automata_list_el_t
);
7739 decl_t decl
, decl_2
;
7742 for (i
= 0; i
< description
->decls_num
; i
++)
7744 decl
= description
->decls
[i
];
7745 if (decl
->mode
== dm_insn_reserv
)
7746 decl
->decl
.insn_reserv
.processed_p
= FALSE
;
7748 for (i
= 0; i
< description
->decls_num
; i
++)
7750 decl
= description
->decls
[i
];
7751 if (decl
->mode
== dm_insn_reserv
&& !decl
->decl
.insn_reserv
.processed_p
)
7753 for (j
= i
; j
< description
->decls_num
; j
++)
7755 decl_2
= description
->decls
[j
];
7756 if (decl_2
->mode
== dm_insn_reserv
7757 && (decl_2
->decl
.insn_reserv
.important_automata_list
7758 == decl
->decl
.insn_reserv
.important_automata_list
))
7760 decl_2
->decl
.insn_reserv
.processed_p
= TRUE
;
7761 fprintf (output_file
, " case %d: /* %s */\n",
7762 decl_2
->decl
.insn_reserv
.insn_num
,
7763 decl_2
->decl
.insn_reserv
.name
);
7766 (*output_automata_list_code
)
7767 (decl
->decl
.insn_reserv
.important_automata_list
);
7773 /* The function outputs a code for evaluation of a minimal delay of
7774 issue of insns which have reservations in given AUTOMATA_LIST. */
7776 output_automata_list_min_issue_delay_code (automata_list
)
7777 automata_list_el_t automata_list
;
7779 automata_list_el_t el
;
7780 automaton_t automaton
;
7782 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7784 automaton
= el
->automaton
;
7785 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7786 output_min_issue_delay_vect_name (output_file
, automaton
);
7787 fprintf (output_file
,
7788 (automaton
->min_issue_delay_table_compression_factor
!= 1
7790 output_translate_vect_name (output_file
, automaton
);
7791 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
7792 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7793 output_chip_member_name (output_file
, automaton
);
7794 fprintf (output_file
, " * %d", automaton
->insn_equiv_classes_num
);
7795 if (automaton
->min_issue_delay_table_compression_factor
== 1)
7796 fprintf (output_file
, "];\n");
7799 fprintf (output_file
, ") / %d];\n",
7800 automaton
->min_issue_delay_table_compression_factor
);
7801 fprintf (output_file
, " %s = (%s >> (8 - (",
7802 TEMPORARY_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7803 output_translate_vect_name (output_file
, automaton
);
7805 (output_file
, " [%s] %% %d + 1) * %d)) & %d;\n",
7806 INTERNAL_INSN_CODE_NAME
,
7807 automaton
->min_issue_delay_table_compression_factor
,
7808 8 / automaton
->min_issue_delay_table_compression_factor
,
7809 (1 << (8 / automaton
->min_issue_delay_table_compression_factor
))
7812 if (el
== automata_list
)
7813 fprintf (output_file
, " %s = %s;\n",
7814 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7817 fprintf (output_file
, " if (%s > %s)\n",
7818 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
7819 fprintf (output_file
, " %s = %s;\n",
7820 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7823 fprintf (output_file
, " break;\n\n");
7826 /* Output function `internal_min_issue_delay'. */
7828 output_internal_min_issue_delay_func ()
7830 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
7831 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, CHIP_NAME
);
7832 fprintf (output_file
,
7833 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
7834 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7835 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
7836 CHIP_PARAMETER_NAME
);
7837 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n int %s;\n",
7838 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
7839 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
7840 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
7841 fprintf (output_file
,
7842 "\n default:\n %s = -1;\n break;\n }\n",
7843 RESULT_VARIABLE_NAME
);
7844 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
7845 fprintf (output_file
, "}\n\n");
7848 /* The function outputs a code changing state after issue of insns
7849 which have reservations in given AUTOMATA_LIST. */
7851 output_automata_list_transition_code (automata_list
)
7852 automata_list_el_t automata_list
;
7854 automata_list_el_t el
, next_el
;
7856 fprintf (output_file
, " {\n");
7857 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
7858 for (el
= automata_list
;; el
= next_el
)
7860 next_el
= el
->next_automata_list_el
;
7861 if (next_el
== NULL
)
7863 fprintf (output_file
, " ");
7864 output_state_member_type (output_file
, el
->automaton
);
7865 fprintf (output_file
, " ");
7866 output_temp_chip_member_name (output_file
, el
->automaton
);
7867 fprintf (output_file
, ";\n");
7869 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7870 if (comb_vect_p (el
->automaton
->trans_table
))
7872 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7873 output_trans_base_vect_name (output_file
, el
->automaton
);
7874 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
7875 output_chip_member_name (output_file
, el
->automaton
);
7876 fprintf (output_file
, "] + ");
7877 output_translate_vect_name (output_file
, el
->automaton
);
7878 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
7879 fprintf (output_file
, " if (");
7880 output_trans_check_vect_name (output_file
, el
->automaton
);
7881 fprintf (output_file
, " [%s] != %s->",
7882 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
7883 output_chip_member_name (output_file
, el
->automaton
);
7884 fprintf (output_file
, ")\n");
7885 fprintf (output_file
, " return %s (%s, %s);\n",
7886 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7887 CHIP_PARAMETER_NAME
);
7888 fprintf (output_file
, " else\n");
7889 fprintf (output_file
, " ");
7890 if (el
->next_automata_list_el
!= NULL
)
7891 output_temp_chip_member_name (output_file
, el
->automaton
);
7894 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7895 output_chip_member_name (output_file
, el
->automaton
);
7897 fprintf (output_file
, " = ");
7898 output_trans_comb_vect_name (output_file
, el
->automaton
);
7899 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
7903 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7904 output_trans_full_vect_name (output_file
, el
->automaton
);
7905 fprintf (output_file
, " [");
7906 output_translate_vect_name (output_file
, el
->automaton
);
7907 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
7908 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7909 output_chip_member_name (output_file
, el
->automaton
);
7910 fprintf (output_file
, " * %d];\n",
7911 el
->automaton
->insn_equiv_classes_num
);
7912 fprintf (output_file
, " if (%s >= %d)\n",
7913 TEMPORARY_VARIABLE_NAME
, el
->automaton
->achieved_states_num
);
7914 fprintf (output_file
, " return %s (%s, %s);\n",
7915 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7916 CHIP_PARAMETER_NAME
);
7917 fprintf (output_file
, " else\n ");
7918 if (el
->next_automata_list_el
!= NULL
)
7919 output_temp_chip_member_name (output_file
, el
->automaton
);
7922 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7923 output_chip_member_name (output_file
, el
->automaton
);
7925 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
7927 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
7928 for (el
= automata_list
;; el
= next_el
)
7930 next_el
= el
->next_automata_list_el
;
7931 if (next_el
== NULL
)
7933 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
7934 output_chip_member_name (output_file
, el
->automaton
);
7935 fprintf (output_file
, " = ");
7936 output_temp_chip_member_name (output_file
, el
->automaton
);
7937 fprintf (output_file
, ";\n");
7939 fprintf (output_file
, " return -1;\n");
7940 fprintf (output_file
, " }\n");
7943 /* Output function `internal_state_transition'. */
7945 output_internal_trans_func ()
7947 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
7948 INTERNAL_TRANSITION_FUNC_NAME
, CHIP_NAME
);
7949 fprintf (output_file
,
7950 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
7951 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7952 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
,
7953 CHIP_NAME
, CHIP_PARAMETER_NAME
);
7954 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME
);
7955 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
7956 output_insn_code_cases (output_automata_list_transition_code
);
7957 fprintf (output_file
, "\n default:\n return -1;\n }\n");
7958 fprintf (output_file
, "}\n\n");
7965 insn_code = dfa_insn_code (insn);
7966 if (insn_code > DFA__ADVANCE_CYCLE)
7970 insn_code = DFA__ADVANCE_CYCLE;
7972 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7973 code denotes CODE. */
7975 output_internal_insn_code_evaluation (insn_name
, insn_code_name
, code
)
7976 const char *insn_name
;
7977 const char *insn_code_name
;
7980 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
7981 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
7982 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
7983 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
7984 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
7985 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
7986 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
7990 /* The function outputs function `dfa_insn_code'. */
7992 output_dfa_insn_code_func ()
7994 fprintf (output_file
, "#ifdef __GNUC__\n__inline__\n#endif\n");
7995 fprintf (output_file
, "static int %s PARAMS ((rtx));\n",
7996 DFA_INSN_CODE_FUNC_NAME
);
7997 fprintf (output_file
, "static int\n%s (%s)\n\trtx %s;\n",
7998 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN_PARAMETER_NAME
);
7999 fprintf (output_file
, "{\n int %s;\n int %s;\n\n",
8000 INTERNAL_INSN_CODE_NAME
, TEMPORARY_VARIABLE_NAME
);
8001 fprintf (output_file
, " if (INSN_UID (%s) >= %s)\n {\n",
8002 INSN_PARAMETER_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8003 fprintf (output_file
, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
8004 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8005 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, INSN_PARAMETER_NAME
);
8006 fprintf (output_file
, " %s = xrealloc (%s, %s * sizeof (int));\n",
8007 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8008 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8009 fprintf (output_file
,
8010 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
8011 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8012 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8013 TEMPORARY_VARIABLE_NAME
);
8014 fprintf (output_file
, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
8015 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8016 INSN_PARAMETER_NAME
);
8017 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8018 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8019 fprintf (output_file
, " %s [INSN_UID (%s)] = %s;\n",
8020 DFA_INSN_CODES_VARIABLE_NAME
, INSN_PARAMETER_NAME
,
8021 INTERNAL_INSN_CODE_NAME
);
8022 fprintf (output_file
, " }\n return %s;\n}\n\n",
8023 INTERNAL_INSN_CODE_NAME
);
8026 /* The function outputs PHR interface function `state_transition'. */
8028 output_trans_func ()
8030 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8031 TRANSITION_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8032 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8033 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8034 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8035 INTERNAL_INSN_CODE_NAME
, -1);
8036 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8037 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8040 /* The function outputs a code for evaluation of alternative states
8041 number for insns which have reservations in given AUTOMATA_LIST. */
8043 output_automata_list_state_alts_code (automata_list
)
8044 automata_list_el_t automata_list
;
8046 automata_list_el_t el
;
8047 automaton_t automaton
;
8049 fprintf (output_file
, " {\n");
8050 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8051 if (comb_vect_p (el
->automaton
->state_alts_table
))
8053 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
8056 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8058 automaton
= el
->automaton
;
8059 if (comb_vect_p (automaton
->state_alts_table
))
8061 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8062 output_state_alts_base_vect_name (output_file
, automaton
);
8063 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8064 output_chip_member_name (output_file
, automaton
);
8065 fprintf (output_file
, "] + ");
8066 output_translate_vect_name (output_file
, automaton
);
8067 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8068 fprintf (output_file
, " if (");
8069 output_state_alts_check_vect_name (output_file
, automaton
);
8070 fprintf (output_file
, " [%s] != %s->",
8071 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8072 output_chip_member_name (output_file
, automaton
);
8073 fprintf (output_file
, ")\n");
8074 fprintf (output_file
, " return 0;\n");
8075 fprintf (output_file
, " else\n");
8076 fprintf (output_file
,
8077 (el
== automata_list
8078 ? " %s = " : " %s += "),
8079 RESULT_VARIABLE_NAME
);
8080 output_state_alts_comb_vect_name (output_file
, automaton
);
8081 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8085 fprintf (output_file
,
8086 (el
== automata_list
8087 ? "\n %s = " : " %s += "),
8088 RESULT_VARIABLE_NAME
);
8089 output_state_alts_full_vect_name (output_file
, automaton
);
8090 fprintf (output_file
, " [");
8091 output_translate_vect_name (output_file
, automaton
);
8092 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8093 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8094 output_chip_member_name (output_file
, automaton
);
8095 fprintf (output_file
, " * %d];\n",
8096 automaton
->insn_equiv_classes_num
);
8099 fprintf (output_file
, " break;\n }\n\n");
8102 /* Output function `internal_state_alts'. */
8104 output_internal_state_alts_func ()
8106 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8107 INTERNAL_STATE_ALTS_FUNC_NAME
, CHIP_NAME
);
8108 fprintf (output_file
,
8109 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8110 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8111 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8112 CHIP_PARAMETER_NAME
);
8113 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8114 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8115 output_insn_code_cases (output_automata_list_state_alts_code
);
8116 fprintf (output_file
,
8117 "\n default:\n %s = 0;\n break;\n }\n",
8118 RESULT_VARIABLE_NAME
);
8119 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8120 fprintf (output_file
, "}\n\n");
8123 /* The function outputs PHR interface function `state_alts'. */
8125 output_state_alts_func ()
8127 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8128 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8129 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8130 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8131 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8132 INTERNAL_INSN_CODE_NAME
, 0);
8133 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8134 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8137 /* Output function `min_issue_delay'. */
8139 output_min_issue_delay_func ()
8141 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8142 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8143 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8144 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8145 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8146 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8147 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8148 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8149 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8150 fprintf (output_file
, " }\n else\n %s = %s;\n",
8151 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8152 fprintf (output_file
, "\n return %s (%s, %s);\n",
8153 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8155 fprintf (output_file
, "}\n\n");
8158 /* Output function `internal_dead_lock'. */
8160 output_internal_dead_lock_func ()
8162 automaton_t automaton
;
8164 fprintf (output_file
, "static int %s PARAMS ((struct %s *));\n",
8165 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
);
8166 fprintf (output_file
, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8167 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_PARAMETER_NAME
, CHIP_NAME
,
8168 CHIP_PARAMETER_NAME
);
8169 fprintf (output_file
, "{\n");
8170 for (automaton
= description
->first_automaton
;
8172 automaton
= automaton
->next_automaton
)
8174 fprintf (output_file
, " if (");
8175 output_dead_lock_vect_name (output_file
, automaton
);
8176 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8177 output_chip_member_name (output_file
, automaton
);
8178 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8180 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8183 /* The function outputs PHR interface function `state_dead_lock_p'. */
8185 output_dead_lock_func ()
8187 fprintf (output_file
, "int\n%s (%s)\n\t%s %s;\n",
8188 DEAD_LOCK_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8189 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8190 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8193 /* Output function `internal_reset'. */
8195 output_internal_reset_func ()
8197 fprintf (output_file
, "static void %s PARAMS ((struct %s *));\n",
8198 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8199 fprintf (output_file
, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8200 INTERNAL_RESET_FUNC_NAME
, CHIP_PARAMETER_NAME
,
8201 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8202 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8203 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8206 /* The function outputs PHR interface function `state_size'. */
8210 fprintf (output_file
, "int\n%s ()\n", SIZE_FUNC_NAME
);
8211 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8214 /* The function outputs PHR interface function `state_reset'. */
8216 output_reset_func ()
8218 fprintf (output_file
, "void\n%s (%s)\n\t %s %s;\n",
8219 RESET_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8220 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8224 /* Output function `min_insn_conflict_delay'. */
8226 output_min_insn_conflict_delay_func ()
8228 fprintf (output_file
,
8229 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8230 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
,
8231 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8232 STATE_TYPE_NAME
, STATE_NAME
,
8233 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8234 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s;\n",
8235 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8236 INTERNAL_INSN2_CODE_NAME
);
8237 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8238 INTERNAL_INSN_CODE_NAME
, 0);
8239 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8240 INTERNAL_INSN2_CODE_NAME
, 0);
8241 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8242 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8243 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8244 fprintf (output_file
, " if (%s (%s, &%s) > 0)\n abort ();\n",
8245 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8246 fprintf (output_file
, " return %s (%s, &%s);\n",
8247 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8249 fprintf (output_file
, "}\n\n");
8252 /* Output function `internal_insn_latency'. */
8254 output_internal_insn_latency_func ()
8257 struct bypass_decl
*bypass
;
8260 fprintf (output_file
, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8261 INTERNAL_INSN_LATENCY_FUNC_NAME
);
8262 fprintf (output_file
, "static int\n%s (%s, %s, %s, %s)",
8263 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8264 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8265 INSN2_PARAMETER_NAME
);
8266 fprintf (output_file
, "\n\tint %s;\n\tint %s;\n",
8267 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8268 fprintf (output_file
,
8269 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8270 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8271 fprintf (output_file
, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8272 for (i
= 0; i
< description
->decls_num
; i
++)
8274 decl
= description
->decls
[i
];
8275 if (decl
->mode
== dm_insn_reserv
)
8277 fprintf (output_file
, " case %d:\n",
8278 decl
->decl
.insn_reserv
.insn_num
);
8279 if (decl
->decl
.insn_reserv
.bypass_list
== NULL
)
8280 fprintf (output_file
, " return (%s != %s ? %d : 0);\n",
8281 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8282 decl
->decl
.insn_reserv
.default_latency
);
8285 fprintf (output_file
, " switch (%s)\n {\n",
8286 INTERNAL_INSN2_CODE_NAME
);
8287 for (bypass
= decl
->decl
.insn_reserv
.bypass_list
;
8289 bypass
= bypass
->next
)
8291 fprintf (output_file
, " case %d:\n",
8292 bypass
->in_insn_reserv
->insn_num
);
8293 if (bypass
->bypass_guard_name
== NULL
)
8294 fprintf (output_file
, " return %d;\n",
8297 fprintf (output_file
,
8298 " return (%s (%s, %s) ? %d : %d);\n",
8299 bypass
->bypass_guard_name
, INSN_PARAMETER_NAME
,
8300 INSN2_PARAMETER_NAME
, bypass
->latency
,
8301 decl
->decl
.insn_reserv
.default_latency
);
8303 fprintf (output_file
, " default:\n");
8304 fprintf (output_file
,
8305 " return (%s != %s ? %d : 0);\n }\n",
8306 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8307 decl
->decl
.insn_reserv
.default_latency
);
8312 fprintf (output_file
, " default:\n return 0;\n }\n}\n\n");
8315 /* The function outputs PHR interface function `insn_latency'. */
8317 output_insn_latency_func ()
8319 fprintf (output_file
, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8320 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8321 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8322 fprintf (output_file
, "{\n int %s, %s;\n",
8323 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8324 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8325 INTERNAL_INSN_CODE_NAME
, 0);
8326 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8327 INTERNAL_INSN2_CODE_NAME
, 0);
8328 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8329 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8330 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8331 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8334 /* The function outputs PHR interface function `print_reservation'. */
8336 output_print_reservation_func ()
8341 fprintf (output_file
, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8342 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8343 INSN_PARAMETER_NAME
, FILE_PARAMETER_NAME
,
8344 INSN_PARAMETER_NAME
);
8345 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8346 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8347 fprintf (output_file
, " %s = %s (%s);\n",
8348 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8349 INSN_PARAMETER_NAME
);
8350 fprintf (output_file
, " if (%s > %s)\n",
8351 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8352 fprintf (output_file
, " {\n fprintf (%s, \"%s\");\n",
8353 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8354 fprintf (output_file
, " return;\n }\n");
8355 fprintf (output_file
, " }\n else\n");
8356 fprintf (output_file
,
8357 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8358 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8359 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8360 for (i
= 0; i
< description
->decls_num
; i
++)
8362 decl
= description
->decls
[i
];
8363 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8365 fprintf (output_file
,
8366 " case %d:\n", decl
->decl
.insn_reserv
.insn_num
);
8367 fprintf (output_file
,
8368 " fprintf (%s, \"%s\");\n break;\n",
8369 FILE_PARAMETER_NAME
,
8370 regexp_representation (decl
->decl
.insn_reserv
.regexp
));
8371 finish_regexp_representation ();
8374 fprintf (output_file
, " default:\n fprintf (%s, \"%s\");\n }\n",
8375 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8376 fprintf (output_file
, "}\n\n");
8379 /* The following function is used to sort unit declaration by their
8382 units_cmp (unit1
, unit2
)
8383 const void *unit1
, *unit2
;
8385 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8386 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8388 return strcmp (u1
->name
, u2
->name
);
8391 /* The following macro value is name of struct containing unit name
8393 #define NAME_CODE_STRUCT_NAME "name_code"
8395 /* The following macro value is name of table of struct name_code. */
8396 #define NAME_CODE_TABLE_NAME "name_code_table"
8398 /* The following macro values are member names for struct name_code. */
8399 #define NAME_MEMBER_NAME "name"
8400 #define CODE_MEMBER_NAME "code"
8402 /* The following macro values are local variable names for function
8403 `get_cpu_unit_code'. */
8404 #define CMP_VARIABLE_NAME "cmp"
8405 #define LOW_VARIABLE_NAME "l"
8406 #define MIDDLE_VARIABLE_NAME "m"
8407 #define HIGH_VARIABLE_NAME "h"
8409 /* The following function outputs function to obtain internal cpu unit
8410 code by the cpu unit name. */
8412 output_get_cpu_unit_code_func ()
8417 fprintf (output_file
, "int\n%s (%s)\n\tconst char *%s;\n",
8418 GET_CPU_UNIT_CODE_FUNC_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8419 CPU_UNIT_NAME_PARAMETER_NAME
);
8420 fprintf (output_file
, "{\n struct %s {const char *%s; int %s;};\n",
8421 NAME_CODE_STRUCT_NAME
, NAME_MEMBER_NAME
, CODE_MEMBER_NAME
);
8422 fprintf (output_file
, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME
,
8423 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8424 fprintf (output_file
, " static struct %s %s [] =\n {\n",
8425 NAME_CODE_STRUCT_NAME
, NAME_CODE_TABLE_NAME
);
8426 units
= (unit_decl_t
*) xmalloc (sizeof (unit_decl_t
)
8427 * description
->units_num
);
8428 memcpy (units
, units_array
, sizeof (unit_decl_t
) * description
->units_num
);
8429 qsort (units
, description
->units_num
, sizeof (unit_decl_t
), units_cmp
);
8430 for (i
= 0; i
< description
->units_num
; i
++)
8431 if (units
[i
]->query_p
)
8432 fprintf (output_file
, " {\"%s\", %d},\n",
8433 units
[i
]->name
, units
[i
]->query_num
);
8434 fprintf (output_file
, " };\n\n");
8435 fprintf (output_file
, " /* The following is binary search: */\n");
8436 fprintf (output_file
, " %s = 0;\n", LOW_VARIABLE_NAME
);
8437 fprintf (output_file
, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8438 HIGH_VARIABLE_NAME
, NAME_CODE_TABLE_NAME
, NAME_CODE_STRUCT_NAME
);
8439 fprintf (output_file
, " while (%s <= %s)\n {\n",
8440 LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8441 fprintf (output_file
, " %s = (%s + %s) / 2;\n",
8442 MIDDLE_VARIABLE_NAME
, LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8443 fprintf (output_file
, " %s = strcmp (%s, %s [%s].%s);\n",
8444 CMP_VARIABLE_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8445 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, NAME_MEMBER_NAME
);
8446 fprintf (output_file
, " if (%s < 0)\n", CMP_VARIABLE_NAME
);
8447 fprintf (output_file
, " %s = %s - 1;\n",
8448 HIGH_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8449 fprintf (output_file
, " else if (%s > 0)\n", CMP_VARIABLE_NAME
);
8450 fprintf (output_file
, " %s = %s + 1;\n",
8451 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8452 fprintf (output_file
, " else\n");
8453 fprintf (output_file
, " return %s [%s].%s;\n }\n",
8454 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, CODE_MEMBER_NAME
);
8455 fprintf (output_file
, " return -1;\n}\n\n");
8459 /* The following function outputs function to check reservation of cpu
8460 unit (its internal code will be passed as the function argument) in
8463 output_cpu_unit_reservation_p ()
8465 automaton_t automaton
;
8467 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8468 CPU_UNIT_RESERVATION_P_FUNC_NAME
, STATE_NAME
,
8469 CPU_CODE_PARAMETER_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8470 CPU_CODE_PARAMETER_NAME
);
8471 fprintf (output_file
, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8472 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
8473 description
->query_units_num
);
8474 for (automaton
= description
->first_automaton
;
8476 automaton
= automaton
->next_automaton
)
8478 fprintf (output_file
, " if ((");
8479 output_reserved_units_table_name (output_file
, automaton
);
8480 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
8481 output_chip_member_name (output_file
, automaton
);
8482 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8483 (description
->query_units_num
+ 7) / 8,
8484 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
8485 fprintf (output_file
, " return 1;\n");
8487 fprintf (output_file
, " return 0;\n}\n\n");
8490 /* The function outputs PHR interface function `dfa_start'. */
8492 output_dfa_start_func ()
8494 fprintf (output_file
,
8495 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8496 DFA_START_FUNC_NAME
, I_VARIABLE_NAME
,
8497 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8498 fprintf (output_file
, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8499 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8500 fprintf (output_file
,
8501 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8502 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
8503 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
8504 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
8507 /* The function outputs PHR interface function `dfa_finish'. */
8509 output_dfa_finish_func ()
8511 fprintf (output_file
, "void\n%s ()\n{\n free (%s);\n}\n\n",
8512 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8517 /* The page contains code for output description file (readable
8518 representation of original description and generated DFA(s). */
8520 /* The function outputs string representation of IR reservation. */
8522 output_regexp (regexp
)
8525 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
8526 finish_regexp_representation ();
8529 /* Output names of units in LIST separated by comma. */
8531 output_unit_set_el_list (list
)
8536 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
8539 fprintf (output_description_file
, ",");
8540 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
8544 /* The function outputs string representation of IR define_reservation
8545 and define_insn_reservation. */
8547 output_description ()
8552 for (i
= 0; i
< description
->decls_num
; i
++)
8554 decl
= description
->decls
[i
];
8555 if (decl
->mode
== dm_unit
)
8557 if (decl
->decl
.unit
.excl_list
!= NULL
)
8559 fprintf (output_description_file
, "unit %s exlusion_set: ",
8560 decl
->decl
.unit
.name
);
8561 output_unit_set_el_list (decl
->decl
.unit
.excl_list
);
8562 fprintf (output_description_file
, "\n");
8564 if (decl
->decl
.unit
.presence_list
!= NULL
)
8566 fprintf (output_description_file
, "unit %s presence_set: ",
8567 decl
->decl
.unit
.name
);
8568 output_unit_set_el_list (decl
->decl
.unit
.presence_list
);
8569 fprintf (output_description_file
, "\n");
8571 if (decl
->decl
.unit
.absence_list
!= NULL
)
8573 fprintf (output_description_file
, "unit %s absence_set: ",
8574 decl
->decl
.unit
.name
);
8575 output_unit_set_el_list (decl
->decl
.unit
.absence_list
);
8576 fprintf (output_description_file
, "\n");
8580 fprintf (output_description_file
, "\n");
8581 for (i
= 0; i
< description
->decls_num
; i
++)
8583 decl
= description
->decls
[i
];
8584 if (decl
->mode
== dm_reserv
)
8586 fprintf (output_description_file
, "reservation ");
8587 fprintf (output_description_file
, decl
->decl
.reserv
.name
);
8588 fprintf (output_description_file
, ": ");
8589 output_regexp (decl
->decl
.reserv
.regexp
);
8590 fprintf (output_description_file
, "\n");
8592 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8594 fprintf (output_description_file
, "insn reservation %s ",
8595 decl
->decl
.insn_reserv
.name
);
8596 print_rtl (output_description_file
, decl
->decl
.insn_reserv
.condexp
);
8597 fprintf (output_description_file
, ": ");
8598 output_regexp (decl
->decl
.insn_reserv
.regexp
);
8599 fprintf (output_description_file
, "\n");
8601 else if (decl
->mode
== dm_bypass
)
8602 fprintf (output_description_file
, "bypass %d %s %s\n",
8603 decl
->decl
.bypass
.latency
, decl
->decl
.bypass
.out_insn_name
,
8604 decl
->decl
.bypass
.in_insn_name
);
8606 fprintf (output_description_file
, "\n\f\n");
8609 /* The function outputs name of AUTOMATON. */
8611 output_automaton_name (f
, automaton
)
8613 automaton_t automaton
;
8615 if (automaton
->corresponding_automaton_decl
== NULL
)
8616 fprintf (f
, "#%d", automaton
->automaton_order_num
);
8618 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
8621 /* Maximal length of line for pretty printing into description
8623 #define MAX_LINE_LENGTH 70
8625 /* The function outputs units name belonging to AUTOMATON. */
8627 output_automaton_units (automaton
)
8628 automaton_t automaton
;
8632 int curr_line_length
;
8633 int there_is_an_automaton_unit
;
8636 fprintf (output_description_file
, "\n Coresponding units:\n");
8637 fprintf (output_description_file
, " ");
8638 curr_line_length
= 4;
8639 there_is_an_automaton_unit
= 0;
8640 for (i
= 0; i
< description
->decls_num
; i
++)
8642 decl
= description
->decls
[i
];
8643 if (decl
->mode
== dm_unit
8644 && (decl
->decl
.unit
.corresponding_automaton_num
8645 == automaton
->automaton_order_num
))
8647 there_is_an_automaton_unit
= 1;
8648 name
= decl
->decl
.unit
.name
;
8649 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
8651 curr_line_length
= strlen (name
) + 4;
8652 fprintf (output_description_file
, "\n ");
8656 curr_line_length
+= strlen (name
) + 1;
8657 fprintf (output_description_file
, " ");
8659 fprintf (output_description_file
, name
);
8662 if (!there_is_an_automaton_unit
)
8663 fprintf (output_description_file
, "<None>");
8664 fprintf (output_description_file
, "\n\n");
8667 /* The following variable is used for forming array of all possible cpu unit
8668 reservations described by the current DFA state. */
8669 static vla_ptr_t state_reservs
;
8671 /* The function forms `state_reservs' for STATE. */
8673 add_state_reservs (state
)
8676 alt_state_t curr_alt_state
;
8677 reserv_sets_t reservs
;
8679 if (state
->component_states
!= NULL
)
8680 for (curr_alt_state
= state
->component_states
;
8681 curr_alt_state
!= NULL
;
8682 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
8683 add_state_reservs (curr_alt_state
->state
);
8686 reservs
= state
->reservs
;
8687 VLA_PTR_ADD (state_reservs
, reservs
);
8691 /* The function outputs readable represenatation of all out arcs of
8694 output_state_arcs (state
)
8700 int curr_line_length
;
8702 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
8705 if (!ainsn
->first_insn_with_same_reservs
)
8707 fprintf (output_description_file
, " ");
8708 curr_line_length
= 7;
8709 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
8712 insn_name
= ainsn
->insn_reserv_decl
->name
;
8713 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
8715 if (ainsn
!= arc
->insn
)
8717 fprintf (output_description_file
, ",\n ");
8718 curr_line_length
= strlen (insn_name
) + 6;
8721 curr_line_length
+= strlen (insn_name
);
8725 curr_line_length
+= strlen (insn_name
);
8726 if (ainsn
!= arc
->insn
)
8728 curr_line_length
+= 2;
8729 fprintf (output_description_file
, ", ");
8732 fprintf (output_description_file
, insn_name
);
8733 ainsn
= ainsn
->next_same_reservs_insn
;
8735 while (ainsn
!= NULL
);
8736 fprintf (output_description_file
, " %d (%d)\n",
8737 arc
->to_state
->order_state_num
, arc
->state_alts
);
8739 fprintf (output_description_file
, "\n");
8742 /* The following function is used for sorting possible cpu unit
8743 reservation of a DFA state. */
8745 state_reservs_cmp (reservs_ptr_1
, reservs_ptr_2
)
8746 const void *reservs_ptr_1
;
8747 const void *reservs_ptr_2
;
8749 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
8750 *(reserv_sets_t
*) reservs_ptr_2
);
8753 /* The following function is used for sorting possible cpu unit
8754 reservation of a DFA state. */
8756 remove_state_duplicate_reservs ()
8758 reserv_sets_t
*reservs_ptr
;
8759 reserv_sets_t
*last_formed_reservs_ptr
;
8761 last_formed_reservs_ptr
= NULL
;
8762 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
8763 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
8765 if (last_formed_reservs_ptr
== NULL
)
8766 last_formed_reservs_ptr
= reservs_ptr
;
8767 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
8769 ++last_formed_reservs_ptr
;
8770 *last_formed_reservs_ptr
= *reservs_ptr
;
8772 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
8775 /* The following function output readable representation of DFA(s)
8776 state used for fast recognition of pipeline hazards. State is
8777 described by possible (current and scehduled) cpu unit
8780 output_state (state
)
8783 reserv_sets_t
*reservs_ptr
;
8785 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
8786 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
8787 fprintf (output_description_file
,
8788 state
->new_cycle_p
? " (new cycle)\n" : "\n");
8789 add_state_reservs (state
);
8790 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
8791 sizeof (reserv_sets_t
), state_reservs_cmp
);
8792 remove_state_duplicate_reservs ();
8793 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
8794 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
8797 fprintf (output_description_file
, " ");
8798 output_reserv_sets (output_description_file
, *reservs_ptr
);
8799 fprintf (output_description_file
, "\n");
8801 fprintf (output_description_file
, "\n");
8802 output_state_arcs (state
);
8803 VLA_PTR_DELETE (state_reservs
);
8806 /* The following function output readable representation of
8807 DFAs used for fast recognition of pipeline hazards. */
8809 output_automaton_descriptions ()
8811 automaton_t automaton
;
8813 for (automaton
= description
->first_automaton
;
8815 automaton
= automaton
->next_automaton
)
8817 fprintf (output_description_file
, "\nAutomaton ");
8818 output_automaton_name (output_description_file
, automaton
);
8819 fprintf (output_description_file
, "\n");
8820 output_automaton_units (automaton
);
8821 pass_states (automaton
, output_state
);
8827 /* The page contains top level function for generation DFA(s) used for
8830 /* The function outputs statistics about work of different phases of
8833 output_statistics (f
)
8836 automaton_t automaton
;
8838 int transition_comb_vect_els
= 0;
8839 int transition_full_vect_els
= 0;
8840 int state_alts_comb_vect_els
= 0;
8841 int state_alts_full_vect_els
= 0;
8842 int min_issue_delay_vect_els
= 0;
8845 for (automaton
= description
->first_automaton
;
8847 automaton
= automaton
->next_automaton
)
8849 fprintf (f
, "\nAutomaton ");
8850 output_automaton_name (f
, automaton
);
8851 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
8852 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
8853 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
8854 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
8855 if (!no_minimization_flag
)
8856 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8857 automaton
->minimal_DFA_states_num
,
8858 automaton
->minimal_DFA_arcs_num
);
8859 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
8860 description
->insns_num
, automaton
->insn_equiv_classes_num
);
8863 (f
, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8864 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
),
8865 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
),
8866 (comb_vect_p (automaton
->trans_table
)
8867 ? "use comb vect" : "use simple vect"));
8869 (f
, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8870 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
),
8871 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
),
8872 (comb_vect_p (automaton
->state_alts_table
)
8873 ? "use comb vect" : "use simple vect"));
8875 (f
, "%5ld min delay table els, compression factor %d\n",
8876 (long) automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
,
8877 automaton
->min_issue_delay_table_compression_factor
);
8878 transition_comb_vect_els
8879 += VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
);
8880 transition_full_vect_els
8881 += VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
);
8882 state_alts_comb_vect_els
8883 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
);
8884 state_alts_full_vect_els
8885 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
);
8886 min_issue_delay_vect_els
8887 += automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
;
8891 fprintf (f
, "\n%5d all allocated states, %5d all allocated arcs\n",
8892 allocated_states_num
, allocated_arcs_num
);
8893 fprintf (f
, "%5d all allocated alternative states\n",
8894 allocated_alt_states_num
);
8895 fprintf (f
, "%5d all transition comb vector els, %5d all trans table els\n",
8896 transition_comb_vect_els
, transition_full_vect_els
);
8898 (f
, "%5d all state alts comb vector els, %5d all state alts table els\n",
8899 state_alts_comb_vect_els
, state_alts_full_vect_els
);
8900 fprintf (f
, "%5d all min delay table els\n", min_issue_delay_vect_els
);
8901 fprintf (f
, "%5d locked states num\n", locked_states_num
);
8905 /* The function output times of work of different phases of DFA
8908 output_time_statistics (f
)
8911 fprintf (f
, "\n transformation: ");
8912 print_active_time (f
, transform_time
);
8913 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
8914 print_active_time (f
, NDFA_time
);
8917 fprintf (f
, ", NDFA -> DFA: ");
8918 print_active_time (f
, NDFA_to_DFA_time
);
8920 fprintf (f
, "\n DFA minimization: ");
8921 print_active_time (f
, minimize_time
);
8922 fprintf (f
, ", making insn equivalence: ");
8923 print_active_time (f
, equiv_time
);
8924 fprintf (f
, "\n all automaton generation: ");
8925 print_active_time (f
, automaton_generation_time
);
8926 fprintf (f
, ", output: ");
8927 print_active_time (f
, output_time
);
8931 /* The function generates DFA (deterministic finate state automaton)
8932 for fast recognition of pipeline hazards. No errors during
8933 checking must be fixed before this function call. */
8937 automata_num
= split_argument
;
8938 if (description
->units_num
< automata_num
)
8939 automata_num
= description
->units_num
;
8942 initiate_automata_lists ();
8943 initiate_pass_states ();
8944 initiate_excl_sets ();
8945 initiate_presence_absence_sets ();
8946 automaton_generation_time
= create_ticker ();
8948 ticker_off (&automaton_generation_time
);
8953 /* The following function creates attribute which order number of insn
8954 in pipeline hazard description translator. */
8956 make_insn_alts_attr ()
8962 condexp
= rtx_alloc (COND
);
8963 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
8964 XEXP (condexp
, 1) = make_numeric_value (0);
8965 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
8967 decl
= description
->decls
[i
];
8968 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8970 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
8971 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
8972 = make_numeric_value (decl
->decl
.insn_reserv
.transformed_regexp
8973 ->regexp
.oneof
.regexps_num
);
8977 if (description
->insns_num
!= insn_num
+ 1)
8979 make_internal_attr (attr_printf (sizeof ("*")
8980 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
8981 "*%s", INSN_ALTS_FUNC_NAME
),
8987 /* The following function creates attribute which is order number of
8988 insn in pipeline hazard description translator. */
8990 make_internal_dfa_insn_code_attr ()
8996 condexp
= rtx_alloc (COND
);
8997 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
8998 XEXP (condexp
, 1) = make_numeric_value (advance_cycle_insn_decl
8999 ->decl
.insn_reserv
.insn_num
+ 1);
9000 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9002 decl
= description
->decls
[i
];
9003 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9005 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
9006 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9007 = make_numeric_value (decl
->decl
.insn_reserv
.insn_num
);
9011 if (description
->insns_num
!= insn_num
+ 1)
9014 (attr_printf (sizeof ("*")
9015 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
9016 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
9022 /* The following function creates attribute which order number of insn
9023 in pipeline hazard description translator. */
9025 make_default_insn_latency_attr ()
9031 condexp
= rtx_alloc (COND
);
9032 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9033 XEXP (condexp
, 1) = make_numeric_value (0);
9034 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9036 decl
= description
->decls
[i
];
9037 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9039 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
9040 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9041 = make_numeric_value (decl
->decl
.insn_reserv
.default_latency
);
9045 if (description
->insns_num
!= insn_num
+ 1)
9047 make_internal_attr (attr_printf (sizeof ("*")
9048 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
9049 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
9055 /* The following function creates attribute which returns 1 if given
9056 output insn has bypassing and 0 otherwise. */
9061 int bypass_insns_num
= 0;
9065 for (i
= 0; i
< description
->decls_num
; i
++)
9067 decl
= description
->decls
[i
];
9068 if (decl
->mode
== dm_insn_reserv
9069 && decl
->decl
.insn_reserv
.condexp
!= NULL
9070 && decl
->decl
.insn_reserv
.bypass_list
!= NULL
)
9073 if (bypass_insns_num
== 0)
9074 result_rtx
= make_numeric_value (0);
9077 result_rtx
= rtx_alloc (COND
);
9078 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
9079 XEXP (result_rtx
, 1) = make_numeric_value (0);
9081 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
9083 decl
= description
->decls
[i
];
9084 if (decl
->mode
== dm_insn_reserv
9085 && decl
->decl
.insn_reserv
.condexp
!= NULL
9086 && decl
->decl
.insn_reserv
.bypass_list
!= NULL
)
9088 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9089 = decl
->decl
.insn_reserv
.condexp
;
9090 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9091 = make_numeric_value (1);
9096 make_internal_attr (attr_printf (sizeof ("*")
9097 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9098 "*%s", BYPASS_P_FUNC_NAME
),
9104 /* This page mainly contains top level functions of pipeline hazards
9105 description translator. */
9107 /* The following macro value is suffix of name of description file of
9108 pipeline hazards description translator. */
9109 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9111 /* The function returns suffix of given file name. The returned
9112 string can not be changed. */
9114 file_name_suffix (file_name
)
9115 const char *file_name
;
9117 const char *last_period
;
9119 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9120 if (*file_name
== '.')
9121 last_period
= file_name
;
9122 return (last_period
== NULL
? file_name
: last_period
);
9125 /* The function returns base name of given file name, i.e. pointer to
9126 first char after last `/' (or `\' for WIN32) in given file name,
9127 given file name itself if the directory name is absent. The
9128 returned string can not be changed. */
9130 base_file_name (file_name
)
9131 const char *file_name
;
9133 int directory_name_length
;
9135 directory_name_length
= strlen (file_name
);
9137 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9138 && file_name
[directory_name_length
] != '\\')
9140 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9142 directory_name_length
--;
9143 return file_name
+ directory_name_length
+ 1;
9146 /* The following is top level function to initialize the work of
9147 pipeline hazards description translator. */
9149 initiate_automaton_gen (argc
, argv
)
9153 const char *base_name
;
9157 split_argument
= 0; /* default value */
9158 no_minimization_flag
= 0;
9162 for (i
= 2; i
< argc
; i
++)
9163 if (strcmp (argv
[i
], NO_MINIMIZATION_OPTION
) == 0)
9164 no_minimization_flag
= 1;
9165 else if (strcmp (argv
[i
], "-time") == 0)
9167 else if (strcmp (argv
[i
], "-v") == 0)
9169 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9171 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9173 else if (strcmp (argv
[i
], "-split") == 0)
9176 fatal ("-split has no argument.");
9177 fatal ("option `-split' has not been implemented yet\n");
9178 /* split_argument = atoi (argument_vect [i + 1]); */
9180 VLA_PTR_CREATE (decls
, 150, "decls");
9181 /* Initialize IR storage. */
9182 obstack_init (&irp
);
9183 initiate_automaton_decl_table ();
9184 initiate_insn_decl_table ();
9185 initiate_decl_table ();
9186 output_file
= stdout
;
9187 output_description_file
= NULL
;
9188 base_name
= base_file_name (argv
[1]);
9189 obstack_grow (&irp
, base_name
,
9190 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9191 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9192 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9193 obstack_1grow (&irp
, '\0');
9194 output_description_file_name
= obstack_base (&irp
);
9195 obstack_finish (&irp
);
9198 /* The following function checks existence at least one arc marked by
9201 check_automata_insn_issues ()
9203 automaton_t automaton
;
9204 ainsn_t ainsn
, reserv_ainsn
;
9206 for (automaton
= description
->first_automaton
;
9208 automaton
= automaton
->next_automaton
)
9210 for (ainsn
= automaton
->ainsn_list
;
9212 ainsn
= ainsn
->next_ainsn
)
9213 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9215 for (reserv_ainsn
= ainsn
;
9216 reserv_ainsn
!= NULL
;
9217 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9218 if (automaton
->corresponding_automaton_decl
!= NULL
)
9221 error ("Automaton `%s': Insn `%s' will never be issued",
9222 automaton
->corresponding_automaton_decl
->name
,
9223 reserv_ainsn
->insn_reserv_decl
->name
);
9226 ("Automaton `%s': Insn `%s' will never be issued",
9227 automaton
->corresponding_automaton_decl
->name
,
9228 reserv_ainsn
->insn_reserv_decl
->name
);
9233 error ("Insn `%s' will never be issued",
9234 reserv_ainsn
->insn_reserv_decl
->name
);
9236 warning ("Insn `%s' will never be issued",
9237 reserv_ainsn
->insn_reserv_decl
->name
);
9243 /* The following vla is used for storing pointers to all achieved
9245 static vla_ptr_t automaton_states
;
9247 /* This function is called by function pass_states to add an achieved
9250 add_automaton_state (state
)
9253 VLA_PTR_ADD (automaton_states
, state
);
9256 /* The following function forms list of important automata (whose
9257 states may be changed after the insn issue) for each insn. */
9259 form_important_insn_automata_lists ()
9261 automaton_t automaton
;
9268 VLA_PTR_CREATE (automaton_states
, 1500,
9269 "automaton states for forming important insn automata sets");
9270 /* Mark important ainsns. */
9271 for (automaton
= description
->first_automaton
;
9273 automaton
= automaton
->next_automaton
)
9275 VLA_PTR_NULLIFY (automaton_states
);
9276 pass_states (automaton
, add_automaton_state
);
9277 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9278 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9281 for (arc
= first_out_arc (*state_ptr
);
9283 arc
= next_out_arc (arc
))
9284 if (arc
->to_state
!= *state_ptr
)
9286 if (!arc
->insn
->first_insn_with_same_reservs
)
9288 for (ainsn
= arc
->insn
;
9290 ainsn
= ainsn
->next_same_reservs_insn
)
9291 ainsn
->important_p
= TRUE
;
9295 VLA_PTR_DELETE (automaton_states
);
9296 /* Create automata sets for the insns. */
9297 for (i
= 0; i
< description
->decls_num
; i
++)
9299 decl
= description
->decls
[i
];
9300 if (decl
->mode
== dm_insn_reserv
)
9302 automata_list_start ();
9303 for (automaton
= description
->first_automaton
;
9305 automaton
= automaton
->next_automaton
)
9306 for (ainsn
= automaton
->ainsn_list
;
9308 ainsn
= ainsn
->next_ainsn
)
9309 if (ainsn
->important_p
9310 && ainsn
->insn_reserv_decl
== &decl
->decl
.insn_reserv
)
9312 automata_list_add (automaton
);
9315 decl
->decl
.insn_reserv
.important_automata_list
9316 = automata_list_finish ();
9322 /* The following is top level function to generate automat(a,on) for
9323 fast recognition of pipeline hazards. */
9329 description
= create_node (sizeof (struct description
)
9330 /* One entry for cycle advancing insn. */
9331 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9332 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9333 description
->query_units_num
= 0;
9334 for (i
= 0; i
< description
->decls_num
; i
++)
9336 description
->decls
[i
] = VLA_PTR (decls
, i
);
9337 if (description
->decls
[i
]->mode
== dm_unit
9338 && description
->decls
[i
]->decl
.unit
.query_p
)
9339 description
->decls
[i
]->decl
.unit
.query_num
9340 = description
->query_units_num
++;
9342 all_time
= create_ticker ();
9343 check_time
= create_ticker ();
9344 fprintf (stderr
, "Check description...");
9346 check_all_description ();
9347 fprintf (stderr
, "done\n");
9348 ticker_off (&check_time
);
9349 generation_time
= create_ticker ();
9352 transform_insn_regexps ();
9353 check_unit_distributions_to_automata ();
9358 check_automata_insn_issues ();
9362 form_important_insn_automata_lists ();
9363 fprintf (stderr
, "Generation of attributes...");
9365 make_internal_dfa_insn_code_attr ();
9366 make_insn_alts_attr ();
9367 make_default_insn_latency_attr ();
9368 make_bypass_attr ();
9369 fprintf (stderr
, "done\n");
9371 ticker_off (&generation_time
);
9372 ticker_off (&all_time
);
9373 fprintf (stderr
, "All other genattrtab stuff...");
9377 /* The following is top level function to output PHR and to finish
9378 work with pipeline description translator. */
9382 fprintf (stderr
, "done\n");
9384 fatal ("Errors in DFA description");
9385 ticker_on (&all_time
);
9386 output_time
= create_ticker ();
9387 fprintf (stderr
, "Forming and outputing automata tables...");
9389 output_dfa_max_issue_rate ();
9391 fprintf (stderr
, "done\n");
9392 fprintf (stderr
, "Output functions to work with automata...");
9394 output_chip_definitions ();
9395 output_max_insn_queue_index_def ();
9396 output_internal_min_issue_delay_func ();
9397 output_internal_trans_func ();
9398 /* Cache of insn dfa codes: */
9399 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9400 fprintf (output_file
, "\nstatic int %s;\n\n",
9401 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9402 output_dfa_insn_code_func ();
9403 output_trans_func ();
9404 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
9405 output_internal_state_alts_func ();
9406 output_state_alts_func ();
9407 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9408 AUTOMATON_STATE_ALTS_MACRO_NAME
);
9409 output_min_issue_delay_func ();
9410 output_internal_dead_lock_func ();
9411 output_dead_lock_func ();
9412 output_size_func ();
9413 output_internal_reset_func ();
9414 output_reset_func ();
9415 output_min_insn_conflict_delay_func ();
9416 output_internal_insn_latency_func ();
9417 output_insn_latency_func ();
9418 output_print_reservation_func ();
9419 if (no_minimization_flag
)
9421 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
9422 output_get_cpu_unit_code_func ();
9423 output_cpu_unit_reservation_p ();
9424 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9425 CPU_UNITS_QUERY_MACRO_NAME
);
9427 output_dfa_start_func ();
9428 output_dfa_finish_func ();
9429 fprintf (stderr
, "done\n");
9432 output_description_file
= fopen (output_description_file_name
, "w");
9433 if (output_description_file
== NULL
)
9435 perror (output_description_file_name
);
9436 exit (FATAL_EXIT_CODE
);
9438 fprintf (stderr
, "Output automata description...");
9440 output_description ();
9441 output_automaton_descriptions ();
9442 fprintf (stderr
, "done\n");
9443 output_statistics (output_description_file
);
9445 output_statistics (stderr
);
9446 ticker_off (&output_time
);
9447 output_time_statistics (stderr
);
9450 finish_automata_lists ();
9453 fprintf (stderr
, "Summary:\n");
9454 fprintf (stderr
, " check time ");
9455 print_active_time (stderr
, check_time
);
9456 fprintf (stderr
, ", generation time ");
9457 print_active_time (stderr
, generation_time
);
9458 fprintf (stderr
, ", all time ");
9459 print_active_time (stderr
, all_time
);
9460 fprintf (stderr
, "\n");
9462 /* Finish all work. */
9463 if (output_description_file
!= NULL
)
9465 fflush (output_description_file
);
9466 if (ferror (stdout
) != 0)
9467 fatal ("Error in writing DFA description file %s",
9468 output_description_file_name
);
9469 fclose (output_description_file
);
9471 finish_automaton_decl_table ();
9472 finish_insn_decl_table ();
9473 finish_decl_table ();
9474 obstack_free (&irp
, NULL
);
9475 if (have_error
&& output_description_file
!= NULL
)
9476 remove (output_description_file_name
);