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
117 #include "genattrtab.h"
119 #define obstack_chunk_alloc xmalloc
120 #define obstack_chunk_free free
122 /* Positions in machine description file. Now they are not used. But
123 they could be used in the future for better diagnostic messages. */
126 /* The following is element of vector of current (and planned in the
127 future) functional unit reservations. */
128 typedef unsigned HOST_WIDE_INT set_el_t
;
130 /* Reservations of function units are represented by value of the following
132 typedef set_el_t
*reserv_sets_t
;
134 /* The following structure represents variable length array (vla) of
135 pointers and HOST WIDE INTs. We could be use only varray. But we
136 add new lay because we add elements very frequently and this could
137 stress OS allocator when varray is used only. */
139 size_t length
; /* current size of vla. */
140 varray_type varray
; /* container for vla. */
143 typedef vla_ptr_t vla_hwint_t
;
145 /* The following structure describes a ticker. */
148 /* The following member value is time of the ticker creation with
149 taking into account time when the ticker is off. Active time of
150 the ticker is current time minus the value. */
151 int modified_creation_time
;
152 /* The following member value is time (incremented by one) when the
153 ticker was off. Zero value means that now the ticker is on. */
154 int incremented_off_time
;
157 /* The ticker is represented by the following type. */
158 typedef struct ticker ticker_t
;
160 /* The following type describes elements of output vectors. */
161 typedef HOST_WIDE_INT vect_el_t
;
163 /* Forward declaration of structures of internal representation of
164 pipeline description based on NDFA. */
169 struct automaton_decl
;
170 struct unit_rel_decl
;
172 struct insn_reserv_decl
;
175 struct result_regexp
;
176 struct reserv_regexp
;
177 struct nothing_regexp
;
178 struct sequence_regexp
;
179 struct repeat_regexp
;
190 struct state_ainsn_table
;
192 /* The following typedefs are for brevity. */
193 typedef struct unit_decl
*unit_decl_t
;
194 typedef struct decl
*decl_t
;
195 typedef struct regexp
*regexp_t
;
196 typedef struct unit_set_el
*unit_set_el_t
;
197 typedef struct alt_state
*alt_state_t
;
198 typedef struct state
*state_t
;
199 typedef struct arc
*arc_t
;
200 typedef struct ainsn
*ainsn_t
;
201 typedef struct automaton
*automaton_t
;
202 typedef struct automata_list_el
*automata_list_el_t
;
203 typedef struct state_ainsn_table
*state_ainsn_table_t
;
206 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
207 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
208 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
209 initiate_automaton_gen, expand_automata, write_automata are
210 described on the file top because the functions are called from
213 static void *create_node
PARAMS ((size_t));
214 static void *copy_node
PARAMS ((void *, size_t));
215 static char *check_name
PARAMS ((char *, pos_t
));
216 static char *next_sep_el
PARAMS ((char **, int, int));
217 static int n_sep_els
PARAMS ((char *, int, int));
218 static char **get_str_vect
PARAMS ((char *, int *, int, int));
219 static regexp_t gen_regexp_el
PARAMS ((char *));
220 static regexp_t gen_regexp_repeat
PARAMS ((char *));
221 static regexp_t gen_regexp_allof
PARAMS ((char *));
222 static regexp_t gen_regexp_oneof
PARAMS ((char *));
223 static regexp_t gen_regexp_sequence
PARAMS ((char *));
224 static regexp_t gen_regexp
PARAMS ((char *));
226 static unsigned string_hash
PARAMS ((const char *));
227 static unsigned automaton_decl_hash
PARAMS ((const void *));
228 static int automaton_decl_eq_p
PARAMS ((const void *,
230 static decl_t insert_automaton_decl
PARAMS ((decl_t
));
231 static decl_t find_automaton_decl
PARAMS ((char *));
232 static void initiate_automaton_decl_table
PARAMS ((void));
233 static void finish_automaton_decl_table
PARAMS ((void));
235 static unsigned insn_decl_hash
PARAMS ((const void *));
236 static int insn_decl_eq_p
PARAMS ((const void *,
238 static decl_t insert_insn_decl
PARAMS ((decl_t
));
239 static decl_t find_insn_decl
PARAMS ((char *));
240 static void initiate_insn_decl_table
PARAMS ((void));
241 static void finish_insn_decl_table
PARAMS ((void));
243 static unsigned decl_hash
PARAMS ((const void *));
244 static int decl_eq_p
PARAMS ((const void *,
246 static decl_t insert_decl
PARAMS ((decl_t
));
247 static decl_t find_decl
PARAMS ((char *));
248 static void initiate_decl_table
PARAMS ((void));
249 static void finish_decl_table
PARAMS ((void));
251 static unit_set_el_t process_excls
PARAMS ((char **, int, pos_t
));
252 static void add_excls
PARAMS ((unit_set_el_t
, unit_set_el_t
,
254 static unit_set_el_t process_presence_absence
255 PARAMS ((char **, int, pos_t
, int));
256 static void add_presence_absence
PARAMS ((unit_set_el_t
, unit_set_el_t
,
258 static void process_decls
PARAMS ((void));
259 static struct bypass_decl
*find_bypass
PARAMS ((struct bypass_decl
*,
260 struct insn_reserv_decl
*));
261 static void check_automaton_usage
PARAMS ((void));
262 static regexp_t process_regexp
PARAMS ((regexp_t
));
263 static void process_regexp_decls
PARAMS ((void));
264 static void check_usage
PARAMS ((void));
265 static int loop_in_regexp
PARAMS ((regexp_t
, decl_t
));
266 static void check_loops_in_regexps
PARAMS ((void));
267 static int process_regexp_cycles
PARAMS ((regexp_t
, int));
268 static void evaluate_max_reserv_cycles
PARAMS ((void));
269 static void check_all_description
PARAMS ((void));
271 static ticker_t create_ticker
PARAMS ((void));
272 static void ticker_off
PARAMS ((ticker_t
*));
273 static void ticker_on
PARAMS ((ticker_t
*));
274 static int active_time
PARAMS ((ticker_t
));
275 static void print_active_time
PARAMS ((FILE *, ticker_t
));
277 static void add_advance_cycle_insn_decl
PARAMS ((void));
279 static alt_state_t get_free_alt_state
PARAMS ((void));
280 static void free_alt_state
PARAMS ((alt_state_t
));
281 static void free_alt_states
PARAMS ((alt_state_t
));
282 static int alt_state_cmp
PARAMS ((const void *alt_state_ptr_1
,
283 const void *alt_state_ptr_2
));
284 static alt_state_t uniq_sort_alt_states
PARAMS ((alt_state_t
));
285 static int alt_states_eq
PARAMS ((alt_state_t
, alt_state_t
));
286 static void initiate_alt_states
PARAMS ((void));
287 static void finish_alt_states
PARAMS ((void));
289 static reserv_sets_t alloc_empty_reserv_sets
PARAMS ((void));
290 static unsigned reserv_sets_hash_value
PARAMS ((reserv_sets_t
));
291 static int reserv_sets_cmp
PARAMS ((reserv_sets_t
, reserv_sets_t
));
292 static int reserv_sets_eq
PARAMS ((reserv_sets_t
, reserv_sets_t
));
293 static void set_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
294 static int test_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
295 static int it_is_empty_reserv_sets
PARAMS ((reserv_sets_t
))
297 static int reserv_sets_are_intersected
PARAMS ((reserv_sets_t
, reserv_sets_t
));
298 static void reserv_sets_shift
PARAMS ((reserv_sets_t
, reserv_sets_t
));
299 static void reserv_sets_or
PARAMS ((reserv_sets_t
, reserv_sets_t
,
301 static void reserv_sets_and
PARAMS ((reserv_sets_t
, reserv_sets_t
,
304 static void output_cycle_reservs
PARAMS ((FILE *, reserv_sets_t
,
306 static void output_reserv_sets
PARAMS ((FILE *, reserv_sets_t
));
307 static state_t get_free_state
PARAMS ((int, automaton_t
));
308 static void free_state
PARAMS ((state_t
));
309 static unsigned state_hash
PARAMS ((const void *));
310 static int state_eq_p
PARAMS ((const void *, const void *));
311 static state_t insert_state
PARAMS ((state_t
));
312 static void set_state_reserv
PARAMS ((state_t
, int, int));
313 static int intersected_state_reservs_p
PARAMS ((state_t
, state_t
));
314 static state_t states_union
PARAMS ((state_t
, state_t
));
315 static state_t state_shift
PARAMS ((state_t
));
316 static void initiate_states
PARAMS ((void));
317 static void finish_states
PARAMS ((void));
319 static void free_arc
PARAMS ((arc_t
));
320 static void remove_arc
PARAMS ((state_t
, arc_t
));
321 static arc_t find_arc
PARAMS ((state_t
, state_t
, ainsn_t
));
322 static arc_t add_arc
PARAMS ((state_t
, state_t
, ainsn_t
, int));
323 static arc_t first_out_arc
PARAMS ((state_t
));
324 static arc_t next_out_arc
PARAMS ((arc_t
));
325 static void initiate_arcs
PARAMS ((void));
326 static void finish_arcs
PARAMS ((void));
328 static automata_list_el_t get_free_automata_list_el
PARAMS ((void));
329 static void free_automata_list_el
PARAMS ((automata_list_el_t
));
330 static void free_automata_list
PARAMS ((automata_list_el_t
));
331 static unsigned automata_list_hash
PARAMS ((const void *));
332 static int automata_list_eq_p
PARAMS ((const void *, const void *));
333 static void initiate_automata_lists
PARAMS ((void));
334 static void automata_list_start
PARAMS ((void));
335 static void automata_list_add
PARAMS ((automaton_t
));
336 static automata_list_el_t automata_list_finish
PARAMS ((void));
337 static void finish_automata_lists
PARAMS ((void));
339 static void initiate_excl_sets
PARAMS ((void));
340 static reserv_sets_t get_excl_set
PARAMS ((reserv_sets_t
));
342 static void initiate_presence_absence_sets
PARAMS ((void));
343 static reserv_sets_t get_presence_absence_set
PARAMS ((reserv_sets_t
, int));
345 static regexp_t copy_insn_regexp
PARAMS ((regexp_t
));
346 static regexp_t transform_1
PARAMS ((regexp_t
));
347 static regexp_t transform_2
PARAMS ((regexp_t
));
348 static regexp_t transform_3
PARAMS ((regexp_t
));
349 static regexp_t regexp_transform_func
350 PARAMS ((regexp_t
, regexp_t (*) (regexp_t
)));
351 static regexp_t transform_regexp
PARAMS ((regexp_t
));
352 static void transform_insn_regexps
PARAMS ((void));
354 static void process_unit_to_form_the_same_automaton_unit_lists
355 PARAMS ((regexp_t
, regexp_t
, int));
356 static void form_the_same_automaton_unit_lists_from_regexp
PARAMS ((regexp_t
));
357 static void form_the_same_automaton_unit_lists
PARAMS ((void));
358 static void check_unit_distributions_to_automata
PARAMS ((void));
360 static int process_seq_for_forming_states
PARAMS ((regexp_t
, automaton_t
,
362 static void finish_forming_alt_state
PARAMS ((alt_state_t
,
364 static void process_alts_for_forming_states
PARAMS ((regexp_t
,
366 static void create_alt_states
PARAMS ((automaton_t
));
368 static void form_ainsn_with_same_reservs
PARAMS ((automaton_t
));
370 static void make_automaton
PARAMS ((automaton_t
));
371 static void form_arcs_marked_by_insn
PARAMS ((state_t
));
372 static void create_composed_state
PARAMS ((state_t
, arc_t
, vla_ptr_t
*));
373 static void NDFA_to_DFA
PARAMS ((automaton_t
));
374 static void pass_state_graph
PARAMS ((state_t
, void (*) (state_t
)));
375 static void pass_states
PARAMS ((automaton_t
,
376 void (*) (state_t
)));
377 static void initiate_pass_states
PARAMS ((void));
378 static void add_achieved_state
PARAMS ((state_t
));
379 static int set_out_arc_insns_equiv_num
PARAMS ((state_t
, int));
380 static void clear_arc_insns_equiv_num
PARAMS ((state_t
));
381 static void copy_equiv_class
PARAMS ((vla_ptr_t
*to
,
382 const vla_ptr_t
*from
));
383 static int state_is_differed
PARAMS ((state_t
, int, int));
384 static state_t init_equiv_class
PARAMS ((state_t
*states
, int));
385 static int partition_equiv_class
PARAMS ((state_t
*, int,
386 vla_ptr_t
*, int *));
387 static void evaluate_equiv_classes
PARAMS ((automaton_t
, vla_ptr_t
*));
388 static void merge_states
PARAMS ((automaton_t
, vla_ptr_t
*));
389 static void set_new_cycle_flags
PARAMS ((state_t
));
390 static void minimize_DFA
PARAMS ((automaton_t
));
391 static void incr_states_and_arcs_nums
PARAMS ((state_t
));
392 static void count_states_and_arcs
PARAMS ((automaton_t
, int *, int *));
393 static void build_automaton
PARAMS ((automaton_t
));
395 static void set_order_state_num
PARAMS ((state_t
));
396 static void enumerate_states
PARAMS ((automaton_t
));
398 static ainsn_t insert_ainsn_into_equiv_class
PARAMS ((ainsn_t
, ainsn_t
));
399 static void delete_ainsn_from_equiv_class
PARAMS ((ainsn_t
));
400 static void process_insn_equiv_class
PARAMS ((ainsn_t
, arc_t
*));
401 static void process_state_for_insn_equiv_partition
PARAMS ((state_t
));
402 static void set_insn_equiv_classes
PARAMS ((automaton_t
));
404 static double estimate_one_automaton_bound
PARAMS ((void));
405 static int compare_max_occ_cycle_nums
PARAMS ((const void *,
407 static void units_to_automata_heuristic_distr
PARAMS ((void));
408 static ainsn_t create_ainsns
PARAMS ((void));
409 static void units_to_automata_distr
PARAMS ((void));
410 static void create_automata
PARAMS ((void));
412 static void form_regexp
PARAMS ((regexp_t
));
413 static const char *regexp_representation
PARAMS ((regexp_t
));
414 static void finish_regexp_representation
PARAMS ((void));
416 static void output_range_type
PARAMS ((FILE *, long int, long int));
417 static int longest_path_length
PARAMS ((state_t
));
418 static void process_state_longest_path_length
PARAMS ((state_t
));
419 static void output_dfa_max_issue_rate
PARAMS ((void));
420 static void output_vect
PARAMS ((vect_el_t
*, int));
421 static void output_chip_member_name
PARAMS ((FILE *, automaton_t
));
422 static void output_temp_chip_member_name
PARAMS ((FILE *, automaton_t
));
423 static void output_translate_vect_name
PARAMS ((FILE *, automaton_t
));
424 static void output_trans_full_vect_name
PARAMS ((FILE *, automaton_t
));
425 static void output_trans_comb_vect_name
PARAMS ((FILE *, automaton_t
));
426 static void output_trans_check_vect_name
PARAMS ((FILE *, automaton_t
));
427 static void output_trans_base_vect_name
PARAMS ((FILE *, automaton_t
));
428 static void output_state_alts_full_vect_name
PARAMS ((FILE *, automaton_t
));
429 static void output_state_alts_comb_vect_name
PARAMS ((FILE *, automaton_t
));
430 static void output_state_alts_check_vect_name
PARAMS ((FILE *, automaton_t
));
431 static void output_state_alts_base_vect_name
PARAMS ((FILE *, automaton_t
));
432 static void output_min_issue_delay_vect_name
PARAMS ((FILE *, automaton_t
));
433 static void output_dead_lock_vect_name
PARAMS ((FILE *, automaton_t
));
434 static void output_reserved_units_table_name
PARAMS ((FILE *, automaton_t
));
435 static void output_state_member_type
PARAMS ((FILE *, automaton_t
));
436 static void output_chip_definitions
PARAMS ((void));
437 static void output_translate_vect
PARAMS ((automaton_t
));
438 static int comb_vect_p
PARAMS ((state_ainsn_table_t
));
439 static state_ainsn_table_t create_state_ainsn_table
PARAMS ((automaton_t
));
440 static void output_state_ainsn_table
441 PARAMS ((state_ainsn_table_t
, char *, void (*) (FILE *, automaton_t
),
442 void (*) (FILE *, automaton_t
), void (*) (FILE *, automaton_t
),
443 void (*) (FILE *, automaton_t
)));
444 static void add_vect
PARAMS ((state_ainsn_table_t
,
445 int, vect_el_t
*, int));
446 static int out_state_arcs_num
PARAMS ((state_t
));
447 static int compare_transition_els_num
PARAMS ((const void *, const void *));
448 static void add_vect_el
PARAMS ((vla_hwint_t
*,
450 static void add_states_vect_el
PARAMS ((state_t
));
451 static void output_trans_table
PARAMS ((automaton_t
));
452 static void output_state_alts_table
PARAMS ((automaton_t
));
453 static int min_issue_delay_pass_states
PARAMS ((state_t
, ainsn_t
));
454 static int min_issue_delay
PARAMS ((state_t
, ainsn_t
));
455 static void initiate_min_issue_delay_pass_states
PARAMS ((void));
456 static void output_min_issue_delay_table
PARAMS ((automaton_t
));
457 static void output_dead_lock_vect
PARAMS ((automaton_t
));
458 static void output_reserved_units_table
PARAMS ((automaton_t
));
459 static void output_tables
PARAMS ((void));
460 static void output_max_insn_queue_index_def
PARAMS ((void));
461 static void output_insn_code_cases
PARAMS ((void (*) (automata_list_el_t
)));
462 static void output_automata_list_min_issue_delay_code
PARAMS ((automata_list_el_t
));
463 static void output_internal_min_issue_delay_func
PARAMS ((void));
464 static void output_automata_list_transition_code
PARAMS ((automata_list_el_t
));
465 static void output_internal_trans_func
PARAMS ((void));
466 static void output_internal_insn_code_evaluation
PARAMS ((const char *,
468 static void output_dfa_insn_code_func
PARAMS ((void));
469 static void output_trans_func
PARAMS ((void));
470 static void output_automata_list_state_alts_code
PARAMS ((automata_list_el_t
));
471 static void output_internal_state_alts_func
PARAMS ((void));
472 static void output_state_alts_func
PARAMS ((void));
473 static void output_min_issue_delay_func
PARAMS ((void));
474 static void output_internal_dead_lock_func
PARAMS ((void));
475 static void output_dead_lock_func
PARAMS ((void));
476 static void output_internal_reset_func
PARAMS ((void));
477 static void output_size_func
PARAMS ((void));
478 static void output_reset_func
PARAMS ((void));
479 static void output_min_insn_conflict_delay_func
PARAMS ((void));
480 static void output_internal_insn_latency_func
PARAMS ((void));
481 static void output_insn_latency_func
PARAMS ((void));
482 static void output_print_reservation_func
PARAMS ((void));
483 static int units_cmp
PARAMS ((const void *,
485 static void output_get_cpu_unit_code_func
PARAMS ((void));
486 static void output_cpu_unit_reservation_p
PARAMS ((void));
487 static void output_dfa_start_func
PARAMS ((void));
488 static void output_dfa_finish_func
PARAMS ((void));
490 static void output_regexp
PARAMS ((regexp_t
));
491 static void output_unit_set_el_list
PARAMS ((unit_set_el_t
));
492 static void output_description
PARAMS ((void));
493 static void output_automaton_name
PARAMS ((FILE *, automaton_t
));
494 static void output_automaton_units
PARAMS ((automaton_t
));
495 static void add_state_reservs
PARAMS ((state_t
));
496 static void output_state_arcs
PARAMS ((state_t
));
497 static int state_reservs_cmp
PARAMS ((const void *,
499 static void remove_state_duplicate_reservs
PARAMS ((void));
500 static void output_state
PARAMS ((state_t
));
501 static void output_automaton_descriptions
PARAMS ((void));
502 static void output_statistics
PARAMS ((FILE *));
503 static void output_time_statistics
PARAMS ((FILE *));
504 static void generate
PARAMS ((void));
506 static void make_insn_alts_attr
PARAMS ((void));
507 static void make_internal_dfa_insn_code_attr
PARAMS ((void));
508 static void make_default_insn_latency_attr
PARAMS ((void));
509 static void make_bypass_attr
PARAMS ((void));
510 static const char *file_name_suffix
PARAMS ((const char *));
511 static const char *base_file_name
PARAMS ((const char *));
512 static void check_automata_insn_issues
PARAMS ((void));
513 static void add_automaton_state
PARAMS ((state_t
));
514 static void form_important_insn_automata_lists
PARAMS ((void));
516 /* Undefined position. */
517 static pos_t no_pos
= 0;
519 /* All IR is stored in the following obstack. */
520 static struct obstack irp
;
524 /* This page contains code for work with variable length array (vla)
525 of pointers. We could be use only varray. But we add new lay
526 because we add elements very frequently and this could stress OS
527 allocator when varray is used only. */
529 /* Start work with vla. */
530 #define VLA_PTR_CREATE(vla, allocated_length, name) \
533 vla_ptr_t *vla_ptr = &(vla); \
535 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
536 vla_ptr->length = 0; \
540 /* Finish work with the vla. */
541 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
543 /* Return start address of the vla. */
544 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
546 /* Address of the last element of the vla. Do not use side effects in
547 the macro argument. */
548 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
550 /* Nullify the vla. */
551 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
553 /* Shorten the vla on given number bytes. */
554 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
556 /* Expand the vla on N elements. The values of new elements are
558 #define VLA_PTR_EXPAND(vla, n) \
560 vla_ptr_t *expand_vla_ptr = &(vla); \
561 size_t new_length = (n) + expand_vla_ptr->length; \
563 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
564 VARRAY_GROW (expand_vla_ptr->varray, \
565 (new_length - expand_vla_ptr->length < 128 \
566 ? expand_vla_ptr->length + 128 : new_length)); \
567 expand_vla_ptr->length = new_length; \
570 /* Add element to the end of the vla. */
571 #define VLA_PTR_ADD(vla, ptr) \
573 vla_ptr_t *vla_ptr = &(vla); \
575 VLA_PTR_EXPAND (*vla_ptr, 1); \
576 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
579 /* Length of the vla in elements. */
580 #define VLA_PTR_LENGTH(vla) ((vla).length)
582 /* N-th element of the vla. */
583 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
586 /* The following macros are analogous to the previous ones but for
587 VLAs of HOST WIDE INTs. */
589 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
591 vla_hwint_t *vla_ptr = &(vla); \
593 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
594 vla_ptr->length = 0; \
597 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
599 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
601 /* Do not use side effects in the macro argument. */
602 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
605 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
607 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
609 #define VLA_HWINT_EXPAND(vla, n) \
611 vla_hwint_t *expand_vla_ptr = &(vla); \
612 size_t new_length = (n) + expand_vla_ptr->length; \
614 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
615 VARRAY_GROW (expand_vla_ptr->varray, \
616 (new_length - expand_vla_ptr->length < 128 \
617 ? expand_vla_ptr->length + 128 : new_length)); \
618 expand_vla_ptr->length = new_length; \
621 #define VLA_HWINT_ADD(vla, ptr) \
623 vla_hwint_t *vla_ptr = &(vla); \
625 VLA_HWINT_EXPAND (*vla_ptr, 1); \
626 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
629 #define VLA_HWINT_LENGTH(vla) ((vla).length)
631 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
635 /* Options with the following names can be set up in automata_option
636 construction. Because the strings occur more one time we use the
639 #define NO_MINIMIZATION_OPTION "-no-minimization"
641 #define TIME_OPTION "-time"
643 #define V_OPTION "-v"
645 #define W_OPTION "-w"
647 #define NDFA_OPTION "-ndfa"
649 /* The following flags are set up by function `initiate_automaton_gen'. */
651 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
652 static int ndfa_flag
;
654 /* Do not make minimization of DFA (`-no-minimization'). */
655 static int no_minimization_flag
;
657 /* Value of this variable is number of automata being generated. The
658 actual number of automata may be less this value if there is not
659 sufficient number of units. This value is defined by argument of
660 option `-split' or by constructions automaton if the value is zero
661 (it is default value of the argument). */
662 static int split_argument
;
664 /* Flag of output time statistics (`-time'). */
665 static int time_flag
;
667 /* Flag of creation of description file which contains description of
668 result automaton and statistics information (`-v'). */
671 /* Flag of generating warning instead of error for non-critical errors
676 /* Output file for pipeline hazard recognizer (PHR) being generated.
677 The value is NULL if the file is not defined. */
678 static FILE *output_file
;
680 /* Description file of PHR. The value is NULL if the file is not
682 static FILE *output_description_file
;
684 /* PHR description file name. */
685 static char *output_description_file_name
;
687 /* Value of the following variable is node representing description
688 being processed. This is start point of IR. */
689 static struct description
*description
;
693 /* This page contains description of IR structure (nodes). */
707 /* This describes define_cpu_unit and define_query_cpu_unit (see file
712 /* NULL if the automaton name is absent. */
713 char *automaton_name
;
714 /* If the following value is not zero, the cpu unit reservation is
715 described in define_query_cpu_unit. */
718 /* The following fields are defined by checker. */
720 /* The following field value is nonzero if the unit is used in an
724 /* The following field value is used to form cyclic lists of units
725 which should be in the same automaton because the unit is
726 reserved not on all alternatives of a regexp on a cycle. */
727 unit_decl_t the_same_automaton_unit
;
728 /* The following field is TRUE if we already reported that the unit
729 is not in the same automaton. */
730 int the_same_automaton_message_reported_p
;
732 /* The following field value is order number (0, 1, ...) of given
735 /* The following field value is corresponding declaration of
736 automaton which was given in description. If the field value is
737 NULL then automaton in the unit declaration was absent. */
738 struct automaton_decl
*automaton_decl
;
739 /* The following field value is maximal cycle number (1, ...) on
740 which given unit occurs in insns. Zero value means that given
741 unit is not used in insns. */
742 int max_occ_cycle_num
;
743 /* The following list contains units which conflict with given
745 unit_set_el_t excl_list
;
746 /* The following list contains units which are required to
747 reservation of given unit. */
748 unit_set_el_t presence_list
;
749 /* The following list contains units which should be not present in
750 reservation for given unit. */
751 unit_set_el_t absence_list
;
752 /* The following is used only when `query_p' has nonzero value.
753 This is query number for the unit. */
756 /* The following fields are defined by automaton generator. */
758 /* The following field value is number of the automaton to which
759 given unit belongs. */
760 int corresponding_automaton_num
;
763 /* This describes define_bypass (see file rtl.def). */
769 char *bypass_guard_name
;
771 /* The following fields are defined by checker. */
773 /* output and input insns of given bypass. */
774 struct insn_reserv_decl
*out_insn_reserv
;
775 struct insn_reserv_decl
*in_insn_reserv
;
776 /* The next bypass for given output insn. */
777 struct bypass_decl
*next
;
780 /* This describes define_automaton (see file rtl.def). */
781 struct automaton_decl
785 /* The following fields are defined by automaton generator. */
787 /* The following field value is nonzero if the automaton is used in
788 an regexp definition. */
789 char automaton_is_used
;
791 /* The following fields are defined by checker. */
793 /* The following field value is the corresponding automaton. This
794 field is not NULL only if the automaton is present in unit
795 declarations and the automatic partition on automata is not
797 automaton_t corresponding_automaton
;
800 /* This describes unit relations: exclusion_set, presence_set, or
801 absence_set (see file rtl.def). */
805 int first_list_length
;
809 /* This describes define_reservation (see file rtl.def). */
815 /* The following fields are defined by checker. */
817 /* The following field value is nonzero if the unit is used in an
820 /* The following field is used to check up cycle in expression
825 /* This describes define_insn_reservartion (see file rtl.def). */
826 struct insn_reserv_decl
833 /* The following fields are defined by checker. */
835 /* The following field value is order number (0, 1, ...) of given
838 /* The following field value is list of bypasses in which given insn
840 struct bypass_decl
*bypass_list
;
842 /* The following fields are defined by automaton generator. */
844 /* The following field is the insn regexp transformed that
845 the regexp has not optional regexp, repetition regexp, and an
846 reservation name (i.e. reservation identifiers are changed by the
847 corresponding regexp) and all alternations are the topest level
848 of the regexp. The value can be NULL only if it is special
849 insn `cycle advancing'. */
850 regexp_t transformed_regexp
;
851 /* The following field value is list of arcs marked given
852 insn. The field is used in transfromation NDFA -> DFA. */
853 arc_t arcs_marked_by_insn
;
854 /* The two following fields are used during minimization of a finite state
856 /* The field value is number of equivalence class of state into
857 which arc marked by given insn enters from a state (fixed during
858 an automaton minimization). */
860 /* The field value is state_alts of arc leaving a state (fixed
861 during an automaton minimization) and marked by given insn
864 /* The following member value is the list to automata which can be
865 changed by the insn issue. */
866 automata_list_el_t important_automata_list
;
867 /* The following member is used to process insn once for output. */
871 /* This contains a declaration mentioned above. */
874 /* What node in the union? */
879 struct unit_decl unit
;
880 struct bypass_decl bypass
;
881 struct automaton_decl automaton
;
882 struct unit_rel_decl excl
;
883 struct unit_rel_decl presence
;
884 struct unit_rel_decl absence
;
885 struct reserv_decl reserv
;
886 struct insn_reserv_decl insn_reserv
;
890 /* The following structures represent parsed reservation strings. */
902 /* Cpu unit in reservation. */
906 unit_decl_t unit_decl
;
909 /* Define_reservation in a reservation. */
913 struct reserv_decl
*reserv_decl
;
916 /* Absence of reservation (represented by string `nothing'). */
917 struct nothing_regexp
919 /* This used to be empty but ISO C doesn't allow that. */
923 /* Representation of reservations separated by ',' (see file
925 struct sequence_regexp
928 regexp_t regexps
[1];
931 /* Representation of construction `repeat' (see file rtl.def). */
938 /* Representation of reservations separated by '+' (see file
943 regexp_t regexps
[1];
946 /* Representation of reservations separated by '|' (see file
951 regexp_t regexps
[1];
954 /* Representation of a reservation string. */
957 /* What node in the union? */
958 enum regexp_mode mode
;
962 struct unit_regexp unit
;
963 struct reserv_regexp reserv
;
964 struct nothing_regexp nothing
;
965 struct sequence_regexp sequence
;
966 struct repeat_regexp repeat
;
967 struct allof_regexp allof
;
968 struct oneof_regexp oneof
;
972 /* Reperesents description of pipeline hazard description based on
978 /* The following fields are defined by checker. */
980 /* The following fields values are correspondingly number of all
981 units, query units, and insns in the description. */
985 /* The following field value is max length (in cycles) of
986 reservations of insns. The field value is defined only for
988 int max_insn_reserv_cycles
;
990 /* The following fields are defined by automaton generator. */
992 /* The following field value is the first automaton. */
993 automaton_t first_automaton
;
995 /* The following field is created by pipeline hazard parser and
996 contains all declarations. We allocate additional entry for
997 special insn "cycle advancing" which is added by the automaton
1004 /* The following nodes are created in automaton checker. */
1006 /* The following nodes represent exclusion, presence, absence set for
1007 cpu units. Each element are accessed through only one excl_list,
1008 presence_list, absence_list. */
1011 unit_decl_t unit_decl
;
1012 unit_set_el_t next_unit_set_el
;
1017 /* The following nodes are created in automaton generator. */
1019 /* The following node type describes state automaton. The state may
1020 be deterministic or non-deterministic. Non-deterministic state has
1021 several component states which represent alternative cpu units
1022 reservations. The state also is used for describing a
1023 deterministic reservation of automaton insn. */
1026 /* The following member value is nonzero if there is a transition by
1029 /* The following field is list of processor unit reservations on
1031 reserv_sets_t reservs
;
1032 /* The following field is unique number of given state between other
1035 /* The following field value is automaton to which given state
1037 automaton_t automaton
;
1038 /* The following field value is the first arc output from given
1040 arc_t first_out_arc
;
1041 /* The following field is used to form NDFA. */
1042 char it_was_placed_in_stack_for_NDFA_forming
;
1043 /* The following field is used to form DFA. */
1044 char it_was_placed_in_stack_for_DFA_forming
;
1045 /* The following field is used to transform NDFA to DFA. The field
1046 value is not NULL if the state is a compound state. In this case
1047 the value of field `unit_sets_list' is NULL. All states in the
1048 list are in the hash table. The list is formed through field
1049 `next_sorted_alt_state'. */
1050 alt_state_t component_states
;
1051 /* The following field is used for passing graph of states. */
1053 /* The list of states belonging to one equivalence class is formed
1054 with the aid of the following field. */
1055 state_t next_equiv_class_state
;
1056 /* The two following fields are used during minimization of a finite
1058 int equiv_class_num_1
, equiv_class_num_2
;
1059 /* The following field is used during minimization of a finite state
1060 automaton. The field value is state corresponding to equivalence
1061 class to which given state belongs. */
1062 state_t equiv_class_state
;
1063 /* The following field value is the order number of given state.
1064 The states in final DFA is enumerated with the aid of the
1066 int order_state_num
;
1067 /* This member is used for passing states for searching minimal
1070 /* The following member is used to evaluate min issue delay of insn
1072 int min_insn_issue_delay
;
1073 /* The following member is used to evaluate max issue rate of the
1074 processor. The value of the member is maximal length of the path
1075 from given state no containing arcs marked by special insn `cycle
1077 int longest_path_length
;
1080 /* The following macro is an initial value of member
1081 `longest_path_length' of a state. */
1082 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1084 /* Automaton arc. */
1087 /* The following field refers for the state into which given arc
1090 /* The following field describes that the insn issue (with cycle
1091 advancing for special insn `cycle advancing' and without cycle
1092 advancing for others) makes transition from given state to
1093 another given state. */
1095 /* The following field value is the next arc output from the same
1098 /* List of arcs marked given insn is formed with the following
1099 field. The field is used in transfromation NDFA -> DFA. */
1100 arc_t next_arc_marked_by_insn
;
1101 /* The following field is defined if NDFA_FLAG is zero. The member
1102 value is number of alternative reservations which can be used for
1103 transition for given state by given insn. */
1107 /* The following node type describes a deterministic alternative in
1108 non-deterministic state which characterizes cpu unit reservations
1109 of automaton insn or which is part of NDFA. */
1112 /* The following field is a determinist state which characterizes
1113 unit reservations of the instruction. */
1115 /* The following field refers to the next state which characterizes
1116 unit reservations of the instruction. */
1117 alt_state_t next_alt_state
;
1118 /* The following field refers to the next state in sorted list. */
1119 alt_state_t next_sorted_alt_state
;
1122 /* The following node type describes insn of automaton. They are
1123 labels of FA arcs. */
1126 /* The following field value is the corresponding insn declaration
1128 struct insn_reserv_decl
*insn_reserv_decl
;
1129 /* The following field value is the next insn declaration for an
1132 /* The following field is states which characterize automaton unit
1133 reservations of the instruction. The value can be NULL only if it
1134 is special insn `cycle advancing'. */
1135 alt_state_t alt_states
;
1136 /* The following field is sorted list of states which characterize
1137 automaton unit reservations of the instruction. The value can be
1138 NULL only if it is special insn `cycle advancing'. */
1139 alt_state_t sorted_alt_states
;
1140 /* The following field refers the next automaton insn with
1141 the same reservations. */
1142 ainsn_t next_same_reservs_insn
;
1143 /* The following field is flag of the first automaton insn with the
1144 same reservations in the declaration list. Only arcs marked such
1145 insn is present in the automaton. This significantly decreases
1146 memory requirements especially when several automata are
1148 char first_insn_with_same_reservs
;
1149 /* The following member has nonzero value if there is arc from state of
1150 the automaton marked by the ainsn. */
1152 /* Cyclic list of insns of an equivalence class is formed with the
1153 aid of the following field. */
1154 ainsn_t next_equiv_class_insn
;
1155 /* The following field value is nonzero if the insn declaration is
1156 the first insn declaration with given equivalence number. */
1157 char first_ainsn_with_given_equialence_num
;
1158 /* The following field is number of class of equivalence of insns.
1159 It is necessary because many insns may be equivalent with the
1160 point of view of pipeline hazards. */
1161 int insn_equiv_class_num
;
1162 /* The following member value is TRUE if there is an arc in the
1163 automaton marked by the insn into another state. In other
1164 words, the insn can change the state of the automaton. */
1168 /* The folowing describes an automaton for PHR. */
1171 /* The following field value is the list of insn declarations for
1174 /* The following field value is the corresponding automaton
1175 declaration. This field is not NULL only if the automatic
1176 partition on automata is not used. */
1177 struct automaton_decl
*corresponding_automaton_decl
;
1178 /* The following field value is the next automaton. */
1179 automaton_t next_automaton
;
1180 /* The following field is start state of FA. There are not unit
1181 reservations in the state. */
1182 state_t start_state
;
1183 /* The following field value is number of equivalence classes of
1184 insns (see field `insn_equiv_class_num' in
1185 `insn_reserv_decl'). */
1186 int insn_equiv_classes_num
;
1187 /* The following field value is number of states of final DFA. */
1188 int achieved_states_num
;
1189 /* The following field value is the order number (0, 1, ...) of
1191 int automaton_order_num
;
1192 /* The following fields contain statistics information about
1193 building automaton. */
1194 int NDFA_states_num
, DFA_states_num
;
1195 /* The following field value is defined only if minimization of DFA
1197 int minimal_DFA_states_num
;
1198 int NDFA_arcs_num
, DFA_arcs_num
;
1199 /* The following field value is defined only if minimization of DFA
1201 int minimal_DFA_arcs_num
;
1202 /* The following two members refer for two table state x ainsn ->
1204 state_ainsn_table_t trans_table
;
1205 state_ainsn_table_t state_alts_table
;
1206 /* The following member value is maximal value of min issue delay
1207 for insns of the automaton. */
1209 /* Usually min issue delay is small and we can place several (2, 4,
1210 8) elements in one vector element. So the compression factor can
1211 be 1 (no compression), 2, 4, 8. */
1212 int min_issue_delay_table_compression_factor
;
1215 /* The following is the element of the list of automata. */
1216 struct automata_list_el
1218 /* The automaton itself. */
1219 automaton_t automaton
;
1220 /* The next automata set element. */
1221 automata_list_el_t next_automata_list_el
;
1224 /* The following structure describes a table state X ainsn -> int(>= 0). */
1225 struct state_ainsn_table
1227 /* Automaton to which given table belongs. */
1228 automaton_t automaton
;
1229 /* The following tree vectors for comb vector implementation of the
1231 vla_hwint_t comb_vect
;
1232 vla_hwint_t check_vect
;
1233 vla_hwint_t base_vect
;
1234 /* This is simple implementation of the table. */
1235 vla_hwint_t full_vect
;
1236 /* Minimal and maximal values of the previous vectors. */
1237 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1238 int min_base_vect_el_value
, max_base_vect_el_value
;
1241 /* Macros to access members of unions. Use only them for access to
1242 union members of declarations and regexps. */
1244 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1246 #define DECL_UNIT(d) __extension__ \
1247 (({ struct decl *_decl = (d); \
1248 if (_decl->mode != dm_unit) \
1249 decl_mode_check_failed (_decl->mode, "dm_unit", \
1250 __FILE__, __LINE__, __FUNCTION__); \
1251 &(_decl)->decl.unit; }))
1253 #define DECL_BYPASS(d) __extension__ \
1254 (({ struct decl *_decl = (d); \
1255 if (_decl->mode != dm_bypass) \
1256 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1257 __FILE__, __LINE__, __FUNCTION__); \
1258 &(_decl)->decl.bypass; }))
1260 #define DECL_AUTOMATON(d) __extension__ \
1261 (({ struct decl *_decl = (d); \
1262 if (_decl->mode != dm_automaton) \
1263 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1264 __FILE__, __LINE__, __FUNCTION__); \
1265 &(_decl)->decl.automaton; }))
1267 #define DECL_EXCL(d) __extension__ \
1268 (({ struct decl *_decl = (d); \
1269 if (_decl->mode != dm_excl) \
1270 decl_mode_check_failed (_decl->mode, "dm_excl", \
1271 __FILE__, __LINE__, __FUNCTION__); \
1272 &(_decl)->decl.excl; }))
1274 #define DECL_PRESENCE(d) __extension__ \
1275 (({ struct decl *_decl = (d); \
1276 if (_decl->mode != dm_presence) \
1277 decl_mode_check_failed (_decl->mode, "dm_presence", \
1278 __FILE__, __LINE__, __FUNCTION__); \
1279 &(_decl)->decl.presence; }))
1281 #define DECL_ABSENCE(d) __extension__ \
1282 (({ struct decl *_decl = (d); \
1283 if (_decl->mode != dm_absence) \
1284 decl_mode_check_failed (_decl->mode, "dm_absence", \
1285 __FILE__, __LINE__, __FUNCTION__); \
1286 &(_decl)->decl.absence; }))
1288 #define DECL_RESERV(d) __extension__ \
1289 (({ struct decl *_decl = (d); \
1290 if (_decl->mode != dm_reserv) \
1291 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1292 __FILE__, __LINE__, __FUNCTION__); \
1293 &(_decl)->decl.reserv; }))
1295 #define DECL_INSN_RESERV(d) __extension__ \
1296 (({ struct decl *_decl = (d); \
1297 if (_decl->mode != dm_insn_reserv) \
1298 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1299 __FILE__, __LINE__, __FUNCTION__); \
1300 &(_decl)->decl.insn_reserv; }))
1302 static const char *decl_name
PARAMS ((enum decl_mode
));
1303 static void decl_mode_check_failed
PARAMS ((enum decl_mode
, const char *,
1304 const char *, int, const char *));
1306 /* Return string representation of declaration mode MODE. */
1309 enum decl_mode mode
;
1311 static char str
[100];
1313 if (mode
== dm_unit
)
1315 else if (mode
== dm_bypass
)
1317 else if (mode
== dm_automaton
)
1318 return "dm_automaton";
1319 else if (mode
== dm_excl
)
1321 else if (mode
== dm_presence
)
1322 return "dm_presence";
1323 else if (mode
== dm_absence
)
1324 return "dm_absence";
1325 else if (mode
== dm_reserv
)
1327 else if (mode
== dm_insn_reserv
)
1328 return "dm_insn_reserv";
1330 sprintf (str
, "unknown (%d)", (int) mode
);
1334 /* The function prints message about unexpected declaration and finish
1337 decl_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1338 enum decl_mode mode
;
1339 const char *expected_mode_str
;
1346 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1347 file
, line
, func
, expected_mode_str
, decl_name (mode
));
1352 #define REGEXP_UNIT(r) __extension__ \
1353 (({ struct regexp *_regexp = (r); \
1354 if (_regexp->mode != rm_unit) \
1355 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1356 __FILE__, __LINE__, __FUNCTION__); \
1357 &(_regexp)->regexp.unit; }))
1359 #define REGEXP_RESERV(r) __extension__ \
1360 (({ struct regexp *_regexp = (r); \
1361 if (_regexp->mode != rm_reserv) \
1362 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1363 __FILE__, __LINE__, __FUNCTION__); \
1364 &(_regexp)->regexp.reserv; }))
1366 #define REGEXP_SEQUENCE(r) __extension__ \
1367 (({ struct regexp *_regexp = (r); \
1368 if (_regexp->mode != rm_sequence) \
1369 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1370 __FILE__, __LINE__, __FUNCTION__); \
1371 &(_regexp)->regexp.sequence; }))
1373 #define REGEXP_REPEAT(r) __extension__ \
1374 (({ struct regexp *_regexp = (r); \
1375 if (_regexp->mode != rm_repeat) \
1376 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1377 __FILE__, __LINE__, __FUNCTION__); \
1378 &(_regexp)->regexp.repeat; }))
1380 #define REGEXP_ALLOF(r) __extension__ \
1381 (({ struct regexp *_regexp = (r); \
1382 if (_regexp->mode != rm_allof) \
1383 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1384 __FILE__, __LINE__, __FUNCTION__); \
1385 &(_regexp)->regexp.allof; }))
1387 #define REGEXP_ONEOF(r) __extension__ \
1388 (({ struct regexp *_regexp = (r); \
1389 if (_regexp->mode != rm_oneof) \
1390 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1391 __FILE__, __LINE__, __FUNCTION__); \
1392 &(_regexp)->regexp.oneof; }))
1394 static const char *regexp_name
PARAMS ((enum regexp_mode
));
1395 static void regexp_mode_check_failed
PARAMS ((enum regexp_mode
, const char *,
1400 /* Return string representation of regexp mode MODE. */
1403 enum regexp_mode mode
;
1405 static char str
[100];
1407 if (mode
== rm_unit
)
1409 else if (mode
== rm_reserv
)
1411 else if (mode
== rm_nothing
)
1412 return "rm_nothing";
1413 else if (mode
== rm_sequence
)
1414 return "rm_sequence";
1415 else if (mode
== rm_repeat
)
1417 else if (mode
== rm_allof
)
1419 else if (mode
== rm_oneof
)
1422 sprintf (str
, "unknown (%d)", (int) mode
);
1426 /* The function prints message about unexpected regexp and finish the
1429 regexp_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1430 enum regexp_mode mode
;
1431 const char *expected_mode_str
;
1438 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1439 file
, line
, func
, expected_mode_str
, regexp_name (mode
));
1443 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1445 #define DECL_UNIT(d) (&(d)->decl.unit)
1446 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1447 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1448 #define DECL_EXCL(d) (&(d)->decl.excl)
1449 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1450 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1451 #define DECL_RESERV(d) (&(d)->decl.reserv)
1452 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1454 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1455 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1456 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1457 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1458 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1459 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1461 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1463 /* Create IR structure (node). */
1470 obstack_blank (&irp
, size
);
1471 result
= obstack_base (&irp
);
1472 obstack_finish (&irp
);
1473 /* Default values of members are NULL and zero. */
1474 memset (result
, 0, size
);
1478 /* Copy IR structure (node). */
1480 copy_node (from
, size
)
1485 result
= create_node (size
);
1486 memcpy (result
, from
, size
);
1490 /* The function checks that NAME does not contain quotes (`"'). */
1492 check_name (name
, pos
)
1494 pos_t pos ATTRIBUTE_UNUSED
;
1498 for (str
= name
; *str
!= '\0'; str
++)
1500 error ("Name `%s' contains quotes", name
);
1504 /* Pointers top all declartions during IR generation are stored in the
1506 static vla_ptr_t decls
;
1508 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1509 string containing the next separated element, taking parentheses
1510 into account if PAR_FLAG has nonzero value. Advance the pointer to
1511 after the string scanned, or the end-of-string. Return NULL if at
1514 next_sep_el (pstr
, sep
, par_flag
)
1524 /* Remove leading whitespaces. */
1525 while (ISSPACE ((int) **pstr
))
1532 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1534 if (par_flag
&& *p
== '(')
1536 else if (par_flag
&& *p
== ')')
1538 else if (pars_num
== 0 && *p
== sep
)
1540 if (pars_num
== 0 && ISSPACE ((int) *p
))
1544 for (; n_spaces
!= 0; n_spaces
--)
1545 obstack_1grow (&irp
, p
[-n_spaces
]);
1546 obstack_1grow (&irp
, *p
);
1549 obstack_1grow (&irp
, '\0');
1550 out_str
= obstack_base (&irp
);
1551 obstack_finish (&irp
);
1560 /* Given a string and a separator, return the number of separated
1561 elements in it, taking parentheses into account if PAR_FLAG has
1562 nonzero value. Return 0 for the null string, -1 if parantheses is
1565 n_sep_els (s
, sep
, par_flag
)
1576 for (pars_num
= 0, n
= 1; *s
; s
++)
1577 if (par_flag
&& *s
== '(')
1579 else if (par_flag
&& *s
== ')')
1581 else if (pars_num
== 0 && *s
== sep
)
1584 return (pars_num
!= 0 ? -1 : n
);
1587 /* Given a string and a separator, return vector of strings which are
1588 elements in the string and number of elements through els_num.
1589 Take parentheses into account if PAR_FLAG has nonzero value.
1590 Return 0 for the null string, -1 if parantheses are not balanced. */
1592 get_str_vect (str
, els_num
, sep
, par_flag
)
1602 *els_num
= n_sep_els (str
, sep
, par_flag
);
1605 obstack_blank (&irp
, sizeof (char *) * (*els_num
));
1606 vect
= (char **) obstack_base (&irp
);
1607 obstack_finish (&irp
);
1609 for (i
= 0; i
< *els_num
; i
++)
1610 vect
[i
] = next_sep_el (pstr
, sep
, par_flag
);
1611 if (next_sep_el (pstr
, sep
, par_flag
) != NULL
)
1616 /* Process a DEFINE_CPU_UNIT.
1618 This gives information about a unit contained in CPU. We fill a
1619 struct unit_decl with information used later by `expand_automata'. */
1625 char **str_cpu_units
;
1629 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1630 if (str_cpu_units
== NULL
)
1631 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1632 for (i
= 0; i
< vect_length
; i
++)
1634 decl
= create_node (sizeof (struct decl
));
1635 decl
->mode
= dm_unit
;
1637 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1638 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1639 DECL_UNIT (decl
)->query_p
= 0;
1640 VLA_PTR_ADD (decls
, decl
);
1645 /* Process a DEFINE_QUERY_CPU_UNIT.
1647 This gives information about a unit contained in CPU. We fill a
1648 struct unit_decl with information used later by `expand_automata'. */
1650 gen_query_cpu_unit (def
)
1654 char **str_cpu_units
;
1658 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1659 if (str_cpu_units
== NULL
)
1660 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1661 for (i
= 0; i
< vect_length
; i
++)
1663 decl
= create_node (sizeof (struct decl
));
1664 decl
->mode
= dm_unit
;
1666 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1667 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1668 DECL_UNIT (decl
)->query_p
= 1;
1669 VLA_PTR_ADD (decls
, decl
);
1674 /* Process a DEFINE_BYPASS.
1676 This gives information about a unit contained in the CPU. We fill
1677 in a struct bypass_decl with information used later by
1678 `expand_automata'. */
1690 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', 0);
1691 if (out_insns
== NULL
)
1692 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1693 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', 0);
1694 if (in_insns
== NULL
)
1695 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1696 for (i
= 0; i
< out_length
; i
++)
1697 for (j
= 0; j
< in_length
; j
++)
1699 decl
= create_node (sizeof (struct decl
));
1700 decl
->mode
= dm_bypass
;
1702 DECL_BYPASS (decl
)->latency
= XINT (def
, 0);
1703 DECL_BYPASS (decl
)->out_insn_name
= out_insns
[i
];
1704 DECL_BYPASS (decl
)->in_insn_name
= in_insns
[j
];
1705 DECL_BYPASS (decl
)->bypass_guard_name
= (char *) XSTR (def
, 3);
1706 VLA_PTR_ADD (decls
, decl
);
1711 /* Process an EXCLUSION_SET.
1713 This gives information about a cpu unit conflicts. We fill a
1714 struct unit_rel_decl (excl) with information used later by
1715 `expand_automata'. */
1721 char **first_str_cpu_units
;
1722 char **second_str_cpu_units
;
1723 int first_vect_length
;
1728 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1729 if (first_str_cpu_units
== NULL
)
1730 fatal ("invalid first string `%s' in exclusion_set", XSTR (def
, 0));
1731 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1733 if (second_str_cpu_units
== NULL
)
1734 fatal ("invalid second string `%s' in exclusion_set", XSTR (def
, 1));
1735 length
+= first_vect_length
;
1736 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1737 decl
->mode
= dm_excl
;
1739 DECL_EXCL (decl
)->names_num
= length
;
1740 DECL_EXCL (decl
)->first_list_length
= first_vect_length
;
1741 for (i
= 0; i
< length
; i
++)
1742 if (i
< first_vect_length
)
1743 DECL_EXCL (decl
)->names
[i
] = first_str_cpu_units
[i
];
1745 DECL_EXCL (decl
)->names
[i
]
1746 = second_str_cpu_units
[i
- first_vect_length
];
1747 VLA_PTR_ADD (decls
, decl
);
1751 /* Process a PRESENCE_SET.
1753 This gives information about a cpu unit reservation requirements.
1754 We fill a struct unit_rel_decl (presence) with information used
1755 later by `expand_automata'. */
1757 gen_presence_set (def
)
1761 char **first_str_cpu_units
;
1762 char **second_str_cpu_units
;
1763 int first_vect_length
;
1768 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1769 if (first_str_cpu_units
== NULL
)
1770 fatal ("invalid first string `%s' in presence_set", XSTR (def
, 0));
1771 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1773 if (second_str_cpu_units
== NULL
)
1774 fatal ("invalid second string `%s' in presence_set", XSTR (def
, 1));
1775 length
+= first_vect_length
;
1776 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1777 decl
->mode
= dm_presence
;
1779 DECL_PRESENCE (decl
)->names_num
= length
;
1780 DECL_PRESENCE (decl
)->first_list_length
= first_vect_length
;
1781 for (i
= 0; i
< length
; i
++)
1782 if (i
< first_vect_length
)
1783 DECL_PRESENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1785 DECL_PRESENCE (decl
)->names
[i
]
1786 = second_str_cpu_units
[i
- first_vect_length
];
1787 VLA_PTR_ADD (decls
, decl
);
1791 /* Process an ABSENCE_SET.
1793 This gives information about a cpu unit reservation requirements.
1794 We fill a struct unit_rel_decl (absence) with information used
1795 later by `expand_automata'. */
1797 gen_absence_set (def
)
1801 char **first_str_cpu_units
;
1802 char **second_str_cpu_units
;
1803 int first_vect_length
;
1808 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1809 if (first_str_cpu_units
== NULL
)
1810 fatal ("invalid first string `%s' in absence_set", XSTR (def
, 0));
1811 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1813 if (second_str_cpu_units
== NULL
)
1814 fatal ("invalid second string `%s' in absence_set", XSTR (def
, 1));
1815 length
+= first_vect_length
;
1816 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1817 decl
->mode
= dm_absence
;
1819 DECL_ABSENCE (decl
)->names_num
= length
;
1820 DECL_ABSENCE (decl
)->first_list_length
= first_vect_length
;
1821 for (i
= 0; i
< length
; i
++)
1822 if (i
< first_vect_length
)
1823 DECL_ABSENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1825 DECL_ABSENCE (decl
)->names
[i
]
1826 = second_str_cpu_units
[i
- first_vect_length
];
1827 VLA_PTR_ADD (decls
, decl
);
1831 /* Process a DEFINE_AUTOMATON.
1833 This gives information about a finite state automaton used for
1834 recognizing pipeline hazards. We fill a struct automaton_decl
1835 with information used later by `expand_automata'. */
1841 char **str_automata
;
1845 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1846 if (str_automata
== NULL
)
1847 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1848 for (i
= 0; i
< vect_length
; i
++)
1850 decl
= create_node (sizeof (struct decl
));
1851 decl
->mode
= dm_automaton
;
1853 DECL_AUTOMATON (decl
)->name
= check_name (str_automata
[i
], decl
->pos
);
1854 VLA_PTR_ADD (decls
, decl
);
1859 /* Process an AUTOMATA_OPTION.
1861 This gives information how to generate finite state automaton used
1862 for recognizing pipeline hazards. */
1864 gen_automata_option (def
)
1867 if (strcmp ((char *) XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1868 no_minimization_flag
= 1;
1869 else if (strcmp ((char *) XSTR (def
, 0), TIME_OPTION
+ 1) == 0)
1871 else if (strcmp ((char *) XSTR (def
, 0), V_OPTION
+ 1) == 0)
1873 else if (strcmp ((char *) XSTR (def
, 0), W_OPTION
+ 1) == 0)
1875 else if (strcmp ((char *) XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1878 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1881 /* Name in reservation to denote absence reservation. */
1882 #define NOTHING_NAME "nothing"
1884 /* The following string contains original reservation string being
1886 static char *reserv_str
;
1888 /* Parse an element in STR. */
1899 if (str
[len
- 1] != ')')
1900 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1901 str
[len
- 1] = '\0';
1902 regexp
= gen_regexp_sequence (str
+ 1);
1904 else if (strcmp (str
, NOTHING_NAME
) == 0)
1906 regexp
= create_node (sizeof (struct decl
));
1907 regexp
->mode
= rm_nothing
;
1911 regexp
= create_node (sizeof (struct decl
));
1912 regexp
->mode
= rm_unit
;
1913 REGEXP_UNIT (regexp
)->name
= str
;
1918 /* Parse construction `repeat' in STR. */
1920 gen_regexp_repeat (str
)
1929 repeat_vect
= get_str_vect (str
, &els_num
, '*', 1);
1930 if (repeat_vect
== NULL
)
1931 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1934 regexp
= gen_regexp_el (repeat_vect
[0]);
1935 for (i
= 1; i
< els_num
; i
++)
1937 repeat
= create_node (sizeof (struct regexp
));
1938 repeat
->mode
= rm_repeat
;
1939 REGEXP_REPEAT (repeat
)->regexp
= regexp
;
1940 REGEXP_REPEAT (repeat
)->repeat_num
= atoi (repeat_vect
[i
]);
1941 if (REGEXP_REPEAT (repeat
)->repeat_num
<= 1)
1942 fatal ("repetition `%s' <= 1 in reservation `%s'",
1949 return gen_regexp_el (str
);
1952 /* Parse reservation STR which possibly contains separator '+'. */
1954 gen_regexp_allof (str
)
1962 allof_vect
= get_str_vect (str
, &els_num
, '+', 1);
1963 if (allof_vect
== NULL
)
1964 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1967 allof
= create_node (sizeof (struct regexp
)
1968 + sizeof (regexp_t
) * (els_num
- 1));
1969 allof
->mode
= rm_allof
;
1970 REGEXP_ALLOF (allof
)->regexps_num
= els_num
;
1971 for (i
= 0; i
< els_num
; i
++)
1972 REGEXP_ALLOF (allof
)->regexps
[i
] = gen_regexp_repeat (allof_vect
[i
]);
1976 return gen_regexp_repeat (str
);
1979 /* Parse reservation STR which possibly contains separator '|'. */
1981 gen_regexp_oneof (str
)
1989 oneof_vect
= get_str_vect (str
, &els_num
, '|', 1);
1990 if (oneof_vect
== NULL
)
1991 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1994 oneof
= create_node (sizeof (struct regexp
)
1995 + sizeof (regexp_t
) * (els_num
- 1));
1996 oneof
->mode
= rm_oneof
;
1997 REGEXP_ONEOF (oneof
)->regexps_num
= els_num
;
1998 for (i
= 0; i
< els_num
; i
++)
1999 REGEXP_ONEOF (oneof
)->regexps
[i
] = gen_regexp_allof (oneof_vect
[i
]);
2003 return gen_regexp_allof (str
);
2006 /* Parse reservation STR which possibly contains separator ','. */
2008 gen_regexp_sequence (str
)
2012 char **sequence_vect
;
2016 sequence_vect
= get_str_vect (str
, &els_num
, ',', 1);
2019 sequence
= create_node (sizeof (struct regexp
)
2020 + sizeof (regexp_t
) * (els_num
- 1));
2021 sequence
->mode
= rm_sequence
;
2022 REGEXP_SEQUENCE (sequence
)->regexps_num
= els_num
;
2023 for (i
= 0; i
< els_num
; i
++)
2024 REGEXP_SEQUENCE (sequence
)->regexps
[i
]
2025 = gen_regexp_oneof (sequence_vect
[i
]);
2029 return gen_regexp_oneof (str
);
2032 /* Parse construction reservation STR. */
2038 return gen_regexp_sequence (str
);;
2041 /* Process a DEFINE_RESERVATION.
2043 This gives information about a reservation of cpu units. We fill
2044 in a struct reserv_decl with information used later by
2045 `expand_automata'. */
2052 decl
= create_node (sizeof (struct decl
));
2053 decl
->mode
= dm_reserv
;
2055 DECL_RESERV (decl
)->name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
2056 DECL_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 1));
2057 VLA_PTR_ADD (decls
, decl
);
2061 /* Process a DEFINE_INSN_RESERVATION.
2063 This gives information about the reservation of cpu units by an
2064 insn. We fill a struct insn_reserv_decl with information used
2065 later by `expand_automata'. */
2067 gen_insn_reserv (def
)
2072 decl
= create_node (sizeof (struct decl
));
2073 decl
->mode
= dm_insn_reserv
;
2075 DECL_INSN_RESERV (decl
)->name
2076 = check_name ((char *) XSTR (def
, 0), decl
->pos
);
2077 DECL_INSN_RESERV (decl
)->default_latency
= XINT (def
, 1);
2078 DECL_INSN_RESERV (decl
)->condexp
= XEXP (def
, 2);
2079 DECL_INSN_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 3));
2080 VLA_PTR_ADD (decls
, decl
);
2086 /* The function evaluates hash value (0..UINT_MAX) of string. */
2088 string_hash (string
)
2093 for (result
= i
= 0;*string
++ != '\0'; i
++)
2094 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
2100 /* This page contains abstract data `table of automaton declarations'.
2101 Elements of the table is nodes representing automaton declarations.
2102 Key of the table elements is name of given automaton. Rememeber
2103 that automaton names have own space. */
2105 /* The function evaluates hash value of an automaton declaration. The
2106 function is used by abstract data `hashtab'. The function returns
2107 hash value (0..UINT_MAX) of given automaton declaration. */
2109 automaton_decl_hash (automaton_decl
)
2110 const void *automaton_decl
;
2112 const decl_t decl
= (decl_t
) automaton_decl
;
2114 if (decl
->mode
== dm_automaton
&& DECL_AUTOMATON (decl
)->name
== NULL
)
2116 return string_hash (DECL_AUTOMATON (decl
)->name
);
2119 /* The function tests automaton declarations on equality of their
2120 keys. The function is used by abstract data `hashtab'. The
2121 function returns 1 if the declarations have the same key, 0
2124 automaton_decl_eq_p (automaton_decl_1
, automaton_decl_2
)
2125 const void* automaton_decl_1
;
2126 const void* automaton_decl_2
;
2128 const decl_t decl1
= (decl_t
) automaton_decl_1
;
2129 const decl_t decl2
= (decl_t
) automaton_decl_2
;
2131 if (decl1
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl1
)->name
== NULL
2132 || decl2
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl2
)->name
== NULL
)
2134 return strcmp (DECL_AUTOMATON (decl1
)->name
,
2135 DECL_AUTOMATON (decl2
)->name
) == 0;
2138 /* The automaton declaration table itself is represented by the
2139 following variable. */
2140 static htab_t automaton_decl_table
;
2142 /* The function inserts automaton declaration into the table. The
2143 function does nothing if an automaton declaration with the same key
2144 exists already in the table. The function returns automaton
2145 declaration node in the table with the same key as given automaton
2146 declaration node. */
2148 insert_automaton_decl (automaton_decl
)
2149 decl_t automaton_decl
;
2153 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
2154 if (*entry_ptr
== NULL
)
2155 *entry_ptr
= (void *) automaton_decl
;
2156 return (decl_t
) *entry_ptr
;
2159 /* The following variable value is node representing automaton
2160 declaration. The node used for searching automaton declaration
2162 static struct decl work_automaton_decl
;
2164 /* The function searches for automaton declaration in the table with
2165 the same key as node representing name of the automaton
2166 declaration. The function returns node found in the table, NULL if
2167 such node does not exist in the table. */
2169 find_automaton_decl (name
)
2174 work_automaton_decl
.mode
= dm_automaton
;
2175 DECL_AUTOMATON (&work_automaton_decl
)->name
= name
;
2176 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
2177 return (decl_t
) entry
;
2180 /* The function creates empty automaton declaration table and node
2181 representing automaton declaration and used for searching automaton
2182 declaration with given name. The function must be called only once
2183 before any work with the automaton declaration table. */
2185 initiate_automaton_decl_table ()
2187 work_automaton_decl
.mode
= dm_automaton
;
2188 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
2189 automaton_decl_eq_p
, (htab_del
) 0);
2192 /* The function deletes the automaton declaration table. Only call of
2193 function `initiate_automaton_decl_table' is possible immediately
2194 after this function call. */
2196 finish_automaton_decl_table ()
2198 htab_delete (automaton_decl_table
);
2203 /* This page contains abstract data `table of insn declarations'.
2204 Elements of the table is nodes representing insn declarations. Key
2205 of the table elements is name of given insn (in corresponding
2206 define_insn_reservation). Rememeber that insn names have own
2209 /* The function evaluates hash value of an insn declaration. The
2210 function is used by abstract data `hashtab'. The function returns
2211 hash value (0..UINT_MAX) of given insn declaration. */
2213 insn_decl_hash (insn_decl
)
2214 const void *insn_decl
;
2216 const decl_t decl
= (decl_t
) insn_decl
;
2218 if (decl
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl
)->name
== NULL
)
2220 return string_hash (DECL_INSN_RESERV (decl
)->name
);
2223 /* The function tests insn declarations on equality of their keys.
2224 The function is used by abstract data `hashtab'. The function
2225 returns 1 if declarations have the same key, 0 otherwise. */
2227 insn_decl_eq_p (insn_decl_1
, insn_decl_2
)
2228 const void *insn_decl_1
;
2229 const void *insn_decl_2
;
2231 const decl_t decl1
= (decl_t
) insn_decl_1
;
2232 const decl_t decl2
= (decl_t
) insn_decl_2
;
2234 if (decl1
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl1
)->name
== NULL
2235 || decl2
->mode
!= dm_insn_reserv
2236 || DECL_INSN_RESERV (decl2
)->name
== NULL
)
2238 return strcmp (DECL_INSN_RESERV (decl1
)->name
,
2239 DECL_INSN_RESERV (decl2
)->name
) == 0;
2242 /* The insn declaration table itself is represented by the following
2243 variable. The table does not contain insn reservation
2245 static htab_t insn_decl_table
;
2247 /* The function inserts insn declaration into the table. The function
2248 does nothing if an insn declaration with the same key exists
2249 already in the table. The function returns insn declaration node
2250 in the table with the same key as given insn declaration node. */
2252 insert_insn_decl (insn_decl
)
2257 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2258 if (*entry_ptr
== NULL
)
2259 *entry_ptr
= (void *) insn_decl
;
2260 return (decl_t
) *entry_ptr
;
2263 /* The following variable value is node representing insn reservation
2264 declaration. The node used for searching insn reservation
2265 declaration with given name. */
2266 static struct decl work_insn_decl
;
2268 /* The function searches for insn reservation declaration in the table
2269 with the same key as node representing name of the insn reservation
2270 declaration. The function returns node found in the table, NULL if
2271 such node does not exist in the table. */
2273 find_insn_decl (name
)
2278 work_insn_decl
.mode
= dm_insn_reserv
;
2279 DECL_INSN_RESERV (&work_insn_decl
)->name
= name
;
2280 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2281 return (decl_t
) entry
;
2284 /* The function creates empty insn declaration table and node
2285 representing insn declaration and used for searching insn
2286 declaration with given name. The function must be called only once
2287 before any work with the insn declaration table. */
2289 initiate_insn_decl_table ()
2291 work_insn_decl
.mode
= dm_insn_reserv
;
2292 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
2296 /* The function deletes the insn declaration table. Only call of
2297 function `initiate_insn_decl_table' is possible immediately after
2298 this function call. */
2300 finish_insn_decl_table ()
2302 htab_delete (insn_decl_table
);
2307 /* This page contains abstract data `table of declarations'. Elements
2308 of the table is nodes representing declarations (of units and
2309 reservations). Key of the table elements is names of given
2312 /* The function evaluates hash value of a declaration. The function
2313 is used by abstract data `hashtab'. The function returns hash
2314 value (0..UINT_MAX) of given declaration. */
2319 const decl_t d
= (const decl_t
) decl
;
2321 if ((d
->mode
!= dm_unit
|| DECL_UNIT (d
)->name
== NULL
)
2322 && (d
->mode
!= dm_reserv
|| DECL_RESERV (d
)->name
== NULL
))
2324 return string_hash (d
->mode
== dm_unit
2325 ? DECL_UNIT (d
)->name
: DECL_RESERV (d
)->name
);
2328 /* The function tests declarations on equality of their keys. The
2329 function is used by abstract data `hashtab'. The function
2330 returns 1 if the declarations have the same key, 0 otherwise. */
2332 decl_eq_p (decl_1
, decl_2
)
2336 const decl_t d1
= (const decl_t
) decl_1
;
2337 const decl_t d2
= (const decl_t
) decl_2
;
2339 if (((d1
->mode
!= dm_unit
|| DECL_UNIT (d1
)->name
== NULL
)
2340 && (d1
->mode
!= dm_reserv
|| DECL_RESERV (d1
)->name
== NULL
))
2341 || ((d2
->mode
!= dm_unit
|| DECL_UNIT (d2
)->name
== NULL
)
2342 && (d2
->mode
!= dm_reserv
|| DECL_RESERV (d2
)->name
== NULL
)))
2344 return strcmp ((d1
->mode
== dm_unit
2345 ? DECL_UNIT (d1
)->name
: DECL_RESERV (d1
)->name
),
2346 (d2
->mode
== dm_unit
2347 ? DECL_UNIT (d2
)->name
: DECL_RESERV (d2
)->name
)) == 0;
2350 /* The declaration table itself is represented by the following
2352 static htab_t decl_table
;
2354 /* The function inserts declaration into the table. The function does
2355 nothing if a declaration with the same key exists already in the
2356 table. The function returns declaration node in the table with the
2357 same key as given declaration node. */
2365 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2366 if (*entry_ptr
== NULL
)
2367 *entry_ptr
= (void *) decl
;
2368 return (decl_t
) *entry_ptr
;
2371 /* The following variable value is node representing declaration. The
2372 node used for searching declaration with given name. */
2373 static struct decl work_decl
;
2375 /* The function searches for declaration in the table with the same
2376 key as node representing name of the declaration. The function
2377 returns node found in the table, NULL if such node does not exist
2385 work_decl
.mode
= dm_unit
;
2386 DECL_UNIT (&work_decl
)->name
= name
;
2387 entry
= htab_find (decl_table
, &work_decl
);
2388 return (decl_t
) entry
;
2391 /* The function creates empty declaration table and node representing
2392 declaration and used for searching declaration with given name.
2393 The function must be called only once before any work with the
2394 declaration table. */
2396 initiate_decl_table ()
2398 work_decl
.mode
= dm_unit
;
2399 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2402 /* The function deletes the declaration table. Only call of function
2403 `initiate_declaration_table' is possible immediately after this
2406 finish_decl_table ()
2408 htab_delete (decl_table
);
2413 /* This page contains checker of pipeline hazard description. */
2415 /* Checking NAMES in an exclusion clause vector and returning formed
2416 unit_set_el_list. */
2417 static unit_set_el_t
2418 process_excls (names
, num
, excl_pos
)
2421 pos_t excl_pos ATTRIBUTE_UNUSED
;
2423 unit_set_el_t el_list
;
2424 unit_set_el_t last_el
;
2425 unit_set_el_t new_el
;
2426 decl_t decl_in_table
;
2431 for (i
= 0; i
< num
; i
++)
2433 decl_in_table
= find_decl (names
[i
]);
2434 if (decl_in_table
== NULL
)
2435 error ("unit `%s' in exclusion is not declared", names
[i
]);
2436 else if (decl_in_table
->mode
!= dm_unit
)
2437 error ("`%s' in exclusion is not unit", names
[i
]);
2440 new_el
= create_node (sizeof (struct unit_set_el
));
2441 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2442 new_el
->next_unit_set_el
= NULL
;
2443 if (last_el
== NULL
)
2444 el_list
= last_el
= new_el
;
2447 last_el
->next_unit_set_el
= new_el
;
2448 last_el
= last_el
->next_unit_set_el
;
2455 /* The function adds each element from SOURCE_LIST to the exclusion
2456 list of the each element from DEST_LIST. Checking situation "unit
2457 excludes itself". */
2459 add_excls (dest_list
, source_list
, excl_pos
)
2460 unit_set_el_t dest_list
;
2461 unit_set_el_t source_list
;
2462 pos_t excl_pos ATTRIBUTE_UNUSED
;
2466 unit_set_el_t curr_el
;
2467 unit_set_el_t prev_el
;
2470 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2471 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2473 if (dst
->unit_decl
== src
->unit_decl
)
2475 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2478 if (dst
->unit_decl
->automaton_name
!= NULL
2479 && src
->unit_decl
->automaton_name
!= NULL
2480 && strcmp (dst
->unit_decl
->automaton_name
,
2481 src
->unit_decl
->automaton_name
) != 0)
2483 error ("units `%s' and `%s' in exclusion set belong to different automata",
2484 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2487 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2489 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2490 if (curr_el
->unit_decl
== src
->unit_decl
)
2492 if (curr_el
== NULL
)
2494 /* Element not found - insert. */
2495 copy
= copy_node (src
, sizeof (*src
));
2496 copy
->next_unit_set_el
= NULL
;
2497 if (prev_el
== NULL
)
2498 dst
->unit_decl
->excl_list
= copy
;
2500 prev_el
->next_unit_set_el
= copy
;
2505 /* Checking NAMES in an presence clause vector and returning formed
2506 unit_set_el_list. The function is called only after processing all
2508 static unit_set_el_t
2509 process_presence_absence (names
, num
, req_pos
, presence_p
)
2512 pos_t req_pos ATTRIBUTE_UNUSED
;
2515 unit_set_el_t el_list
;
2516 unit_set_el_t last_el
;
2517 unit_set_el_t new_el
;
2518 decl_t decl_in_table
;
2523 for (i
= 0; i
< num
; i
++)
2525 decl_in_table
= find_decl (names
[i
]);
2526 if (decl_in_table
== NULL
)
2528 ? "unit `%s' in presence set is not declared"
2529 : "unit `%s' in absence set is not declared"), names
[i
]);
2530 else if (decl_in_table
->mode
!= dm_unit
)
2532 ? "`%s' in presence set is not unit"
2533 : "`%s' in absence set is not unit"), names
[i
]);
2536 new_el
= create_node (sizeof (struct unit_set_el
));
2537 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2538 new_el
->next_unit_set_el
= NULL
;
2539 if (last_el
== NULL
)
2540 el_list
= last_el
= new_el
;
2543 last_el
->next_unit_set_el
= new_el
;
2544 last_el
= last_el
->next_unit_set_el
;
2551 /* The function adds each element from SOURCE_LIST to presence (if
2552 PRESENCE_P) or absence list of the each element from DEST_LIST.
2553 Checking situations "unit requires own presence", "unit requires
2554 own absence", and "unit excludes and requires presence of ...".
2555 Remember that we process absence sets only after all presence
2558 add_presence_absence (dest_list
, source_list
, req_pos
, presence_p
)
2559 unit_set_el_t dest_list
;
2560 unit_set_el_t source_list
;
2561 pos_t req_pos ATTRIBUTE_UNUSED
;
2566 unit_set_el_t curr_el
;
2567 unit_set_el_t prev_el
;
2570 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2571 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2573 if (dst
->unit_decl
== src
->unit_decl
)
2576 ? "unit `%s' requires own presence"
2577 : "unit `%s' requires own absence"), src
->unit_decl
->name
);
2580 if (dst
->unit_decl
->automaton_name
!= NULL
2581 && src
->unit_decl
->automaton_name
!= NULL
2582 && strcmp (dst
->unit_decl
->automaton_name
,
2583 src
->unit_decl
->automaton_name
) != 0)
2586 ? "units `%s' and `%s' in presence set belong to different automata"
2587 : "units `%s' and `%s' in absence set belong to different automata"),
2588 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2591 for (curr_el
= (presence_p
2592 ? dst
->unit_decl
->presence_list
2593 : dst
->unit_decl
->absence_list
), prev_el
= NULL
;
2595 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2596 if (curr_el
->unit_decl
== src
->unit_decl
)
2598 if (curr_el
== NULL
)
2600 /* Element not found - insert if there is no error. */
2601 int no_error_flag
= 1;
2604 for (curr_el
= dst
->unit_decl
->excl_list
;
2606 curr_el
= curr_el
->next_unit_set_el
)
2608 if (src
->unit_decl
== curr_el
->unit_decl
)
2613 ("unit `%s' excludes and requires presence of `%s'",
2614 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2619 ("unit `%s' excludes and requires presence of `%s'",
2620 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2624 for (curr_el
= dst
->unit_decl
->presence_list
;
2626 curr_el
= curr_el
->next_unit_set_el
)
2628 if (src
->unit_decl
== curr_el
->unit_decl
)
2633 ("unit `%s' requires absence and presence of `%s'",
2634 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2639 ("unit `%s' requires absence and presence of `%s'",
2640 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2645 copy
= copy_node (src
, sizeof (*src
));
2646 copy
->next_unit_set_el
= NULL
;
2647 if (prev_el
== NULL
)
2650 dst
->unit_decl
->presence_list
= copy
;
2652 dst
->unit_decl
->absence_list
= copy
;
2655 prev_el
->next_unit_set_el
= copy
;
2661 /* The function searches for bypass with given IN_INSN_RESERV in given
2663 static struct bypass_decl
*
2664 find_bypass (bypass_list
, in_insn_reserv
)
2665 struct bypass_decl
*bypass_list
;
2666 struct insn_reserv_decl
*in_insn_reserv
;
2668 struct bypass_decl
*bypass
;
2670 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2671 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2676 /* The function processes pipeline description declarations, checks
2677 their correctness, and forms exclusion/presence/absence sets. */
2682 decl_t automaton_decl
;
2683 decl_t decl_in_table
;
2684 decl_t out_insn_reserv
;
2685 decl_t in_insn_reserv
;
2686 struct bypass_decl
*bypass
;
2687 int automaton_presence
;
2690 /* Checking repeated automata declarations. */
2691 automaton_presence
= 0;
2692 for (i
= 0; i
< description
->decls_num
; i
++)
2694 decl
= description
->decls
[i
];
2695 if (decl
->mode
== dm_automaton
)
2697 automaton_presence
= 1;
2698 decl_in_table
= insert_automaton_decl (decl
);
2699 if (decl_in_table
!= decl
)
2702 error ("repeated declaration of automaton `%s'",
2703 DECL_AUTOMATON (decl
)->name
);
2705 warning ("repeated declaration of automaton `%s'",
2706 DECL_AUTOMATON (decl
)->name
);
2710 /* Checking undeclared automata, repeated declarations (except for
2711 automata) and correctness of their attributes (insn latency times
2713 for (i
= 0; i
< description
->decls_num
; i
++)
2715 decl
= description
->decls
[i
];
2716 if (decl
->mode
== dm_insn_reserv
)
2718 DECL_INSN_RESERV (decl
)->condexp
2719 = check_attr_test (DECL_INSN_RESERV (decl
)->condexp
, 0, 0);
2720 if (DECL_INSN_RESERV (decl
)->default_latency
< 0)
2721 error ("define_insn_reservation `%s' has negative latency time",
2722 DECL_INSN_RESERV (decl
)->name
);
2723 DECL_INSN_RESERV (decl
)->insn_num
= description
->insns_num
;
2724 description
->insns_num
++;
2725 decl_in_table
= insert_insn_decl (decl
);
2726 if (decl_in_table
!= decl
)
2727 error ("`%s' is already used as insn reservation name",
2728 DECL_INSN_RESERV (decl
)->name
);
2730 else if (decl
->mode
== dm_bypass
)
2732 if (DECL_BYPASS (decl
)->latency
< 0)
2733 error ("define_bypass `%s - %s' has negative latency time",
2734 DECL_BYPASS (decl
)->out_insn_name
,
2735 DECL_BYPASS (decl
)->in_insn_name
);
2737 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2739 if (decl
->mode
== dm_unit
)
2741 DECL_UNIT (decl
)->automaton_decl
= NULL
;
2742 if (DECL_UNIT (decl
)->automaton_name
!= NULL
)
2745 = find_automaton_decl (DECL_UNIT (decl
)->automaton_name
);
2746 if (automaton_decl
== NULL
)
2747 error ("automaton `%s' is not declared",
2748 DECL_UNIT (decl
)->automaton_name
);
2751 DECL_AUTOMATON (automaton_decl
)->automaton_is_used
= 1;
2752 DECL_UNIT (decl
)->automaton_decl
2753 = DECL_AUTOMATON (automaton_decl
);
2756 else if (automaton_presence
)
2757 error ("define_unit `%s' without automaton when one defined",
2758 DECL_UNIT (decl
)->name
);
2759 DECL_UNIT (decl
)->unit_num
= description
->units_num
;
2760 description
->units_num
++;
2761 if (strcmp (DECL_UNIT (decl
)->name
, NOTHING_NAME
) == 0)
2763 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2766 decl_in_table
= find_decl (DECL_UNIT (decl
)->name
);
2770 if (strcmp (DECL_RESERV (decl
)->name
, NOTHING_NAME
) == 0)
2772 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2775 decl_in_table
= find_decl (DECL_RESERV (decl
)->name
);
2777 if (decl_in_table
== NULL
)
2778 decl_in_table
= insert_decl (decl
);
2781 if (decl
->mode
== dm_unit
)
2782 error ("repeated declaration of unit `%s'",
2783 DECL_UNIT (decl
)->name
);
2785 error ("repeated declaration of reservation `%s'",
2786 DECL_RESERV (decl
)->name
);
2790 /* Check bypasses and form list of bypasses for each (output)
2792 for (i
= 0; i
< description
->decls_num
; i
++)
2794 decl
= description
->decls
[i
];
2795 if (decl
->mode
== dm_bypass
)
2797 out_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->out_insn_name
);
2798 in_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->in_insn_name
);
2799 if (out_insn_reserv
== NULL
)
2800 error ("there is no insn reservation `%s'",
2801 DECL_BYPASS (decl
)->out_insn_name
);
2802 else if (in_insn_reserv
== NULL
)
2803 error ("there is no insn reservation `%s'",
2804 DECL_BYPASS (decl
)->in_insn_name
);
2807 DECL_BYPASS (decl
)->out_insn_reserv
2808 = DECL_INSN_RESERV (out_insn_reserv
);
2809 DECL_BYPASS (decl
)->in_insn_reserv
2810 = DECL_INSN_RESERV (in_insn_reserv
);
2812 = find_bypass (DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
,
2813 DECL_BYPASS (decl
)->in_insn_reserv
);
2816 if (DECL_BYPASS (decl
)->latency
== bypass
->latency
)
2820 ("the same bypass `%s - %s' is already defined",
2821 DECL_BYPASS (decl
)->out_insn_name
,
2822 DECL_BYPASS (decl
)->in_insn_name
);
2825 ("the same bypass `%s - %s' is already defined",
2826 DECL_BYPASS (decl
)->out_insn_name
,
2827 DECL_BYPASS (decl
)->in_insn_name
);
2830 error ("bypass `%s - %s' is already defined",
2831 DECL_BYPASS (decl
)->out_insn_name
,
2832 DECL_BYPASS (decl
)->in_insn_name
);
2836 DECL_BYPASS (decl
)->next
2837 = DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
;
2838 DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
2839 = DECL_BYPASS (decl
);
2845 /* Check exclusion set declarations and form exclussion sets. */
2846 for (i
= 0; i
< description
->decls_num
; i
++)
2848 decl
= description
->decls
[i
];
2849 if (decl
->mode
== dm_excl
)
2851 unit_set_el_t unit_set_el_list
;
2852 unit_set_el_t unit_set_el_list_2
;
2855 = process_excls (DECL_EXCL (decl
)->names
,
2856 DECL_EXCL (decl
)->first_list_length
, decl
->pos
);
2858 = process_excls (&DECL_EXCL (decl
)->names
2859 [DECL_EXCL (decl
)->first_list_length
],
2860 DECL_EXCL (decl
)->names_num
2861 - DECL_EXCL (decl
)->first_list_length
,
2863 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2864 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2868 /* Check presence set declarations and form presence sets. */
2869 for (i
= 0; i
< description
->decls_num
; i
++)
2871 decl
= description
->decls
[i
];
2872 if (decl
->mode
== dm_presence
)
2874 unit_set_el_t unit_set_el_list
;
2875 unit_set_el_t unit_set_el_list_2
;
2878 = process_presence_absence
2879 (DECL_PRESENCE (decl
)->names
,
2880 DECL_PRESENCE (decl
)->first_list_length
, decl
->pos
, 1);
2882 = process_presence_absence
2883 (&DECL_PRESENCE (decl
)->names
2884 [DECL_PRESENCE (decl
)->first_list_length
],
2885 DECL_PRESENCE (decl
)->names_num
2886 - DECL_PRESENCE (decl
)->first_list_length
,
2888 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2893 /* Check absence set declarations and form absence sets. */
2894 for (i
= 0; i
< description
->decls_num
; i
++)
2896 decl
= description
->decls
[i
];
2897 if (decl
->mode
== dm_absence
)
2899 unit_set_el_t unit_set_el_list
;
2900 unit_set_el_t unit_set_el_list_2
;
2903 = process_presence_absence
2904 (DECL_ABSENCE (decl
)->names
,
2905 DECL_ABSENCE (decl
)->first_list_length
, decl
->pos
, 0);
2907 = process_presence_absence
2908 (&DECL_ABSENCE (decl
)->names
2909 [DECL_ABSENCE (decl
)->first_list_length
],
2910 DECL_ABSENCE (decl
)->names_num
2911 - DECL_ABSENCE (decl
)->first_list_length
,
2913 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2919 /* The following function checks that declared automaton is used. If
2920 the automaton is not used, the function fixes error/warning. The
2921 following function must be called only after `process_decls'. */
2923 check_automaton_usage ()
2928 for (i
= 0; i
< description
->decls_num
; i
++)
2930 decl
= description
->decls
[i
];
2931 if (decl
->mode
== dm_automaton
2932 && !DECL_AUTOMATON (decl
)->automaton_is_used
)
2935 error ("automaton `%s' is not used", DECL_AUTOMATON (decl
)->name
);
2937 warning ("automaton `%s' is not used",
2938 DECL_AUTOMATON (decl
)->name
);
2943 /* The following recursive function processes all regexp in order to
2944 fix usage of units or reservations and to fix errors of undeclared
2945 name. The function may change unit_regexp onto reserv_regexp.
2946 Remember that reserv_regexp does not exist before the function
2949 process_regexp (regexp
)
2952 decl_t decl_in_table
;
2953 regexp_t new_regexp
;
2956 if (regexp
->mode
== rm_unit
)
2958 decl_in_table
= find_decl (REGEXP_UNIT (regexp
)->name
);
2959 if (decl_in_table
== NULL
)
2960 error ("undeclared unit or reservation `%s'",
2961 REGEXP_UNIT (regexp
)->name
);
2962 else if (decl_in_table
->mode
== dm_unit
)
2964 DECL_UNIT (decl_in_table
)->unit_is_used
= 1;
2965 REGEXP_UNIT (regexp
)->unit_decl
= DECL_UNIT (decl_in_table
);
2967 else if (decl_in_table
->mode
== dm_reserv
)
2969 DECL_RESERV (decl_in_table
)->reserv_is_used
= 1;
2970 new_regexp
= create_node (sizeof (struct regexp
));
2971 new_regexp
->mode
= rm_reserv
;
2972 new_regexp
->pos
= regexp
->pos
;
2973 REGEXP_RESERV (new_regexp
)->name
= REGEXP_UNIT (regexp
)->name
;
2974 REGEXP_RESERV (new_regexp
)->reserv_decl
2975 = DECL_RESERV (decl_in_table
);
2976 regexp
= new_regexp
;
2981 else if (regexp
->mode
== rm_sequence
)
2982 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
2983 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
2984 = process_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
2985 else if (regexp
->mode
== rm_allof
)
2986 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
2987 REGEXP_ALLOF (regexp
)->regexps
[i
]
2988 = process_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
2989 else if (regexp
->mode
== rm_oneof
)
2990 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
2991 REGEXP_ONEOF (regexp
)->regexps
[i
]
2992 = process_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
2993 else if (regexp
->mode
== rm_repeat
)
2994 REGEXP_REPEAT (regexp
)->regexp
2995 = process_regexp (REGEXP_REPEAT (regexp
)->regexp
);
2996 else if (regexp
->mode
!= rm_nothing
)
3001 /* The following function processes regexp of define_reservation and
3002 define_insn_reservation with the aid of function
3003 `process_regexp'. */
3005 process_regexp_decls ()
3010 for (i
= 0; i
< description
->decls_num
; i
++)
3012 decl
= description
->decls
[i
];
3013 if (decl
->mode
== dm_reserv
)
3014 DECL_RESERV (decl
)->regexp
3015 = process_regexp (DECL_RESERV (decl
)->regexp
);
3016 else if (decl
->mode
== dm_insn_reserv
)
3017 DECL_INSN_RESERV (decl
)->regexp
3018 = process_regexp (DECL_INSN_RESERV (decl
)->regexp
);
3022 /* The following function checks that declared unit is used. If the
3023 unit is not used, the function fixes errors/warnings. The
3024 following function must be called only after `process_decls',
3025 `process_regexp_decls'. */
3032 for (i
= 0; i
< description
->decls_num
; i
++)
3034 decl
= description
->decls
[i
];
3035 if (decl
->mode
== dm_unit
&& !DECL_UNIT (decl
)->unit_is_used
)
3038 error ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3040 warning ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3042 else if (decl
->mode
== dm_reserv
&& !DECL_RESERV (decl
)->reserv_is_used
)
3045 error ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3047 warning ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3052 /* The following variable value is number of reservation being
3053 processed on loop recognition. */
3054 static int curr_loop_pass_num
;
3056 /* The following recursive function returns nonzero value if REGEXP
3057 contains given decl or reservations in given regexp refers for
3060 loop_in_regexp (regexp
, start_decl
)
3068 if (regexp
->mode
== rm_unit
)
3070 else if (regexp
->mode
== rm_reserv
)
3072 if (start_decl
->mode
== dm_reserv
3073 && REGEXP_RESERV (regexp
)->reserv_decl
== DECL_RESERV (start_decl
))
3075 else if (REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3076 == curr_loop_pass_num
)
3077 /* declaration has been processed. */
3081 REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3082 = curr_loop_pass_num
;
3083 return loop_in_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3087 else if (regexp
->mode
== rm_sequence
)
3089 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3090 if (loop_in_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
], start_decl
))
3094 else if (regexp
->mode
== rm_allof
)
3096 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3097 if (loop_in_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
], start_decl
))
3101 else if (regexp
->mode
== rm_oneof
)
3103 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3104 if (loop_in_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
], start_decl
))
3108 else if (regexp
->mode
== rm_repeat
)
3109 return loop_in_regexp (REGEXP_REPEAT (regexp
)->regexp
, start_decl
);
3112 if (regexp
->mode
!= rm_nothing
)
3118 /* The following function fixes errors "cycle in definition ...". The
3119 function uses function `loop_in_regexp' for that. */
3121 check_loops_in_regexps ()
3126 for (i
= 0; i
< description
->decls_num
; i
++)
3128 decl
= description
->decls
[i
];
3129 if (decl
->mode
== dm_reserv
)
3130 DECL_RESERV (decl
)->loop_pass_num
= 0;
3132 for (i
= 0; i
< description
->decls_num
; i
++)
3134 decl
= description
->decls
[i
];
3135 curr_loop_pass_num
= i
;
3137 if (decl
->mode
== dm_reserv
)
3139 DECL_RESERV (decl
)->loop_pass_num
= curr_loop_pass_num
;
3140 if (loop_in_regexp (DECL_RESERV (decl
)->regexp
, decl
))
3142 if (DECL_RESERV (decl
)->regexp
== NULL
)
3144 error ("cycle in definition of reservation `%s'",
3145 DECL_RESERV (decl
)->name
);
3151 /* The function recursively processes IR of reservation and defines
3152 max and min cycle for reservation of unit and for result in the
3155 process_regexp_cycles (regexp
, start_cycle
)
3161 if (regexp
->mode
== rm_unit
)
3163 if (REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
< start_cycle
)
3164 REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
= start_cycle
;
3167 else if (regexp
->mode
== rm_reserv
)
3168 return process_regexp_cycles (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3170 else if (regexp
->mode
== rm_repeat
)
3172 for (i
= 0; i
< REGEXP_REPEAT (regexp
)->repeat_num
; i
++)
3173 start_cycle
= process_regexp_cycles (REGEXP_REPEAT (regexp
)->regexp
,
3177 else if (regexp
->mode
== rm_sequence
)
3179 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3181 = process_regexp_cycles (REGEXP_SEQUENCE (regexp
)->regexps
[i
],
3185 else if (regexp
->mode
== rm_allof
)
3187 int finish_cycle
= 0;
3190 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3192 cycle
= process_regexp_cycles (REGEXP_ALLOF (regexp
)->regexps
[i
],
3194 if (finish_cycle
< cycle
)
3195 finish_cycle
= cycle
;
3197 return finish_cycle
;
3199 else if (regexp
->mode
== rm_oneof
)
3201 int finish_cycle
= 0;
3204 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3206 cycle
= process_regexp_cycles (REGEXP_ONEOF (regexp
)->regexps
[i
],
3208 if (finish_cycle
< cycle
)
3209 finish_cycle
= cycle
;
3211 return finish_cycle
;
3215 if (regexp
->mode
!= rm_nothing
)
3221 /* The following function is called only for correct program. The
3222 function defines max reservation of insns in cycles. */
3224 evaluate_max_reserv_cycles ()
3226 int max_insn_cycles_num
;
3230 description
->max_insn_reserv_cycles
= 0;
3231 for (i
= 0; i
< description
->decls_num
; i
++)
3233 decl
= description
->decls
[i
];
3234 if (decl
->mode
== dm_insn_reserv
)
3237 = process_regexp_cycles (DECL_INSN_RESERV (decl
)->regexp
, 0);
3238 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3239 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3242 description
->max_insn_reserv_cycles
++;
3245 /* The following function calls functions for checking all
3248 check_all_description ()
3251 check_automaton_usage ();
3252 process_regexp_decls ();
3254 check_loops_in_regexps ();
3256 evaluate_max_reserv_cycles ();
3261 /* The page contains abstract data `ticker'. This data is used to
3262 report time of different phases of building automata. It is
3263 possibly to write a description for which automata will be built
3264 during several minutes even on fast machine. */
3266 /* The following function creates ticker and makes it active. */
3272 ticker
.modified_creation_time
= get_run_time ();
3273 ticker
.incremented_off_time
= 0;
3277 /* The following function switches off given ticker. */
3282 if (ticker
->incremented_off_time
== 0)
3283 ticker
->incremented_off_time
= get_run_time () + 1;
3286 /* The following function switches on given ticker. */
3291 if (ticker
->incremented_off_time
!= 0)
3293 ticker
->modified_creation_time
3294 += get_run_time () - ticker
->incremented_off_time
+ 1;
3295 ticker
->incremented_off_time
= 0;
3299 /* The following function returns current time in milliseconds since
3300 the moment when given ticker was created. */
3302 active_time (ticker
)
3305 if (ticker
.incremented_off_time
!= 0)
3306 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3308 return get_run_time () - ticker
.modified_creation_time
;
3311 /* The following function returns string representation of active time
3312 of given ticker. The result is string representation of seconds
3313 with accuracy of 1/100 second. Only result of the last call of the
3314 function exists. Therefore the following code is not correct
3316 printf ("parser time: %s\ngeneration time: %s\n",
3317 active_time_string (parser_ticker),
3318 active_time_string (generation_ticker));
3320 Correct code has to be the following
3322 printf ("parser time: %s\n", active_time_string (parser_ticker));
3323 printf ("generation time: %s\n",
3324 active_time_string (generation_ticker));
3328 print_active_time (f
, ticker
)
3334 msecs
= active_time (ticker
);
3335 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3340 /* The following variable value is number of automaton which are
3341 really being created. This value is defined on the base of
3342 argument of option `-split'. If the variable has zero value the
3343 number of automata is defined by the constructions `%automaton'.
3344 This case occures when option `-split' is absent or has zero
3345 argument. If constructions `define_automaton' is absent only one
3346 automaton is created. */
3347 static int automata_num
;
3349 /* The following variable values are times of
3350 o transformation of regular expressions
3351 o building NDFA (DFA if !ndfa_flag)
3352 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3354 o building insn equivalence classes
3357 static ticker_t transform_time
;
3358 static ticker_t NDFA_time
;
3359 static ticker_t NDFA_to_DFA_time
;
3360 static ticker_t minimize_time
;
3361 static ticker_t equiv_time
;
3362 static ticker_t automaton_generation_time
;
3363 static ticker_t output_time
;
3365 /* The following variable values are times of
3368 all pipeline hazard translator work */
3369 static ticker_t check_time
;
3370 static ticker_t generation_time
;
3371 static ticker_t all_time
;
3375 /* Pseudo insn decl which denotes advancing cycle. */
3376 static decl_t advance_cycle_insn_decl
;
3378 add_advance_cycle_insn_decl ()
3380 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3381 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3382 advance_cycle_insn_decl
->pos
= no_pos
;
3383 DECL_INSN_RESERV (advance_cycle_insn_decl
)->regexp
= NULL
;
3384 DECL_INSN_RESERV (advance_cycle_insn_decl
)->name
= (char *) "$advance_cycle";
3385 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
3386 = description
->insns_num
;
3387 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3388 description
->decls_num
++;
3389 description
->insns_num
++;
3394 /* Abstract data `alternative states' which reperesents
3395 nondeterministic nature of the description (see comments for
3396 structures alt_state and state). */
3398 /* List of free states. */
3399 static alt_state_t first_free_alt_state
;
3402 /* The following variables is maximal number of allocated nodes
3404 static int allocated_alt_states_num
= 0;
3407 /* The following function returns free node alt_state. It may be new
3408 allocated node or node freed eralier. */
3410 get_free_alt_state ()
3414 if (first_free_alt_state
!= NULL
)
3416 result
= first_free_alt_state
;
3417 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3422 allocated_alt_states_num
++;
3424 result
= create_node (sizeof (struct alt_state
));
3426 result
->state
= NULL
;
3427 result
->next_alt_state
= NULL
;
3428 result
->next_sorted_alt_state
= NULL
;
3432 /* The function frees node ALT_STATE. */
3434 free_alt_state (alt_state
)
3435 alt_state_t alt_state
;
3437 if (alt_state
== NULL
)
3439 alt_state
->next_alt_state
= first_free_alt_state
;
3440 first_free_alt_state
= alt_state
;
3443 /* The function frees list started with node ALT_STATE_LIST. */
3445 free_alt_states (alt_states_list
)
3446 alt_state_t alt_states_list
;
3448 alt_state_t curr_alt_state
;
3449 alt_state_t next_alt_state
;
3451 for (curr_alt_state
= alt_states_list
;
3452 curr_alt_state
!= NULL
;
3453 curr_alt_state
= next_alt_state
)
3455 next_alt_state
= curr_alt_state
->next_alt_state
;
3456 free_alt_state (curr_alt_state
);
3460 /* The function compares unique numbers of alt states. */
3462 alt_state_cmp (alt_state_ptr_1
, alt_state_ptr_2
)
3463 const void *alt_state_ptr_1
;
3464 const void *alt_state_ptr_2
;
3466 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3467 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3469 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3470 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3476 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3477 states from the list. The comparison key is alt state unique
3480 uniq_sort_alt_states (alt_states_list
)
3481 alt_state_t alt_states_list
;
3483 alt_state_t curr_alt_state
;
3484 vla_ptr_t alt_states
;
3486 size_t prev_unique_state_ind
;
3488 alt_state_t
*result_ptr
;
3490 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3491 for (curr_alt_state
= alt_states_list
;
3492 curr_alt_state
!= NULL
;
3493 curr_alt_state
= curr_alt_state
->next_alt_state
)
3494 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3495 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3496 sizeof (alt_state_t
), alt_state_cmp
);
3497 if (VLA_PTR_LENGTH (alt_states
) == 0)
3501 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3502 prev_unique_state_ind
= 0;
3503 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3504 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3506 prev_unique_state_ind
++;
3507 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3510 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3511 free_alt_state (result_ptr
[i
]);
3513 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3514 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3515 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3516 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3517 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3518 result
= *result_ptr
;
3520 VLA_PTR_DELETE (alt_states
);
3524 /* The function checks equality of alt state lists. Remember that the
3525 lists must be already sorted by the previous function. */
3527 alt_states_eq (alt_states_1
, alt_states_2
)
3528 alt_state_t alt_states_1
;
3529 alt_state_t alt_states_2
;
3531 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3532 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3534 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3535 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3537 return alt_states_1
== alt_states_2
;
3540 /* Initialization of the abstract data. */
3542 initiate_alt_states ()
3544 first_free_alt_state
= NULL
;
3547 /* Finishing work with the abstract data. */
3549 finish_alt_states ()
3555 /* The page contains macros for work with bits strings. We could use
3556 standard gcc bitmap or sbitmap but it would result in difficulties
3557 of building canadian cross. */
3559 /* Set bit number bitno in the bit string. The macro is not side
3561 #define SET_BIT(bitstring, bitno) \
3562 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3564 /* Test if bit number bitno in the bitstring is set. The macro is not
3565 side effect proof. */
3566 #define TEST_BIT(bitstring, bitno) \
3567 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3571 /* This page contains abstract data `state'. */
3573 /* Maximal length of reservations in cycles (>= 1). */
3574 static int max_cycles_num
;
3576 /* Number of set elements (see type set_el_t) needed for
3577 representation of one cycle reservation. It is depended on units
3579 static int els_in_cycle_reserv
;
3581 /* Number of set elements (see type set_el_t) needed for
3582 representation of maximal length reservation. Deterministic
3583 reservation is stored as set (bit string) of length equal to the
3584 variable value * number of bits in set_el_t. */
3585 static int els_in_reservs
;
3587 /* VLA for representation of array of pointers to unit
3589 static vla_ptr_t units_container
;
3591 /* The start address of the array. */
3592 static unit_decl_t
*units_array
;
3594 /* Empty reservation of maximal length. */
3595 static reserv_sets_t empty_reserv
;
3597 /* The state table itself is represented by the following variable. */
3598 static htab_t state_table
;
3600 /* VLA for representation of array of pointers to free nodes
3602 static vla_ptr_t free_states
;
3604 static int curr_unique_state_num
;
3607 /* The following variables is maximal number of allocated nodes
3609 static int allocated_states_num
= 0;
3612 /* Allocate new reservation set. */
3613 static reserv_sets_t
3614 alloc_empty_reserv_sets ()
3616 reserv_sets_t result
;
3618 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3619 result
= (reserv_sets_t
) obstack_base (&irp
);
3620 obstack_finish (&irp
);
3621 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3625 /* Hash value of reservation set. */
3627 reserv_sets_hash_value (reservs
)
3628 reserv_sets_t reservs
;
3630 set_el_t hash_value
;
3633 set_el_t
*reserv_ptr
;
3636 reservs_num
= els_in_reservs
;
3637 reserv_ptr
= reservs
;
3639 while (reservs_num
!= 0)
3642 hash_value
+= ((*reserv_ptr
>> i
)
3643 | (*reserv_ptr
<< (sizeof (set_el_t
) * CHAR_BIT
- i
)));
3645 if (i
== sizeof (set_el_t
) * CHAR_BIT
)
3649 if (sizeof (set_el_t
) <= sizeof (unsigned))
3652 for (i
= sizeof (set_el_t
); i
> 0; i
-= sizeof (unsigned) - 1)
3654 result
+= (unsigned) hash_value
;
3655 hash_value
>>= (sizeof (unsigned) - 1) * CHAR_BIT
;
3660 /* Comparison of given reservation sets. */
3662 reserv_sets_cmp (reservs_1
, reservs_2
)
3663 reserv_sets_t reservs_1
;
3664 reserv_sets_t reservs_2
;
3667 set_el_t
*reserv_ptr_1
;
3668 set_el_t
*reserv_ptr_2
;
3670 if (reservs_1
== NULL
|| reservs_2
== NULL
)
3672 reservs_num
= els_in_reservs
;
3673 reserv_ptr_1
= reservs_1
;
3674 reserv_ptr_2
= reservs_2
;
3675 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3681 if (reservs_num
== 0)
3683 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3689 /* The function checks equality of the reservation sets. */
3691 reserv_sets_eq (reservs_1
, reservs_2
)
3692 reserv_sets_t reservs_1
;
3693 reserv_sets_t reservs_2
;
3695 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3698 /* Set up in the reservation set that unit with UNIT_NUM is used on
3701 set_unit_reserv (reservs
, cycle_num
, unit_num
)
3702 reserv_sets_t reservs
;
3706 if (cycle_num
>= max_cycles_num
)
3708 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3709 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3712 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3713 used on CYCLE_NUM. */
3715 test_unit_reserv (reservs
, cycle_num
, unit_num
)
3716 reserv_sets_t reservs
;
3720 if (cycle_num
>= max_cycles_num
)
3722 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3723 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3726 /* The function checks that the reservation set represents no one unit
3729 it_is_empty_reserv_sets (operand
)
3730 reserv_sets_t operand
;
3732 set_el_t
*reserv_ptr
;
3735 if (operand
== NULL
)
3737 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3739 reserv_ptr
++, reservs_num
--)
3740 if (*reserv_ptr
!= 0)
3745 /* The function checks that the reservation sets are intersected,
3746 i.e. there is a unit reservation on a cycle in both reservation
3749 reserv_sets_are_intersected (operand_1
, operand_2
)
3750 reserv_sets_t operand_1
;
3751 reserv_sets_t operand_2
;
3755 set_el_t
*cycle_ptr_1
;
3756 set_el_t
*cycle_ptr_2
;
3759 if (operand_1
== NULL
|| operand_2
== NULL
)
3761 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3762 el_ptr_1
< operand_1
+ els_in_reservs
;
3763 el_ptr_1
++, el_ptr_2
++)
3764 if (*el_ptr_1
& *el_ptr_2
)
3766 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3767 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3768 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3770 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3771 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3772 el_ptr_1
++, el_ptr_2
++)
3773 if (*el_ptr_1
& *el_ptr_2
)
3776 for (el_ptr_1
= cycle_ptr_1
,
3777 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 1);
3778 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3779 el_ptr_1
++, el_ptr_2
++)
3780 if (*el_ptr_1
& *el_ptr_2
)
3782 else if (*el_ptr_2
!= 0)
3784 if (nonzero_p
&& el_ptr_1
>= cycle_ptr_1
+ els_in_cycle_reserv
)
3786 for (el_ptr_1
= cycle_ptr_1
,
3787 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 0);
3788 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3789 el_ptr_1
++, el_ptr_2
++)
3790 /* It looks like code for exclusion but exclusion set is
3791 made as symmetric relation preliminary. */
3792 if (*el_ptr_1
& *el_ptr_2
)
3798 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3799 cpu cycle. The remaining bits of OPERAND (representing the last
3800 cycle unit reservations) are not chenged. */
3802 reserv_sets_shift (result
, operand
)
3803 reserv_sets_t result
;
3804 reserv_sets_t operand
;
3808 if (result
== NULL
|| operand
== NULL
|| result
== operand
)
3810 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3811 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3814 /* OR of the reservation sets. */
3816 reserv_sets_or (result
, operand_1
, operand_2
)
3817 reserv_sets_t result
;
3818 reserv_sets_t operand_1
;
3819 reserv_sets_t operand_2
;
3823 set_el_t
*result_set_el_ptr
;
3825 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3827 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3828 el_ptr_1
< operand_1
+ els_in_reservs
;
3829 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3830 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3833 /* AND of the reservation sets. */
3835 reserv_sets_and (result
, operand_1
, operand_2
)
3836 reserv_sets_t result
;
3837 reserv_sets_t operand_1
;
3838 reserv_sets_t operand_2
;
3842 set_el_t
*result_set_el_ptr
;
3844 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3846 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3847 el_ptr_1
< operand_1
+ els_in_reservs
;
3848 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3849 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3852 /* The function outputs string representation of units reservation on
3853 cycle START_CYCLE in the reservation set. The function uses repeat
3854 construction if REPETITION_NUM > 1. */
3856 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
)
3858 reserv_sets_t reservs
;
3863 int reserved_units_num
;
3865 reserved_units_num
= 0;
3866 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3867 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3868 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3869 reserved_units_num
++;
3870 if (repetition_num
<= 0)
3872 if (repetition_num
!= 1 && reserved_units_num
> 1)
3874 reserved_units_num
= 0;
3876 unit_num
< description
->units_num
;
3878 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3879 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3881 if (reserved_units_num
!= 0)
3883 reserved_units_num
++;
3884 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3886 if (reserved_units_num
== 0)
3887 fprintf (f
, NOTHING_NAME
);
3888 if (repetition_num
<= 0)
3890 if (reserved_units_num
> 1)
3892 if (repetition_num
!= 1)
3893 fprintf (f
, "*%d", repetition_num
);
3896 /* The function outputs string representation of units reservation in
3897 the reservation set. */
3899 output_reserv_sets (f
, reservs
)
3901 reserv_sets_t reservs
;
3903 int start_cycle
= 0;
3908 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
3909 if (repetition_num
== 0)
3912 start_cycle
= cycle
;
3915 ((char *) reservs
+ start_cycle
* els_in_cycle_reserv
3916 * sizeof (set_el_t
),
3917 (char *) reservs
+ cycle
* els_in_cycle_reserv
3918 * sizeof (set_el_t
),
3919 els_in_cycle_reserv
* sizeof (set_el_t
)) == 0)
3923 if (start_cycle
!= 0)
3925 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3927 start_cycle
= cycle
;
3929 if (start_cycle
< max_cycles_num
)
3931 if (start_cycle
!= 0)
3933 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3937 /* The following function returns free node state for AUTOMATON. It
3938 may be new allocated node or node freed eralier. The function also
3939 allocates reservation set if WITH_RESERVS has nonzero value. */
3941 get_free_state (with_reservs
, automaton
)
3943 automaton_t automaton
;
3947 if (max_cycles_num
<= 0 || automaton
== NULL
)
3949 if (VLA_PTR_LENGTH (free_states
) != 0)
3951 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
3952 VLA_PTR_SHORTEN (free_states
, 1);
3953 result
->automaton
= automaton
;
3954 result
->first_out_arc
= NULL
;
3955 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
3956 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
3957 result
->component_states
= NULL
;
3958 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3963 allocated_states_num
++;
3965 result
= create_node (sizeof (struct state
));
3966 result
->automaton
= automaton
;
3967 result
->first_out_arc
= NULL
;
3968 result
->unique_num
= curr_unique_state_num
;
3969 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3970 curr_unique_state_num
++;
3974 if (result
->reservs
== NULL
)
3975 result
->reservs
= alloc_empty_reserv_sets ();
3977 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
3982 /* The function frees node STATE. */
3987 free_alt_states (state
->component_states
);
3988 VLA_PTR_ADD (free_states
, state
);
3991 /* Hash value of STATE. If STATE represents deterministic state it is
3992 simply hash value of the corresponding reservation set. Otherwise
3993 it is formed from hash values of the component deterministic
3994 states. One more key is order number of state automaton. */
3999 unsigned int hash_value
;
4000 alt_state_t alt_state
;
4002 if (((state_t
) state
)->component_states
== NULL
)
4003 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
4007 for (alt_state
= ((state_t
) state
)->component_states
;
4009 alt_state
= alt_state
->next_sorted_alt_state
)
4010 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4011 | (hash_value
<< CHAR_BIT
))
4012 + alt_state
->state
->unique_num
);
4014 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4015 | (hash_value
<< CHAR_BIT
))
4016 + ((state_t
) state
)->automaton
->automaton_order_num
);
4020 /* Return nonzero value if the states are the same. */
4022 state_eq_p (state_1
, state_2
)
4023 const void *state_1
;
4024 const void *state_2
;
4026 alt_state_t alt_state_1
;
4027 alt_state_t alt_state_2
;
4029 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
4031 else if (((state_t
) state_1
)->component_states
== NULL
4032 && ((state_t
) state_2
)->component_states
== NULL
)
4033 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
4034 ((state_t
) state_2
)->reservs
);
4035 else if (((state_t
) state_1
)->component_states
!= NULL
4036 && ((state_t
) state_2
)->component_states
!= NULL
)
4038 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
4039 alt_state_2
= ((state_t
) state_2
)->component_states
;
4040 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
4041 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
4042 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
4043 /* All state in the list must be already in the hash table.
4044 Also the lists must be sorted. */
4045 if (alt_state_1
->state
!= alt_state_2
->state
)
4047 return alt_state_1
== alt_state_2
;
4053 /* Insert STATE into the state table. */
4055 insert_state (state
)
4060 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
4061 if (*entry_ptr
== NULL
)
4062 *entry_ptr
= (void *) state
;
4063 return (state_t
) *entry_ptr
;
4066 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4067 deterministic STATE. */
4069 set_state_reserv (state
, cycle_num
, unit_num
)
4074 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
4077 /* Return nonzero value if the deterministic states contains a
4078 reservation of the same cpu unit on the same cpu cycle. */
4080 intersected_state_reservs_p (state1
, state2
)
4084 if (state1
->automaton
!= state2
->automaton
)
4086 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
4089 /* Return deterministic state (inserted into the table) which
4090 representing the automaton state whic is union of reservations of
4091 deterministic states. */
4093 states_union (state1
, state2
)
4098 state_t state_in_table
;
4100 if (state1
->automaton
!= state2
->automaton
)
4102 result
= get_free_state (1, state1
->automaton
);
4103 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
4104 state_in_table
= insert_state (result
);
4105 if (result
!= state_in_table
)
4107 free_state (result
);
4108 result
= state_in_table
;
4113 /* Return deterministic state (inserted into the table) which
4114 represent the automaton state is obtained from deterministic STATE
4115 by advancing cpu cycle. */
4121 state_t state_in_table
;
4123 result
= get_free_state (1, state
->automaton
);
4124 reserv_sets_shift (result
->reservs
, state
->reservs
);
4125 state_in_table
= insert_state (result
);
4126 if (result
!= state_in_table
)
4128 free_state (result
);
4129 result
= state_in_table
;
4134 /* Initialization of the abstract data. */
4141 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
4143 = (description
->decls_num
&& description
->units_num
4144 ? VLA_PTR_BEGIN (units_container
) : NULL
);
4145 for (i
= 0; i
< description
->decls_num
; i
++)
4147 decl
= description
->decls
[i
];
4148 if (decl
->mode
== dm_unit
)
4149 units_array
[DECL_UNIT (decl
)->unit_num
] = DECL_UNIT (decl
);
4151 max_cycles_num
= description
->max_insn_reserv_cycles
;
4153 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
4154 / (sizeof (set_el_t
) * CHAR_BIT
));
4155 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
4156 curr_unique_state_num
= 0;
4157 initiate_alt_states ();
4158 VLA_PTR_CREATE (free_states
, 1500, "free states");
4159 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
4160 empty_reserv
= alloc_empty_reserv_sets ();
4163 /* Finisging work with the abstract data. */
4167 VLA_PTR_DELETE (units_container
);
4168 htab_delete (state_table
);
4169 VLA_PTR_DELETE (free_states
);
4170 finish_alt_states ();
4175 /* Abstract data `arcs'. */
4177 /* List of free arcs. */
4178 static arc_t first_free_arc
;
4181 /* The following variables is maximal number of allocated nodes
4183 static int allocated_arcs_num
= 0;
4186 /* The function frees node ARC. */
4191 arc
->next_out_arc
= first_free_arc
;
4192 first_free_arc
= arc
;
4195 /* The function removes and frees ARC staring from FROM_STATE. */
4197 remove_arc (from_state
, arc
)
4206 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
4208 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
4209 if (curr_arc
== arc
)
4211 if (curr_arc
== NULL
)
4213 if (prev_arc
== NULL
)
4214 from_state
->first_out_arc
= arc
->next_out_arc
;
4216 prev_arc
->next_out_arc
= arc
->next_out_arc
;
4220 /* The functions returns arc with given characteristics (or NULL if
4221 the arc does not exist). */
4223 find_arc (from_state
, to_state
, insn
)
4230 for (arc
= first_out_arc (from_state
); arc
!= NULL
; arc
= next_out_arc (arc
))
4231 if (arc
->to_state
== to_state
&& arc
->insn
== insn
)
4236 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4237 and with given STATE_ALTS. The function returns added arc (or
4238 already existing arc). */
4240 add_arc (from_state
, to_state
, ainsn
, state_alts
)
4248 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4249 if (new_arc
!= NULL
)
4251 if (first_free_arc
== NULL
)
4254 allocated_arcs_num
++;
4256 new_arc
= create_node (sizeof (struct arc
));
4257 new_arc
->to_state
= NULL
;
4258 new_arc
->insn
= NULL
;
4259 new_arc
->next_out_arc
= NULL
;
4263 new_arc
= first_free_arc
;
4264 first_free_arc
= first_free_arc
->next_out_arc
;
4266 new_arc
->to_state
= to_state
;
4267 new_arc
->insn
= ainsn
;
4268 ainsn
->arc_exists_p
= 1;
4269 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4270 from_state
->first_out_arc
= new_arc
;
4271 new_arc
->next_arc_marked_by_insn
= NULL
;
4272 new_arc
->state_alts
= state_alts
;
4276 /* The function returns the first arc starting from STATE. */
4278 first_out_arc (state
)
4281 return state
->first_out_arc
;
4284 /* The function returns next out arc after ARC. */
4289 return arc
->next_out_arc
;
4292 /* Initialization of the abstract data. */
4296 first_free_arc
= NULL
;
4299 /* Finishing work with the abstract data. */
4307 /* Abstract data `automata lists'. */
4309 /* List of free states. */
4310 static automata_list_el_t first_free_automata_list_el
;
4312 /* The list being formed. */
4313 static automata_list_el_t current_automata_list
;
4315 /* Hash table of automata lists. */
4316 static htab_t automata_list_table
;
4318 /* The following function returns free automata list el. It may be
4319 new allocated node or node freed earlier. */
4320 static automata_list_el_t
4321 get_free_automata_list_el ()
4323 automata_list_el_t result
;
4325 if (first_free_automata_list_el
!= NULL
)
4327 result
= first_free_automata_list_el
;
4328 first_free_automata_list_el
4329 = first_free_automata_list_el
->next_automata_list_el
;
4332 result
= create_node (sizeof (struct automata_list_el
));
4333 result
->automaton
= NULL
;
4334 result
->next_automata_list_el
= NULL
;
4338 /* The function frees node AUTOMATA_LIST_EL. */
4340 free_automata_list_el (automata_list_el
)
4341 automata_list_el_t automata_list_el
;
4343 if (automata_list_el
== NULL
)
4345 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4346 first_free_automata_list_el
= automata_list_el
;
4349 /* The function frees list AUTOMATA_LIST. */
4351 free_automata_list (automata_list
)
4352 automata_list_el_t automata_list
;
4354 automata_list_el_t curr_automata_list_el
;
4355 automata_list_el_t next_automata_list_el
;
4357 for (curr_automata_list_el
= automata_list
;
4358 curr_automata_list_el
!= NULL
;
4359 curr_automata_list_el
= next_automata_list_el
)
4361 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4362 free_automata_list_el (curr_automata_list_el
);
4366 /* Hash value of AUTOMATA_LIST. */
4368 automata_list_hash (automata_list
)
4369 const void *automata_list
;
4371 unsigned int hash_value
;
4372 automata_list_el_t curr_automata_list_el
;
4375 for (curr_automata_list_el
= (automata_list_el_t
) automata_list
;
4376 curr_automata_list_el
!= NULL
;
4377 curr_automata_list_el
= curr_automata_list_el
->next_automata_list_el
)
4378 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4379 | (hash_value
<< CHAR_BIT
))
4380 + curr_automata_list_el
->automaton
->automaton_order_num
);
4384 /* Return nonzero value if the automata_lists are the same. */
4386 automata_list_eq_p (automata_list_1
, automata_list_2
)
4387 const void *automata_list_1
;
4388 const void *automata_list_2
;
4390 automata_list_el_t automata_list_el_1
;
4391 automata_list_el_t automata_list_el_2
;
4393 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4394 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4395 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4396 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4397 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4398 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4400 return automata_list_el_1
== automata_list_el_2
;
4403 /* Initialization of the abstract data. */
4405 initiate_automata_lists ()
4407 first_free_automata_list_el
= NULL
;
4408 automata_list_table
= htab_create (1500, automata_list_hash
,
4409 automata_list_eq_p
, (htab_del
) 0);
4412 /* The following function starts new automata list and makes it the
4415 automata_list_start ()
4417 current_automata_list
= NULL
;
4420 /* The following function adds AUTOMATON to the current list. */
4422 automata_list_add (automaton
)
4423 automaton_t automaton
;
4425 automata_list_el_t el
;
4427 el
= get_free_automata_list_el ();
4428 el
->automaton
= automaton
;
4429 el
->next_automata_list_el
= current_automata_list
;
4430 current_automata_list
= el
;
4433 /* The following function finishes forming the current list, inserts
4434 it into the table and returns it. */
4435 static automata_list_el_t
4436 automata_list_finish ()
4440 if (current_automata_list
== NULL
)
4442 entry_ptr
= htab_find_slot (automata_list_table
,
4443 (void *) current_automata_list
, 1);
4444 if (*entry_ptr
== NULL
)
4445 *entry_ptr
= (void *) current_automata_list
;
4447 free_automata_list (current_automata_list
);
4448 current_automata_list
= NULL
;
4449 return (automata_list_el_t
) *entry_ptr
;
4452 /* Finishing work with the abstract data. */
4454 finish_automata_lists ()
4456 htab_delete (automata_list_table
);
4461 /* The page contains abstract data for work with exclusion sets (see
4462 exclusion_set in file rtl.def). */
4464 /* The following variable refers to an exclusion set returned by
4465 get_excl_set. This is bit string of length equal to cpu units
4466 number. If exclusion set for given unit contains 1 for a unit,
4467 then simultaneous reservation of the units is prohibited. */
4468 static reserv_sets_t excl_set
;
4470 /* The array contains exclusion sets for each unit. */
4471 static reserv_sets_t
*unit_excl_set_table
;
4473 /* The following function forms the array containing exclusion sets
4476 initiate_excl_sets ()
4479 reserv_sets_t unit_excl_set
;
4483 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4484 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4485 obstack_finish (&irp
);
4486 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4487 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4488 obstack_finish (&irp
);
4489 /* Evaluate unit exclusion sets. */
4490 for (i
= 0; i
< description
->decls_num
; i
++)
4492 decl
= description
->decls
[i
];
4493 if (decl
->mode
== dm_unit
)
4495 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4496 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4497 obstack_finish (&irp
);
4498 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4499 for (el
= DECL_UNIT (decl
)->excl_list
;
4501 el
= el
->next_unit_set_el
)
4502 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4503 unit_excl_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_excl_set
;
4508 /* The function sets up and return EXCL_SET which is union of
4509 exclusion sets for each unit in IN_SET. */
4510 static reserv_sets_t
4511 get_excl_set (in_set
)
4512 reserv_sets_t in_set
;
4520 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4521 memset (excl_set
, 0, chars_num
);
4522 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4523 if (((unsigned char *) in_set
) [excl_char_num
])
4524 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4525 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4527 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4528 if (start_unit_num
>= description
->units_num
)
4530 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4533 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4541 /* The page contains abstract data for work with presence/absence sets
4542 (see presence_set/absence_set in file rtl.def). */
4544 /* The following variables refer to correspondingly an presence and an
4545 absence set returned by get_presence_absence_set. This is bit
4546 string of length equal to cpu units number. */
4547 static reserv_sets_t presence_set
, absence_set
;
4549 /* The following arrays contain correspondingly presence and absence
4550 sets for each unit. */
4551 static reserv_sets_t
*unit_presence_set_table
, *unit_absence_set_table
;
4553 /* The following function forms the array containing presence and
4554 absence sets for each unit */
4556 initiate_presence_absence_sets ()
4559 reserv_sets_t unit_set
;
4563 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4564 presence_set
= (reserv_sets_t
) obstack_base (&irp
);
4565 obstack_finish (&irp
);
4566 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4567 unit_presence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4568 obstack_finish (&irp
);
4569 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4570 absence_set
= (reserv_sets_t
) obstack_base (&irp
);
4571 obstack_finish (&irp
);
4572 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4573 unit_absence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4574 obstack_finish (&irp
);
4575 /* Evaluate unit presence/absence sets. */
4576 for (i
= 0; i
< description
->decls_num
; i
++)
4578 decl
= description
->decls
[i
];
4579 if (decl
->mode
== dm_unit
)
4581 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4582 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4583 obstack_finish (&irp
);
4584 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4585 for (el
= DECL_UNIT (decl
)->presence_list
;
4587 el
= el
->next_unit_set_el
)
4588 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4589 unit_presence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4591 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4592 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4593 obstack_finish (&irp
);
4594 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4595 for (el
= DECL_UNIT (decl
)->absence_list
;
4597 el
= el
->next_unit_set_el
)
4598 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4599 unit_absence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4604 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4605 ABSENCE_SET which is union of corresponding sets for each unit in
4607 static reserv_sets_t
4608 get_presence_absence_set (in_set
, presence_p
)
4609 reserv_sets_t in_set
;
4618 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4620 memset (presence_set
, 0, chars_num
);
4622 memset (absence_set
, 0, chars_num
);
4623 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4624 if (((unsigned char *) in_set
) [char_num
])
4625 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4626 if ((((unsigned char *) in_set
) [char_num
] >> i
) & 1)
4628 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4629 if (start_unit_num
>= description
->units_num
)
4630 return (presence_p
? presence_set
: absence_set
);
4631 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4633 presence_set
[unit_num
]
4634 |= unit_presence_set_table
[start_unit_num
] [unit_num
];
4636 absence_set
[unit_num
]
4637 |= unit_absence_set_table
[start_unit_num
] [unit_num
];
4639 return (presence_p
? presence_set
: absence_set
);
4644 /* This page contains code for transformation of original reservations
4645 described in .md file. The main goal of transformations is
4646 simplifying reservation and lifting up all `|' on the top of IR
4647 reservation representation. */
4650 /* The following function makes copy of IR representation of
4651 reservation. The function also substitutes all reservations
4652 defined by define_reservation by corresponding value during making
4655 copy_insn_regexp (regexp
)
4661 if (regexp
->mode
== rm_reserv
)
4662 result
= copy_insn_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
);
4663 else if (regexp
->mode
== rm_unit
)
4664 result
= copy_node (regexp
, sizeof (struct regexp
));
4665 else if (regexp
->mode
== rm_repeat
)
4667 result
= copy_node (regexp
, sizeof (struct regexp
));
4668 REGEXP_REPEAT (result
)->regexp
4669 = copy_insn_regexp (REGEXP_REPEAT (regexp
)->regexp
);
4671 else if (regexp
->mode
== rm_sequence
)
4673 result
= copy_node (regexp
,
4674 sizeof (struct regexp
) + sizeof (regexp_t
)
4675 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4676 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4677 REGEXP_SEQUENCE (result
)->regexps
[i
]
4678 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4680 else if (regexp
->mode
== rm_allof
)
4682 result
= copy_node (regexp
,
4683 sizeof (struct regexp
) + sizeof (regexp_t
)
4684 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4685 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4686 REGEXP_ALLOF (result
)->regexps
[i
]
4687 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4689 else if (regexp
->mode
== rm_oneof
)
4691 result
= copy_node (regexp
,
4692 sizeof (struct regexp
) + sizeof (regexp_t
)
4693 * (REGEXP_ONEOF (regexp
)->regexps_num
- 1));
4694 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4695 REGEXP_ONEOF (result
)->regexps
[i
]
4696 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4700 if (regexp
->mode
!= rm_nothing
)
4702 result
= copy_node (regexp
, sizeof (struct regexp
));
4707 /* The following variable is set up 1 if a transformation has been
4709 static int regexp_transformed_p
;
4711 /* The function makes transformation
4714 transform_1 (regexp
)
4722 if (regexp
->mode
== rm_repeat
)
4724 repeat_num
= REGEXP_REPEAT (regexp
)->repeat_num
;
4725 if (repeat_num
<= 1)
4727 operand
= REGEXP_REPEAT (regexp
)->regexp
;
4729 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4730 * (repeat_num
- 1));
4731 regexp
->mode
= rm_sequence
;
4733 REGEXP_SEQUENCE (regexp
)->regexps_num
= repeat_num
;
4734 for (i
= 0; i
< repeat_num
; i
++)
4735 REGEXP_SEQUENCE (regexp
)->regexps
[i
] = copy_insn_regexp (operand
);
4736 regexp_transformed_p
= 1;
4741 /* The function makes transformations
4742 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4743 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4744 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4746 transform_2 (regexp
)
4749 if (regexp
->mode
== rm_sequence
)
4751 regexp_t sequence
= NULL
;
4753 int sequence_index
= 0;
4756 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4757 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4760 sequence
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4763 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4765 if ( REGEXP_SEQUENCE (sequence
)->regexps_num
<= 1
4766 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4768 result
= create_node (sizeof (struct regexp
)
4770 * (REGEXP_SEQUENCE (regexp
)->regexps_num
4771 + REGEXP_SEQUENCE (sequence
)->regexps_num
4773 result
->mode
= rm_sequence
;
4774 result
->pos
= regexp
->pos
;
4775 REGEXP_SEQUENCE (result
)->regexps_num
4776 = (REGEXP_SEQUENCE (regexp
)->regexps_num
4777 + REGEXP_SEQUENCE (sequence
)->regexps_num
- 1);
4778 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4779 if (i
< sequence_index
)
4780 REGEXP_SEQUENCE (result
)->regexps
[i
]
4781 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4782 else if (i
> sequence_index
)
4783 REGEXP_SEQUENCE (result
)->regexps
4784 [i
+ REGEXP_SEQUENCE (sequence
)->regexps_num
- 1]
4785 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4787 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4788 REGEXP_SEQUENCE (result
)->regexps
[i
+ j
]
4789 = copy_insn_regexp (REGEXP_SEQUENCE (sequence
)->regexps
[j
]);
4790 regexp_transformed_p
= 1;
4794 else if (regexp
->mode
== rm_allof
)
4796 regexp_t allof
= NULL
;
4798 int allof_index
= 0;
4801 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4802 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_allof
)
4805 allof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4808 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4810 if (REGEXP_ALLOF (allof
)->regexps_num
<= 1
4811 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4813 result
= create_node (sizeof (struct regexp
)
4815 * (REGEXP_ALLOF (regexp
)->regexps_num
4816 + REGEXP_ALLOF (allof
)->regexps_num
- 2));
4817 result
->mode
= rm_allof
;
4818 result
->pos
= regexp
->pos
;
4819 REGEXP_ALLOF (result
)->regexps_num
4820 = (REGEXP_ALLOF (regexp
)->regexps_num
4821 + REGEXP_ALLOF (allof
)->regexps_num
- 1);
4822 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4823 if (i
< allof_index
)
4824 REGEXP_ALLOF (result
)->regexps
[i
]
4825 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4826 else if (i
> allof_index
)
4827 REGEXP_ALLOF (result
)->regexps
4828 [i
+ REGEXP_ALLOF (allof
)->regexps_num
- 1]
4829 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4831 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4832 REGEXP_ALLOF (result
)->regexps
[i
+ j
]
4833 = copy_insn_regexp (REGEXP_ALLOF (allof
)->regexps
[j
]);
4834 regexp_transformed_p
= 1;
4838 else if (regexp
->mode
== rm_oneof
)
4840 regexp_t oneof
= NULL
;
4842 int oneof_index
= 0;
4845 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4846 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4849 oneof
= REGEXP_ONEOF (regexp
)->regexps
[i
];
4852 if (i
< REGEXP_ONEOF (regexp
)->regexps_num
)
4854 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4855 || REGEXP_ONEOF (regexp
)->regexps_num
<= 1)
4857 result
= create_node (sizeof (struct regexp
)
4859 * (REGEXP_ONEOF (regexp
)->regexps_num
4860 + REGEXP_ONEOF (oneof
)->regexps_num
- 2));
4861 result
->mode
= rm_oneof
;
4862 result
->pos
= regexp
->pos
;
4863 REGEXP_ONEOF (result
)->regexps_num
4864 = (REGEXP_ONEOF (regexp
)->regexps_num
4865 + REGEXP_ONEOF (oneof
)->regexps_num
- 1);
4866 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4867 if (i
< oneof_index
)
4868 REGEXP_ONEOF (result
)->regexps
[i
]
4869 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4870 else if (i
> oneof_index
)
4871 REGEXP_ONEOF (result
)->regexps
4872 [i
+ REGEXP_ONEOF (oneof
)->regexps_num
- 1]
4873 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4875 for (j
= 0; j
< REGEXP_ONEOF (oneof
)->regexps_num
; j
++)
4876 REGEXP_ONEOF (result
)->regexps
[i
+ j
]
4877 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[j
]);
4878 regexp_transformed_p
= 1;
4885 /* The function makes transformations
4886 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4887 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4888 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4889 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
4891 transform_3 (regexp
)
4894 if (regexp
->mode
== rm_sequence
)
4896 regexp_t oneof
= NULL
;
4897 int oneof_index
= 0;
4902 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4903 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4906 oneof
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4909 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4911 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4912 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4914 result
= create_node (sizeof (struct regexp
)
4916 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4917 result
->mode
= rm_oneof
;
4918 result
->pos
= regexp
->pos
;
4919 REGEXP_ONEOF (result
)->regexps_num
4920 = REGEXP_ONEOF (oneof
)->regexps_num
;
4921 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4924 = create_node (sizeof (struct regexp
)
4926 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4927 sequence
->mode
= rm_sequence
;
4928 sequence
->pos
= regexp
->pos
;
4929 REGEXP_SEQUENCE (sequence
)->regexps_num
4930 = REGEXP_SEQUENCE (regexp
)->regexps_num
;
4931 REGEXP_ONEOF (result
)->regexps
[i
] = sequence
;
4932 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4933 if (j
!= oneof_index
)
4934 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4935 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[j
]);
4937 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4938 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4940 regexp_transformed_p
= 1;
4944 else if (regexp
->mode
== rm_allof
)
4946 regexp_t oneof
= NULL
, seq
;
4947 int oneof_index
= 0, max_seq_length
, allof_length
;
4949 regexp_t allof
= NULL
, allof_op
= NULL
;
4952 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4953 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4956 oneof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4959 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4961 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4962 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4964 result
= create_node (sizeof (struct regexp
)
4966 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4967 result
->mode
= rm_oneof
;
4968 result
->pos
= regexp
->pos
;
4969 REGEXP_ONEOF (result
)->regexps_num
4970 = REGEXP_ONEOF (oneof
)->regexps_num
;
4971 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4974 = create_node (sizeof (struct regexp
)
4976 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4977 allof
->mode
= rm_allof
;
4978 allof
->pos
= regexp
->pos
;
4979 REGEXP_ALLOF (allof
)->regexps_num
4980 = REGEXP_ALLOF (regexp
)->regexps_num
;
4981 REGEXP_ONEOF (result
)->regexps
[i
] = allof
;
4982 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4983 if (j
!= oneof_index
)
4984 REGEXP_ALLOF (allof
)->regexps
[j
]
4985 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[j
]);
4987 REGEXP_ALLOF (allof
)->regexps
[j
]
4988 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4990 regexp_transformed_p
= 1;
4994 if (regexp
->mode
== rm_allof
)
4995 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4996 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4998 seq
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4999 if (max_seq_length
< REGEXP_SEQUENCE (seq
)->regexps_num
)
5000 max_seq_length
= REGEXP_SEQUENCE (seq
)->regexps_num
;
5002 else if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
!= rm_unit
)
5007 if (max_seq_length
!= 0)
5009 if (max_seq_length
== 1 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
5011 result
= create_node (sizeof (struct regexp
)
5012 + sizeof (regexp_t
) * (max_seq_length
- 1));
5013 result
->mode
= rm_sequence
;
5014 result
->pos
= regexp
->pos
;
5015 REGEXP_SEQUENCE (result
)->regexps_num
= max_seq_length
;
5016 for (i
= 0; i
< max_seq_length
; i
++)
5019 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5020 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5021 && (i
< (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5022 ->regexps
[j
])->regexps_num
)))
5025 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)->regexps
[j
])
5030 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5033 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5036 if (allof_length
== 1)
5037 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof_op
;
5040 allof
= create_node (sizeof (struct regexp
)
5042 * (allof_length
- 1));
5043 allof
->mode
= rm_allof
;
5044 allof
->pos
= regexp
->pos
;
5045 REGEXP_ALLOF (allof
)->regexps_num
= allof_length
;
5046 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof
;
5048 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5049 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5051 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5052 ->regexps
[j
])->regexps_num
)))
5054 allof_op
= (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5057 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5062 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5065 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5066 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5072 regexp_transformed_p
= 1;
5079 /* The function traverses IR of reservation and applies transformations
5080 implemented by FUNC. */
5082 regexp_transform_func (regexp
, func
)
5084 regexp_t (*func
) PARAMS ((regexp_t regexp
));
5088 if (regexp
->mode
== rm_sequence
)
5089 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5090 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
5091 = regexp_transform_func (REGEXP_SEQUENCE (regexp
)->regexps
[i
], func
);
5092 else if (regexp
->mode
== rm_allof
)
5093 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5094 REGEXP_ALLOF (regexp
)->regexps
[i
]
5095 = regexp_transform_func (REGEXP_ALLOF (regexp
)->regexps
[i
], func
);
5096 else if (regexp
->mode
== rm_oneof
)
5097 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
5098 REGEXP_ONEOF (regexp
)->regexps
[i
]
5099 = regexp_transform_func (REGEXP_ONEOF (regexp
)->regexps
[i
], func
);
5100 else if (regexp
->mode
== rm_repeat
)
5101 REGEXP_REPEAT (regexp
)->regexp
5102 = regexp_transform_func (REGEXP_REPEAT (regexp
)->regexp
, func
);
5103 else if (regexp
->mode
!= rm_nothing
&& regexp
->mode
!= rm_unit
)
5105 return (*func
) (regexp
);
5108 /* The function applies all transformations for IR representation of
5109 reservation REGEXP. */
5111 transform_regexp (regexp
)
5114 regexp
= regexp_transform_func (regexp
, transform_1
);
5117 regexp_transformed_p
= 0;
5118 regexp
= regexp_transform_func (regexp
, transform_2
);
5119 regexp
= regexp_transform_func (regexp
, transform_3
);
5121 while (regexp_transformed_p
);
5125 /* The function applys all transformations for reservations of all
5126 insn declarations. */
5128 transform_insn_regexps ()
5133 transform_time
= create_ticker ();
5134 add_advance_cycle_insn_decl ();
5135 fprintf (stderr
, "Reservation transformation...");
5137 for (i
= 0; i
< description
->decls_num
; i
++)
5139 decl
= description
->decls
[i
];
5140 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
5141 DECL_INSN_RESERV (decl
)->transformed_regexp
5142 = transform_regexp (copy_insn_regexp
5143 (DECL_INSN_RESERV (decl
)->regexp
));
5145 fprintf (stderr
, "done\n");
5146 ticker_off (&transform_time
);
5152 /* The following variable is an array indexed by cycle. Each element
5153 contains cyclic list of units which should be in the same cycle. */
5154 static unit_decl_t
*the_same_automaton_lists
;
5156 /* The function processes all alternative reservations on CYCLE in
5157 given REGEXP to check the UNIT is not reserved on the all
5158 alternatives. If it is true, the unit should be in the same
5159 automaton with other analogous units reserved on CYCLE in given
5162 process_unit_to_form_the_same_automaton_unit_lists (unit
, regexp
, cycle
)
5168 regexp_t seq
, allof
;
5169 unit_decl_t unit_decl
, last
;
5171 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5173 unit_decl
= REGEXP_UNIT (unit
)->unit_decl
;
5174 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5176 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5177 if (seq
->mode
== rm_sequence
)
5179 if (cycle
>= REGEXP_SEQUENCE (seq
)->regexps_num
)
5181 allof
= REGEXP_SEQUENCE (seq
)->regexps
[cycle
];
5182 if (allof
->mode
== rm_allof
)
5184 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5185 if (REGEXP_ALLOF (allof
)->regexps
[k
]->mode
== rm_unit
5186 && (REGEXP_UNIT (REGEXP_ALLOF (allof
)->regexps
[k
])
5187 ->unit_decl
== unit_decl
))
5189 if (k
>= REGEXP_ALLOF (allof
)->regexps_num
)
5192 else if (allof
->mode
== rm_unit
5193 && REGEXP_UNIT (allof
)->unit_decl
!= unit_decl
)
5196 else if (cycle
!= 0)
5198 else if (seq
->mode
== rm_allof
)
5200 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5201 if (REGEXP_ALLOF (seq
)->regexps
[k
]->mode
== rm_unit
5202 && (REGEXP_UNIT (REGEXP_ALLOF (seq
)->regexps
[k
])->unit_decl
5205 if (k
>= REGEXP_ALLOF (seq
)->regexps_num
)
5208 else if (seq
->mode
== rm_unit
5209 && REGEXP_UNIT (seq
)->unit_decl
!= unit_decl
)
5214 if (the_same_automaton_lists
[cycle
] == NULL
)
5215 the_same_automaton_lists
[cycle
] = unit_decl
;
5218 for (last
= the_same_automaton_lists
[cycle
];;)
5220 if (last
== unit_decl
)
5222 if (last
->the_same_automaton_unit
5223 == the_same_automaton_lists
[cycle
])
5225 last
= last
->the_same_automaton_unit
;
5227 last
->the_same_automaton_unit
= unit_decl
->the_same_automaton_unit
;
5228 unit_decl
->the_same_automaton_unit
5229 = the_same_automaton_lists
[cycle
];
5234 /* The function processes given REGEXP to find units which should be
5235 in the same automaton. */
5237 form_the_same_automaton_unit_lists_from_regexp (regexp
)
5241 regexp_t seq
, allof
, unit
;
5243 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5245 for (i
= 0; i
< description
->max_insn_reserv_cycles
; i
++)
5246 the_same_automaton_lists
[i
] = NULL
;
5247 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5249 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5250 if (seq
->mode
== rm_sequence
)
5251 for (j
= 0; j
< REGEXP_SEQUENCE (seq
)->regexps_num
; j
++)
5253 allof
= REGEXP_SEQUENCE (seq
)->regexps
[j
];
5254 if (allof
->mode
== rm_allof
)
5255 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5257 unit
= REGEXP_ALLOF (allof
)->regexps
[k
];
5258 if (unit
->mode
== rm_unit
)
5259 process_unit_to_form_the_same_automaton_unit_lists
5261 else if (unit
->mode
!= rm_nothing
)
5264 else if (allof
->mode
== rm_unit
)
5265 process_unit_to_form_the_same_automaton_unit_lists
5267 else if (allof
->mode
!= rm_nothing
)
5270 else if (seq
->mode
== rm_allof
)
5271 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5273 unit
= REGEXP_ALLOF (seq
)->regexps
[k
];
5274 if (unit
->mode
== rm_unit
)
5275 process_unit_to_form_the_same_automaton_unit_lists
5277 else if (unit
->mode
!= rm_nothing
)
5280 else if (seq
->mode
== rm_unit
)
5281 process_unit_to_form_the_same_automaton_unit_lists (seq
, regexp
, 0);
5282 else if (seq
->mode
!= rm_nothing
)
5287 /* The function initializes data to search for units which should be
5288 in the same automaton and call function
5289 `form_the_same_automaton_unit_lists_from_regexp' for each insn
5290 reservation regexp. */
5292 form_the_same_automaton_unit_lists ()
5297 the_same_automaton_lists
5298 = (unit_decl_t
*) xmalloc (description
->max_insn_reserv_cycles
5299 * sizeof (unit_decl_t
));
5300 for (i
= 0; i
< description
->decls_num
; i
++)
5302 decl
= description
->decls
[i
];
5303 if (decl
->mode
== dm_unit
)
5305 DECL_UNIT (decl
)->the_same_automaton_message_reported_p
= FALSE
;
5306 DECL_UNIT (decl
)->the_same_automaton_unit
= DECL_UNIT (decl
);
5309 for (i
= 0; i
< description
->decls_num
; i
++)
5311 decl
= description
->decls
[i
];
5312 if (decl
->mode
== dm_insn_reserv
)
5313 form_the_same_automaton_unit_lists_from_regexp
5314 (DECL_INSN_RESERV (decl
)->transformed_regexp
);
5316 free (the_same_automaton_lists
);
5319 /* The function finds units which should be in the same automaton and,
5320 if they are not, reports about it. */
5322 check_unit_distributions_to_automata ()
5325 unit_decl_t start_unit_decl
, unit_decl
;
5328 form_the_same_automaton_unit_lists ();
5329 for (i
= 0; i
< description
->decls_num
; i
++)
5331 decl
= description
->decls
[i
];
5332 if (decl
->mode
== dm_unit
)
5334 start_unit_decl
= DECL_UNIT (decl
);
5335 if (!start_unit_decl
->the_same_automaton_message_reported_p
)
5336 for (unit_decl
= start_unit_decl
->the_same_automaton_unit
;
5337 unit_decl
!= start_unit_decl
;
5338 unit_decl
= unit_decl
->the_same_automaton_unit
)
5339 if (start_unit_decl
->automaton_decl
!= unit_decl
->automaton_decl
)
5341 error ("Units `%s' and `%s' should be in the same automaton",
5342 start_unit_decl
->name
, unit_decl
->name
);
5343 unit_decl
->the_same_automaton_message_reported_p
= TRUE
;
5351 /* The page contains code for building alt_states (see comments for
5352 IR) describing all possible insns reservations of an automaton. */
5354 /* Current state being formed for which the current alt_state
5356 static state_t state_being_formed
;
5358 /* Current alt_state being formed. */
5359 static alt_state_t alt_state_being_formed
;
5361 /* This recursive function processes `,' and units in reservation
5362 REGEXP for forming alt_states of AUTOMATON. It is believed that
5363 CURR_CYCLE is start cycle of all reservation REGEXP. */
5365 process_seq_for_forming_states (regexp
, automaton
, curr_cycle
)
5367 automaton_t automaton
;
5374 else if (regexp
->mode
== rm_unit
)
5376 if (REGEXP_UNIT (regexp
)->unit_decl
->corresponding_automaton_num
5377 == automaton
->automaton_order_num
)
5378 set_state_reserv (state_being_formed
, curr_cycle
,
5379 REGEXP_UNIT (regexp
)->unit_decl
->unit_num
);
5382 else if (regexp
->mode
== rm_sequence
)
5384 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5386 = process_seq_for_forming_states
5387 (REGEXP_SEQUENCE (regexp
)->regexps
[i
], automaton
, curr_cycle
) + 1;
5390 else if (regexp
->mode
== rm_allof
)
5392 int finish_cycle
= 0;
5395 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5397 cycle
= process_seq_for_forming_states (REGEXP_ALLOF (regexp
)
5399 automaton
, curr_cycle
);
5400 if (finish_cycle
< cycle
)
5401 finish_cycle
= cycle
;
5403 return finish_cycle
;
5407 if (regexp
->mode
!= rm_nothing
)
5413 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5414 inserts alt_state into the table. */
5416 finish_forming_alt_state (alt_state
, automaton
)
5417 alt_state_t alt_state
;
5418 automaton_t automaton ATTRIBUTE_UNUSED
;
5420 state_t state_in_table
;
5421 state_t corresponding_state
;
5423 corresponding_state
= alt_state
->state
;
5424 state_in_table
= insert_state (corresponding_state
);
5425 if (state_in_table
!= corresponding_state
)
5427 free_state (corresponding_state
);
5428 alt_state
->state
= state_in_table
;
5432 /* The following variable value is current automaton insn for whose
5433 reservation the alt states are created. */
5434 static ainsn_t curr_ainsn
;
5436 /* This recursive function processes `|' in reservation REGEXP for
5437 forming alt_states of AUTOMATON. List of the alt states should
5438 have the same order as in the description. */
5440 process_alts_for_forming_states (regexp
, automaton
, inside_oneof_p
)
5442 automaton_t automaton
;
5447 if (regexp
->mode
!= rm_oneof
)
5449 alt_state_being_formed
= get_free_alt_state ();
5450 state_being_formed
= get_free_state (1, automaton
);
5451 alt_state_being_formed
->state
= state_being_formed
;
5452 /* We inserts in reverse order but we process alternatives also
5453 in reverse order. So we have the same order of alternative
5454 as in the description. */
5455 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5456 curr_ainsn
->alt_states
= alt_state_being_formed
;
5457 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5458 finish_forming_alt_state (alt_state_being_formed
, automaton
);
5464 /* We processes it in reverse order to get list with the same
5465 order as in the description. See also the previous
5467 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5468 process_alts_for_forming_states (REGEXP_ONEOF (regexp
)->regexps
[i
],
5473 /* Create nodes alt_state for all AUTOMATON insns. */
5475 create_alt_states (automaton
)
5476 automaton_t automaton
;
5478 struct insn_reserv_decl
*reserv_decl
;
5480 for (curr_ainsn
= automaton
->ainsn_list
;
5482 curr_ainsn
= curr_ainsn
->next_ainsn
)
5484 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5485 if (reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5487 curr_ainsn
->alt_states
= NULL
;
5488 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5490 curr_ainsn
->sorted_alt_states
5491 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5498 /* The page contains major code for building DFA(s) for fast pipeline
5499 hazards recognition. */
5501 /* The function forms list of ainsns of AUTOMATON with the same
5504 form_ainsn_with_same_reservs (automaton
)
5505 automaton_t automaton
;
5509 vla_ptr_t first_insns
;
5510 vla_ptr_t last_insns
;
5512 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5513 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5514 for (curr_ainsn
= automaton
->ainsn_list
;
5516 curr_ainsn
= curr_ainsn
->next_ainsn
)
5517 if (curr_ainsn
->insn_reserv_decl
5518 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
5520 curr_ainsn
->next_same_reservs_insn
= NULL
;
5521 curr_ainsn
->first_insn_with_same_reservs
= 1;
5525 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5527 (curr_ainsn
->sorted_alt_states
,
5528 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5530 curr_ainsn
->next_same_reservs_insn
= NULL
;
5531 if (i
< VLA_PTR_LENGTH (first_insns
))
5533 curr_ainsn
->first_insn_with_same_reservs
= 0;
5534 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5536 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5540 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5541 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5542 curr_ainsn
->first_insn_with_same_reservs
= 1;
5545 VLA_PTR_DELETE (first_insns
);
5546 VLA_PTR_DELETE (last_insns
);
5549 /* The following function creates all states of nondeterministic (if
5550 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5552 make_automaton (automaton
)
5553 automaton_t automaton
;
5556 struct insn_reserv_decl
*insn_reserv_decl
;
5557 alt_state_t alt_state
;
5559 state_t start_state
;
5561 ainsn_t advance_cycle_ainsn
;
5563 vla_ptr_t state_stack
;
5565 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5566 /* Create the start state (empty state). */
5567 start_state
= insert_state (get_free_state (1, automaton
));
5568 automaton
->start_state
= start_state
;
5569 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5570 VLA_PTR_ADD (state_stack
, start_state
);
5571 while (VLA_PTR_LENGTH (state_stack
) != 0)
5573 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5574 VLA_PTR_SHORTEN (state_stack
, 1);
5575 advance_cycle_ainsn
= NULL
;
5576 for (ainsn
= automaton
->ainsn_list
;
5578 ainsn
= ainsn
->next_ainsn
)
5579 if (ainsn
->first_insn_with_same_reservs
)
5581 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5582 if (insn_reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5584 /* We process alt_states in the same order as they are
5585 present in the description. */
5587 for (alt_state
= ainsn
->alt_states
;
5589 alt_state
= alt_state
->next_alt_state
)
5591 state2
= alt_state
->state
;
5592 if (!intersected_state_reservs_p (state
, state2
))
5594 state2
= states_union (state
, state2
);
5595 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5597 state2
->it_was_placed_in_stack_for_NDFA_forming
5599 VLA_PTR_ADD (state_stack
, state2
);
5601 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5606 if (!ndfa_flag
&& added_arc
!= NULL
)
5608 added_arc
->state_alts
= 0;
5609 for (alt_state
= ainsn
->alt_states
;
5611 alt_state
= alt_state
->next_alt_state
)
5613 state2
= alt_state
->state
;
5614 if (!intersected_state_reservs_p (state
, state2
))
5615 added_arc
->state_alts
++;
5620 advance_cycle_ainsn
= ainsn
;
5622 /* Add transition to advance cycle. */
5623 state2
= state_shift (state
);
5624 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5626 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5627 VLA_PTR_ADD (state_stack
, state2
);
5629 if (advance_cycle_ainsn
== NULL
)
5631 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5633 VLA_PTR_DELETE (state_stack
);
5636 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5638 form_arcs_marked_by_insn (state
)
5645 for (i
= 0; i
< description
->decls_num
; i
++)
5647 decl
= description
->decls
[i
];
5648 if (decl
->mode
== dm_insn_reserv
)
5649 DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
= NULL
;
5651 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5653 if (arc
->insn
== NULL
)
5655 arc
->next_arc_marked_by_insn
5656 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5657 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5661 /* The function creates composed state (see comments for IR) from
5662 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5663 same insn. If the composed state is not in STATE_STACK yet, it is
5664 popped to STATE_STACK. */
5666 create_composed_state (original_state
, arcs_marked_by_insn
, state_stack
)
5667 state_t original_state
;
5668 arc_t arcs_marked_by_insn
;
5669 vla_ptr_t
*state_stack
;
5672 alt_state_t curr_alt_state
;
5673 alt_state_t new_alt_state
;
5676 state_t state_in_table
;
5678 alt_state_t canonical_alt_states_list
;
5681 if (arcs_marked_by_insn
== NULL
)
5683 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5684 state
= arcs_marked_by_insn
->to_state
;
5689 /* Create composed state. */
5690 state
= get_free_state (0, arcs_marked_by_insn
->to_state
->automaton
);
5691 curr_alt_state
= NULL
;
5692 for (curr_arc
= arcs_marked_by_insn
;
5694 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5696 new_alt_state
= get_free_alt_state ();
5697 new_alt_state
->next_alt_state
= curr_alt_state
;
5698 new_alt_state
->state
= curr_arc
->to_state
;
5699 if (curr_arc
->to_state
->component_states
!= NULL
)
5701 curr_alt_state
= new_alt_state
;
5703 /* There are not identical sets in the alt state list. */
5704 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5705 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5708 state
= canonical_alt_states_list
->state
;
5709 free_state (temp_state
);
5713 state
->component_states
= canonical_alt_states_list
;
5714 state_in_table
= insert_state (state
);
5715 if (state_in_table
!= state
)
5717 if (!state_in_table
->it_was_placed_in_stack_for_DFA_forming
)
5720 state
= state_in_table
;
5724 if (state
->it_was_placed_in_stack_for_DFA_forming
)
5726 for (curr_alt_state
= state
->component_states
;
5727 curr_alt_state
!= NULL
;
5728 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
5729 for (curr_arc
= first_out_arc (curr_alt_state
->state
);
5731 curr_arc
= next_out_arc (curr_arc
))
5732 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5734 arcs_marked_by_insn
->to_state
= state
;
5735 for (alts_number
= 0,
5736 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5738 curr_arc
= next_arc
)
5740 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5741 remove_arc (original_state
, curr_arc
);
5744 arcs_marked_by_insn
->state_alts
= alts_number
;
5747 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5749 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5750 VLA_PTR_ADD (*state_stack
, state
);
5754 /* The function transformes nondeterminstic AUTOMATON into
5757 NDFA_to_DFA (automaton
)
5758 automaton_t automaton
;
5760 state_t start_state
;
5763 vla_ptr_t state_stack
;
5766 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5767 /* Create the start state (empty state). */
5768 start_state
= automaton
->start_state
;
5769 start_state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5770 VLA_PTR_ADD (state_stack
, start_state
);
5771 while (VLA_PTR_LENGTH (state_stack
) != 0)
5773 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5774 VLA_PTR_SHORTEN (state_stack
, 1);
5775 form_arcs_marked_by_insn (state
);
5776 for (i
= 0; i
< description
->decls_num
; i
++)
5778 decl
= description
->decls
[i
];
5779 if (decl
->mode
== dm_insn_reserv
)
5780 create_composed_state
5781 (state
, DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
,
5785 VLA_PTR_DELETE (state_stack
);
5788 /* The following variable value is current number (1, 2, ...) of passing
5790 static int curr_state_graph_pass_num
;
5792 /* This recursive function passes all states achieved from START_STATE
5793 and applies APPLIED_FUNC to them. */
5795 pass_state_graph (start_state
, applied_func
)
5796 state_t start_state
;
5797 void (*applied_func
) PARAMS ((state_t state
));
5801 if (start_state
->pass_num
== curr_state_graph_pass_num
)
5803 start_state
->pass_num
= curr_state_graph_pass_num
;
5804 (*applied_func
) (start_state
);
5805 for (arc
= first_out_arc (start_state
);
5807 arc
= next_out_arc (arc
))
5808 pass_state_graph (arc
->to_state
, applied_func
);
5811 /* This recursive function passes all states of AUTOMATON and applies
5812 APPLIED_FUNC to them. */
5814 pass_states (automaton
, applied_func
)
5815 automaton_t automaton
;
5816 void (*applied_func
) PARAMS ((state_t state
));
5818 curr_state_graph_pass_num
++;
5819 pass_state_graph (automaton
->start_state
, applied_func
);
5822 /* The function initializes code for passing of all states. */
5824 initiate_pass_states ()
5826 curr_state_graph_pass_num
= 0;
5829 /* The following vla is used for storing pointers to all achieved
5831 static vla_ptr_t all_achieved_states
;
5833 /* This function is called by function pass_states to add an achieved
5836 add_achieved_state (state
)
5839 VLA_PTR_ADD (all_achieved_states
, state
);
5842 /* The function sets up equivalence numbers of insns which mark all
5843 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5844 nonzero value) or by equiv_class_num_2 of the destination state.
5845 The function returns number of out arcs of STATE. */
5847 set_out_arc_insns_equiv_num (state
, odd_iteration_flag
)
5849 int odd_iteration_flag
;
5851 int state_out_arcs_num
;
5854 state_out_arcs_num
= 0;
5855 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5857 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
!= 0
5858 || arc
->insn
->insn_reserv_decl
->state_alts
!= 0)
5860 state_out_arcs_num
++;
5861 arc
->insn
->insn_reserv_decl
->equiv_class_num
5862 = (odd_iteration_flag
5863 ? arc
->to_state
->equiv_class_num_1
5864 : arc
->to_state
->equiv_class_num_2
);
5865 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
5866 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
== 0
5867 || arc
->insn
->insn_reserv_decl
->state_alts
<= 0)
5870 return state_out_arcs_num
;
5873 /* The function clears equivalence numbers and alt_states in all insns
5874 which mark all out arcs of STATE. */
5876 clear_arc_insns_equiv_num (state
)
5881 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5883 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
5884 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
5888 /* The function copies pointers to equivalent states from vla FROM
5891 copy_equiv_class (to
, from
)
5893 const vla_ptr_t
*from
;
5897 VLA_PTR_NULLIFY (*to
);
5898 for (class_ptr
= VLA_PTR_BEGIN (*from
);
5899 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
5901 VLA_PTR_ADD (*to
, *class_ptr
);
5904 /* The function returns nonzero value if STATE is not equivalent to
5905 another state from the same current partition on equivalence
5906 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5907 output arcs. Iteration of making equivalence partition is defined
5908 by ODD_ITERATION_FLAG. */
5910 state_is_differed (state
, original_state_out_arcs_num
, odd_iteration_flag
)
5912 int original_state_out_arcs_num
;
5913 int odd_iteration_flag
;
5916 int state_out_arcs_num
;
5918 state_out_arcs_num
= 0;
5919 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5921 state_out_arcs_num
++;
5922 if ((odd_iteration_flag
5923 ? arc
->to_state
->equiv_class_num_1
5924 : arc
->to_state
->equiv_class_num_2
)
5925 != arc
->insn
->insn_reserv_decl
->equiv_class_num
5926 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
5929 return state_out_arcs_num
!= original_state_out_arcs_num
;
5932 /* The function makes initial partition of STATES on equivalent
5935 init_equiv_class (states
, states_num
)
5940 state_t result_equiv_class
;
5942 result_equiv_class
= NULL
;
5943 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
5945 (*state_ptr
)->equiv_class_num_1
= 1;
5946 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
5947 result_equiv_class
= *state_ptr
;
5949 return result_equiv_class
;
5952 /* The function processes equivalence class given by its pointer
5953 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5954 are not equvalent states, the function partitions the class
5955 removing nonequivalent states and placing them in
5956 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5957 assigns it to the state equivalence number. If the class has been
5958 partitioned, the function returns nonzero value. */
5960 partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5961 next_iteration_classes
, new_equiv_class_num_ptr
)
5962 state_t
*equiv_class_ptr
;
5963 int odd_iteration_flag
;
5964 vla_ptr_t
*next_iteration_classes
;
5965 int *new_equiv_class_num_ptr
;
5967 state_t new_equiv_class
;
5969 state_t first_state
;
5976 if (*equiv_class_ptr
== NULL
)
5978 for (first_state
= *equiv_class_ptr
;
5979 first_state
!= NULL
;
5980 first_state
= new_equiv_class
)
5982 new_equiv_class
= NULL
;
5983 if (first_state
->next_equiv_class_state
!= NULL
)
5985 /* There are more one states in the class equivalence. */
5986 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
5987 odd_iteration_flag
);
5988 for (prev_state
= first_state
,
5989 curr_state
= first_state
->next_equiv_class_state
;
5991 curr_state
= next_state
)
5993 next_state
= curr_state
->next_equiv_class_state
;
5994 if (state_is_differed (curr_state
, out_arcs_num
,
5995 odd_iteration_flag
))
5997 /* Remove curr state from the class equivalence. */
5998 prev_state
->next_equiv_class_state
= next_state
;
5999 /* Add curr state to the new class equivalence. */
6000 curr_state
->next_equiv_class_state
= new_equiv_class
;
6001 if (new_equiv_class
== NULL
)
6002 (*new_equiv_class_num_ptr
)++;
6003 if (odd_iteration_flag
)
6004 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
6006 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
6007 new_equiv_class
= curr_state
;
6011 prev_state
= curr_state
;
6013 clear_arc_insns_equiv_num (first_state
);
6015 if (new_equiv_class
!= NULL
)
6016 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
6021 /* The function finds equivalent states of AUTOMATON. */
6023 evaluate_equiv_classes (automaton
, equiv_classes
)
6024 automaton_t automaton
;
6025 vla_ptr_t
*equiv_classes
;
6027 state_t new_equiv_class
;
6028 int new_equiv_class_num
;
6029 int odd_iteration_flag
;
6031 vla_ptr_t next_iteration_classes
;
6032 state_t
*equiv_class_ptr
;
6035 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
6036 pass_states (automaton
, add_achieved_state
);
6037 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
6038 VLA_PTR_LENGTH (all_achieved_states
));
6039 odd_iteration_flag
= 0;
6040 new_equiv_class_num
= 1;
6041 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
6042 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
6045 odd_iteration_flag
= !odd_iteration_flag
;
6047 copy_equiv_class (equiv_classes
, &next_iteration_classes
);
6048 /* Transfer equiv numbers for the next iteration. */
6049 for (state_ptr
= VLA_PTR_BEGIN (all_achieved_states
);
6050 state_ptr
<= (state_t
*) VLA_PTR_LAST (all_achieved_states
);
6052 if (odd_iteration_flag
)
6053 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
6055 (*state_ptr
)->equiv_class_num_1
= (*state_ptr
)->equiv_class_num_2
;
6056 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6057 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6059 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
6060 &next_iteration_classes
,
6061 &new_equiv_class_num
))
6064 while (!finish_flag
);
6065 VLA_PTR_DELETE (next_iteration_classes
);
6066 VLA_PTR_DELETE (all_achieved_states
);
6069 /* The function merges equivalent states of AUTOMATON. */
6071 merge_states (automaton
, equiv_classes
)
6072 automaton_t automaton
;
6073 vla_ptr_t
*equiv_classes
;
6075 state_t
*equiv_class_ptr
;
6078 state_t first_class_state
;
6079 alt_state_t alt_states
;
6080 alt_state_t new_alt_state
;
6084 /* Create states corresponding to equivalence classes containing two
6086 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6087 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6089 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6091 /* There are more one states in the class equivalence. */
6092 /* Create new compound state. */
6093 new_state
= get_free_state (0, automaton
);
6095 first_class_state
= *equiv_class_ptr
;
6096 for (curr_state
= first_class_state
;
6098 curr_state
= curr_state
->next_equiv_class_state
)
6100 curr_state
->equiv_class_state
= new_state
;
6101 new_alt_state
= get_free_alt_state ();
6102 new_alt_state
->state
= curr_state
;
6103 new_alt_state
->next_sorted_alt_state
= alt_states
;
6104 alt_states
= new_alt_state
;
6106 new_state
->component_states
= alt_states
;
6109 (*equiv_class_ptr
)->equiv_class_state
= *equiv_class_ptr
;
6110 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6111 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6113 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6115 first_class_state
= *equiv_class_ptr
;
6116 /* Create new arcs output from the state corresponding to
6118 for (curr_arc
= first_out_arc (first_class_state
);
6120 curr_arc
= next_out_arc (curr_arc
))
6121 add_arc (first_class_state
->equiv_class_state
,
6122 curr_arc
->to_state
->equiv_class_state
,
6123 curr_arc
->insn
, curr_arc
->state_alts
);
6124 /* Delete output arcs from states of given class equivalence. */
6125 for (curr_state
= first_class_state
;
6127 curr_state
= curr_state
->next_equiv_class_state
)
6129 if (automaton
->start_state
== curr_state
)
6130 automaton
->start_state
= curr_state
->equiv_class_state
;
6131 /* Delete the state and its output arcs. */
6132 for (curr_arc
= first_out_arc (curr_state
);
6134 curr_arc
= next_arc
)
6136 next_arc
= next_out_arc (curr_arc
);
6137 free_arc (curr_arc
);
6143 /* Change `to_state' of arcs output from the state of given
6144 equivalence class. */
6145 for (curr_arc
= first_out_arc (*equiv_class_ptr
);
6147 curr_arc
= next_out_arc (curr_arc
))
6148 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
6152 /* The function sets up new_cycle_p for states if there is arc to the
6153 state marked by advance_cycle_insn_decl. */
6155 set_new_cycle_flags (state
)
6160 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6161 if (arc
->insn
->insn_reserv_decl
6162 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
6163 arc
->to_state
->new_cycle_p
= 1;
6166 /* The top level function for minimization of deterministic
6169 minimize_DFA (automaton
)
6170 automaton_t automaton
;
6172 vla_ptr_t equiv_classes
;
6174 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
6175 evaluate_equiv_classes (automaton
, &equiv_classes
);
6176 merge_states (automaton
, &equiv_classes
);
6177 pass_states (automaton
, set_new_cycle_flags
);
6178 VLA_PTR_DELETE (equiv_classes
);
6181 /* Values of two variables are counted number of states and arcs in an
6183 static int curr_counted_states_num
;
6184 static int curr_counted_arcs_num
;
6186 /* The function is called by function `pass_states' to count states
6187 and arcs of an automaton. */
6189 incr_states_and_arcs_nums (state
)
6194 curr_counted_states_num
++;
6195 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6196 curr_counted_arcs_num
++;
6199 /* The function counts states and arcs of AUTOMATON. */
6201 count_states_and_arcs (automaton
, states_num
, arcs_num
)
6202 automaton_t automaton
;
6206 curr_counted_states_num
= 0;
6207 curr_counted_arcs_num
= 0;
6208 pass_states (automaton
, incr_states_and_arcs_nums
);
6209 *states_num
= curr_counted_states_num
;
6210 *arcs_num
= curr_counted_arcs_num
;
6213 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6214 recognition after checking and simplifying IR of the
6217 build_automaton (automaton
)
6218 automaton_t automaton
;
6223 ticker_on (&NDFA_time
);
6224 make_automaton (automaton
);
6225 ticker_off (&NDFA_time
);
6226 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6227 automaton
->NDFA_states_num
= states_num
;
6228 automaton
->NDFA_arcs_num
= arcs_num
;
6229 ticker_on (&NDFA_to_DFA_time
);
6230 NDFA_to_DFA (automaton
);
6231 ticker_off (&NDFA_to_DFA_time
);
6232 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6233 automaton
->DFA_states_num
= states_num
;
6234 automaton
->DFA_arcs_num
= arcs_num
;
6235 if (!no_minimization_flag
)
6237 ticker_on (&minimize_time
);
6238 minimize_DFA (automaton
);
6239 ticker_off (&minimize_time
);
6240 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6241 automaton
->minimal_DFA_states_num
= states_num
;
6242 automaton
->minimal_DFA_arcs_num
= arcs_num
;
6248 /* The page contains code for enumeration of all states of an automaton. */
6250 /* Variable used for enumeration of all states of an automaton. Its
6251 value is current number of automaton states. */
6252 static int curr_state_order_num
;
6254 /* The function is called by function `pass_states' for enumerating
6257 set_order_state_num (state
)
6260 state
->order_state_num
= curr_state_order_num
;
6261 curr_state_order_num
++;
6264 /* The function enumerates all states of AUTOMATON. */
6266 enumerate_states (automaton
)
6267 automaton_t automaton
;
6269 curr_state_order_num
= 0;
6270 pass_states (automaton
, set_order_state_num
);
6271 automaton
->achieved_states_num
= curr_state_order_num
;
6276 /* The page contains code for finding equivalent automaton insns
6279 /* The function inserts AINSN into cyclic list
6280 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6282 insert_ainsn_into_equiv_class (ainsn
, cyclic_equiv_class_insn_list
)
6284 ainsn_t cyclic_equiv_class_insn_list
;
6286 if (cyclic_equiv_class_insn_list
== NULL
)
6287 ainsn
->next_equiv_class_insn
= ainsn
;
6290 ainsn
->next_equiv_class_insn
6291 = cyclic_equiv_class_insn_list
->next_equiv_class_insn
;
6292 cyclic_equiv_class_insn_list
->next_equiv_class_insn
= ainsn
;
6297 /* The function deletes equiv_class_insn into cyclic list of
6298 equivalent ainsns. */
6300 delete_ainsn_from_equiv_class (equiv_class_insn
)
6301 ainsn_t equiv_class_insn
;
6303 ainsn_t curr_equiv_class_insn
;
6304 ainsn_t prev_equiv_class_insn
;
6306 prev_equiv_class_insn
= equiv_class_insn
;
6307 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
6308 curr_equiv_class_insn
!= equiv_class_insn
;
6309 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
6310 prev_equiv_class_insn
= curr_equiv_class_insn
;
6311 if (prev_equiv_class_insn
!= equiv_class_insn
)
6312 prev_equiv_class_insn
->next_equiv_class_insn
6313 = equiv_class_insn
->next_equiv_class_insn
;
6316 /* The function processes AINSN of a state in order to find equivalent
6317 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6320 process_insn_equiv_class (ainsn
, insn_arcs_array
)
6322 arc_t
*insn_arcs_array
;
6326 ainsn_t cyclic_insn_list
;
6329 if (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
] == NULL
)
6332 /* New class of ainsns which are not equivalent to given ainsn. */
6333 cyclic_insn_list
= NULL
;
6336 next_insn
= curr_insn
->next_equiv_class_insn
;
6337 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6339 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6342 delete_ainsn_from_equiv_class (curr_insn
);
6343 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6346 curr_insn
= next_insn
;
6348 while (curr_insn
!= ainsn
);
6351 /* The function processes STATE in order to find equivalent ainsns. */
6353 process_state_for_insn_equiv_partition (state
)
6357 arc_t
*insn_arcs_array
;
6359 vla_ptr_t insn_arcs_vect
;
6361 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6362 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6363 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6364 /* Process insns of the arcs. */
6365 for (i
= 0; i
< description
->insns_num
; i
++)
6366 insn_arcs_array
[i
] = NULL
;
6367 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6368 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6369 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6370 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6371 VLA_PTR_DELETE (insn_arcs_vect
);
6374 /* The function searches for equivalent ainsns of AUTOMATON. */
6376 set_insn_equiv_classes (automaton
)
6377 automaton_t automaton
;
6382 ainsn_t cyclic_insn_list
;
6383 ainsn_t insn_with_same_reservs
;
6384 int equiv_classes_num
;
6386 /* All insns are included in one equivalence class. */
6387 cyclic_insn_list
= NULL
;
6388 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6389 if (ainsn
->first_insn_with_same_reservs
)
6390 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
6392 /* Process insns in order to make equivalence partition. */
6393 pass_states (automaton
, process_state_for_insn_equiv_partition
);
6394 /* Enumerate equiv classes. */
6395 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6396 /* Set undefined value. */
6397 ainsn
->insn_equiv_class_num
= -1;
6398 equiv_classes_num
= 0;
6399 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6400 if (ainsn
->insn_equiv_class_num
< 0)
6403 if (!first_insn
->first_insn_with_same_reservs
)
6405 first_insn
->first_ainsn_with_given_equialence_num
= 1;
6406 curr_insn
= first_insn
;
6409 for (insn_with_same_reservs
= curr_insn
;
6410 insn_with_same_reservs
!= NULL
;
6411 insn_with_same_reservs
6412 = insn_with_same_reservs
->next_same_reservs_insn
)
6413 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6414 curr_insn
= curr_insn
->next_equiv_class_insn
;
6416 while (curr_insn
!= first_insn
);
6417 equiv_classes_num
++;
6419 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6424 /* This page contains code for creating DFA(s) and calls functions
6428 /* The following value is used to prevent floating point overflow for
6429 estimating an automaton bound. The value should be less DBL_MAX on
6430 the host machine. We use here approximate minimum of maximal
6431 double floating point value required by ANSI C standard. It
6432 will work for non ANSI sun compiler too. */
6434 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6436 /* The function estimate size of the single DFA used by PHR (pipeline
6437 hazards recognizer). */
6439 estimate_one_automaton_bound ()
6442 double one_automaton_estimation_bound
;
6446 one_automaton_estimation_bound
= 1.0;
6447 for (i
= 0; i
< description
->decls_num
; i
++)
6449 decl
= description
->decls
[i
];
6450 if (decl
->mode
== dm_unit
)
6452 root_value
= exp (log (DECL_UNIT (decl
)->max_occ_cycle_num
+ 1.0)
6454 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6455 > one_automaton_estimation_bound
)
6456 one_automaton_estimation_bound
*= root_value
;
6459 return one_automaton_estimation_bound
;
6462 /* The function compares unit declarations acoording to their maximal
6463 cycle in reservations. */
6465 compare_max_occ_cycle_nums (unit_decl_1
, unit_decl_2
)
6466 const void *unit_decl_1
;
6467 const void *unit_decl_2
;
6469 if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6470 < (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6472 else if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6473 == (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6479 /* The function makes heuristic assigning automata to units. Actually
6480 efficacy of the algorithm has been checked yet??? */
6482 units_to_automata_heuristic_distr ()
6484 double estimation_bound
;
6486 decl_t
*unit_decl_ptr
;
6490 vla_ptr_t unit_decls
;
6493 if (description
->units_num
== 0)
6495 estimation_bound
= estimate_one_automaton_bound ();
6496 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6497 for (i
= 0; i
< description
->decls_num
; i
++)
6499 decl
= description
->decls
[i
];
6500 if (decl
->mode
== dm_unit
)
6501 VLA_PTR_ADD (unit_decls
, decl
);
6503 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6504 sizeof (decl_t
), compare_max_occ_cycle_nums
);
6506 unit_decl_ptr
= VLA_PTR_BEGIN (unit_decls
);
6507 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6508 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6509 for (unit_decl_ptr
++;
6510 unit_decl_ptr
<= (decl_t
*) VLA_PTR_LAST (unit_decls
);
6514 = ((decl_t
*) VLA_PTR_LAST (unit_decls
) - unit_decl_ptr
+ 1);
6515 if (automata_num
- automaton_num
- 1 > rest_units_num
)
6517 if (automaton_num
< automata_num
- 1
6518 && ((automata_num
- automaton_num
- 1 == rest_units_num
)
6521 / (DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
)))))
6523 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6527 bound_value
*= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6528 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6530 if (automaton_num
!= automata_num
- 1)
6532 VLA_PTR_DELETE (unit_decls
);
6535 /* The functions creates automaton insns for each automata. Automaton
6536 insn is simply insn for given automaton which makes reservation
6537 only of units of the automaton. */
6542 ainsn_t first_ainsn
;
6549 for (i
= 0; i
< description
->decls_num
; i
++)
6551 decl
= description
->decls
[i
];
6552 if (decl
->mode
== dm_insn_reserv
)
6554 curr_ainsn
= create_node (sizeof (struct ainsn
));
6555 curr_ainsn
->insn_reserv_decl
= DECL_INSN_RESERV (decl
);
6556 curr_ainsn
->important_p
= FALSE
;
6557 curr_ainsn
->next_ainsn
= NULL
;
6558 if (prev_ainsn
== NULL
)
6559 first_ainsn
= curr_ainsn
;
6561 prev_ainsn
->next_ainsn
= curr_ainsn
;
6562 prev_ainsn
= curr_ainsn
;
6568 /* The function assigns automata to units according to constructions
6569 `define_automaton' in the description. */
6571 units_to_automata_distr ()
6576 for (i
= 0; i
< description
->decls_num
; i
++)
6578 decl
= description
->decls
[i
];
6579 if (decl
->mode
== dm_unit
)
6581 if (DECL_UNIT (decl
)->automaton_decl
== NULL
6582 || (DECL_UNIT (decl
)->automaton_decl
->corresponding_automaton
6584 /* Distribute to the first automaton. */
6585 DECL_UNIT (decl
)->corresponding_automaton_num
= 0;
6587 DECL_UNIT (decl
)->corresponding_automaton_num
6588 = (DECL_UNIT (decl
)->automaton_decl
6589 ->corresponding_automaton
->automaton_order_num
);
6594 /* The function creates DFA(s) for fast pipeline hazards recognition
6595 after checking and simplifying IR of the description. */
6599 automaton_t curr_automaton
;
6600 automaton_t prev_automaton
;
6602 int curr_automaton_num
;
6605 if (automata_num
!= 0)
6607 units_to_automata_heuristic_distr ();
6608 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6609 curr_automaton_num
< automata_num
;
6610 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6612 curr_automaton
= create_node (sizeof (struct automaton
));
6613 curr_automaton
->ainsn_list
= create_ainsns ();
6614 curr_automaton
->corresponding_automaton_decl
= NULL
;
6615 curr_automaton
->next_automaton
= NULL
;
6616 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6617 if (prev_automaton
== NULL
)
6618 description
->first_automaton
= curr_automaton
;
6620 prev_automaton
->next_automaton
= curr_automaton
;
6625 curr_automaton_num
= 0;
6626 prev_automaton
= NULL
;
6627 for (i
= 0; i
< description
->decls_num
; i
++)
6629 decl
= description
->decls
[i
];
6630 if (decl
->mode
== dm_automaton
6631 && DECL_AUTOMATON (decl
)->automaton_is_used
)
6633 curr_automaton
= create_node (sizeof (struct automaton
));
6634 curr_automaton
->ainsn_list
= create_ainsns ();
6635 curr_automaton
->corresponding_automaton_decl
6636 = DECL_AUTOMATON (decl
);
6637 curr_automaton
->next_automaton
= NULL
;
6638 DECL_AUTOMATON (decl
)->corresponding_automaton
= curr_automaton
;
6639 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6640 if (prev_automaton
== NULL
)
6641 description
->first_automaton
= curr_automaton
;
6643 prev_automaton
->next_automaton
= curr_automaton
;
6644 curr_automaton_num
++;
6645 prev_automaton
= curr_automaton
;
6648 if (curr_automaton_num
== 0)
6650 curr_automaton
= create_node (sizeof (struct automaton
));
6651 curr_automaton
->ainsn_list
= create_ainsns ();
6652 curr_automaton
->corresponding_automaton_decl
= NULL
;
6653 curr_automaton
->next_automaton
= NULL
;
6654 description
->first_automaton
= curr_automaton
;
6656 units_to_automata_distr ();
6658 NDFA_time
= create_ticker ();
6659 ticker_off (&NDFA_time
);
6660 NDFA_to_DFA_time
= create_ticker ();
6661 ticker_off (&NDFA_to_DFA_time
);
6662 minimize_time
= create_ticker ();
6663 ticker_off (&minimize_time
);
6664 equiv_time
= create_ticker ();
6665 ticker_off (&equiv_time
);
6666 for (curr_automaton
= description
->first_automaton
;
6667 curr_automaton
!= NULL
;
6668 curr_automaton
= curr_automaton
->next_automaton
)
6670 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6671 fprintf (stderr
, "Create anonymous automaton ...");
6673 fprintf (stderr
, "Create automaton `%s'...",
6674 curr_automaton
->corresponding_automaton_decl
->name
);
6675 create_alt_states (curr_automaton
);
6676 form_ainsn_with_same_reservs (curr_automaton
);
6677 build_automaton (curr_automaton
);
6678 enumerate_states (curr_automaton
);
6679 ticker_on (&equiv_time
);
6680 set_insn_equiv_classes (curr_automaton
);
6681 ticker_off (&equiv_time
);
6682 fprintf (stderr
, "done\n");
6688 /* This page contains code for forming string representation of
6689 regexp. The representation is formed on IR obstack. So you should
6690 not work with IR obstack between regexp_representation and
6691 finish_regexp_representation calls. */
6693 /* This recursive function forms string representation of regexp
6694 (without tailing '\0'). */
6696 form_regexp (regexp
)
6701 if (regexp
->mode
== rm_unit
|| regexp
->mode
== rm_reserv
)
6703 const char *name
= (regexp
->mode
== rm_unit
6704 ? REGEXP_UNIT (regexp
)->name
6705 : REGEXP_RESERV (regexp
)->name
);
6707 obstack_grow (&irp
, name
, strlen (name
));
6709 else if (regexp
->mode
== rm_sequence
)
6710 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
6713 obstack_1grow (&irp
, ',');
6714 form_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
6716 else if (regexp
->mode
== rm_allof
)
6718 obstack_1grow (&irp
, '(');
6719 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
6722 obstack_1grow (&irp
, '+');
6723 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6724 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6725 obstack_1grow (&irp
, '(');
6726 form_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
6727 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6728 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6729 obstack_1grow (&irp
, ')');
6731 obstack_1grow (&irp
, ')');
6733 else if (regexp
->mode
== rm_oneof
)
6734 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
6737 obstack_1grow (&irp
, '|');
6738 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6739 obstack_1grow (&irp
, '(');
6740 form_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
6741 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6742 obstack_1grow (&irp
, ')');
6744 else if (regexp
->mode
== rm_repeat
)
6748 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6749 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6750 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6751 obstack_1grow (&irp
, '(');
6752 form_regexp (REGEXP_REPEAT (regexp
)->regexp
);
6753 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6754 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6755 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6756 obstack_1grow (&irp
, ')');
6757 sprintf (digits
, "*%d", REGEXP_REPEAT (regexp
)->repeat_num
);
6758 obstack_grow (&irp
, digits
, strlen (digits
));
6760 else if (regexp
->mode
== rm_nothing
)
6761 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
6766 /* The function returns string representation of REGEXP on IR
6769 regexp_representation (regexp
)
6772 form_regexp (regexp
);
6773 obstack_1grow (&irp
, '\0');
6774 return obstack_base (&irp
);
6777 /* The function frees memory allocated for last formed string
6778 representation of regexp. */
6780 finish_regexp_representation ()
6782 int length
= obstack_object_size (&irp
);
6784 obstack_blank_fast (&irp
, -length
);
6789 /* This page contains code for output PHR (pipeline hazards recognizer). */
6791 /* The function outputs minimal C type which is sufficient for
6792 representation numbers in range min_range_value and
6793 max_range_value. Because host machine and build machine may be
6794 different, we use here minimal values required by ANSI C standard
6795 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6799 output_range_type (f
, min_range_value
, max_range_value
)
6801 long int min_range_value
;
6802 long int max_range_value
;
6804 if (min_range_value
>= 0 && max_range_value
<= 255)
6805 fprintf (f
, "unsigned char");
6806 else if (min_range_value
>= -127 && max_range_value
<= 127)
6807 fprintf (f
, "signed char");
6808 else if (min_range_value
>= 0 && max_range_value
<= 65535)
6809 fprintf (f
, "unsigned short");
6810 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
6811 fprintf (f
, "short");
6816 /* The following macro value is used as value of member
6817 `longest_path_length' of state when we are processing path and the
6818 state on the path. */
6820 #define ON_THE_PATH -2
6822 /* The following recursive function searches for the length of the
6823 longest path starting from STATE which does not contain cycles and
6824 `cycle advance' arcs. */
6827 longest_path_length (state
)
6833 if (state
->longest_path_length
== ON_THE_PATH
)
6834 /* We don't expect the path cycle here. Our graph may contain
6835 only cycles with one state on the path not containing `cycle
6836 advance' arcs -- see comment below. */
6838 else if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
6839 /* We alreday visited the state. */
6840 return state
->longest_path_length
;
6843 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6844 /* Ignore cycles containing one state and `cycle advance' arcs. */
6845 if (arc
->to_state
!= state
6846 && (arc
->insn
->insn_reserv_decl
6847 != DECL_INSN_RESERV (advance_cycle_insn_decl
)))
6849 length
= longest_path_length (arc
->to_state
);
6850 if (length
> result
)
6853 state
->longest_path_length
= result
+ 1;
6857 /* The following variable value is value of the corresponding global
6858 variable in the automaton based pipeline interface. */
6860 static int max_dfa_issue_rate
;
6862 /* The following function processes the longest path length staring
6863 from STATE to find MAX_DFA_ISSUE_RATE. */
6866 process_state_longest_path_length (state
)
6871 value
= longest_path_length (state
);
6872 if (value
> max_dfa_issue_rate
)
6873 max_dfa_issue_rate
= value
;
6876 /* The following nacro value is name of the corresponding global
6877 variable in the automaton based pipeline interface. */
6879 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6881 /* The following function calculates value of the the corresponding
6882 global variable and outputs its declaration. */
6885 output_dfa_max_issue_rate ()
6887 automaton_t automaton
;
6889 if (UNDEFINED_LONGEST_PATH_LENGTH
== ON_THE_PATH
|| ON_THE_PATH
>= 0)
6891 max_dfa_issue_rate
= 0;
6892 for (automaton
= description
->first_automaton
;
6894 automaton
= automaton
->next_automaton
)
6895 pass_states (automaton
, process_state_longest_path_length
);
6896 fprintf (output_file
, "\nint %s = %d;\n",
6897 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
6900 /* The function outputs all initialization values of VECT with length
6903 output_vect (vect
, vect_length
)
6910 if (vect_length
== 0)
6911 fprintf (output_file
,
6912 "0 /* This is dummy el because the vect is empty */");
6917 fprintf (output_file
, "%5ld", (long) *vect
);
6919 if (els_on_line
== 10)
6922 fprintf (output_file
, ",\n");
6924 else if (vect_length
!= 0)
6925 fprintf (output_file
, ", ");
6929 while (vect_length
!= 0);
6933 /* The following is name of the structure which represents DFA(s) for
6935 #define CHIP_NAME "DFA_chip"
6937 /* The following is name of member which represents state of a DFA for
6940 output_chip_member_name (f
, automaton
)
6942 automaton_t automaton
;
6944 if (automaton
->corresponding_automaton_decl
== NULL
)
6945 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
6947 fprintf (f
, "%s_automaton_state",
6948 automaton
->corresponding_automaton_decl
->name
);
6951 /* The following is name of temporary variable which stores state of a
6954 output_temp_chip_member_name (f
, automaton
)
6956 automaton_t automaton
;
6959 output_chip_member_name (f
, automaton
);
6962 /* This is name of macro value which is code of pseudo_insn
6963 representing advancing cpu cycle. Its value is used as internal
6964 code unknown insn. */
6965 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6967 /* Output name of translate vector for given automaton. */
6969 output_translate_vect_name (f
, automaton
)
6971 automaton_t automaton
;
6973 if (automaton
->corresponding_automaton_decl
== NULL
)
6974 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
6976 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
6979 /* Output name for simple transition table representation. */
6981 output_trans_full_vect_name (f
, automaton
)
6983 automaton_t automaton
;
6985 if (automaton
->corresponding_automaton_decl
== NULL
)
6986 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6988 fprintf (f
, "%s_transitions",
6989 automaton
->corresponding_automaton_decl
->name
);
6992 /* Output name of comb vector of the transition table for given
6995 output_trans_comb_vect_name (f
, automaton
)
6997 automaton_t automaton
;
6999 if (automaton
->corresponding_automaton_decl
== NULL
)
7000 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
7002 fprintf (f
, "%s_transitions",
7003 automaton
->corresponding_automaton_decl
->name
);
7006 /* Output name of check vector of the transition table for given
7009 output_trans_check_vect_name (f
, automaton
)
7011 automaton_t automaton
;
7013 if (automaton
->corresponding_automaton_decl
== NULL
)
7014 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
7016 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
7019 /* Output name of base vector of the transition table for given
7022 output_trans_base_vect_name (f
, automaton
)
7024 automaton_t automaton
;
7026 if (automaton
->corresponding_automaton_decl
== NULL
)
7027 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
7029 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
7032 /* Output name for simple alternatives number representation. */
7034 output_state_alts_full_vect_name (f
, automaton
)
7036 automaton_t automaton
;
7038 if (automaton
->corresponding_automaton_decl
== NULL
)
7039 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7041 fprintf (f
, "%s_state_alts",
7042 automaton
->corresponding_automaton_decl
->name
);
7045 /* Output name of comb vector of the alternatives number table for given
7048 output_state_alts_comb_vect_name (f
, automaton
)
7050 automaton_t automaton
;
7052 if (automaton
->corresponding_automaton_decl
== NULL
)
7053 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7055 fprintf (f
, "%s_state_alts",
7056 automaton
->corresponding_automaton_decl
->name
);
7059 /* Output name of check vector of the alternatives number table for given
7062 output_state_alts_check_vect_name (f
, automaton
)
7064 automaton_t automaton
;
7066 if (automaton
->corresponding_automaton_decl
== NULL
)
7067 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
7069 fprintf (f
, "%s_check_state_alts",
7070 automaton
->corresponding_automaton_decl
->name
);
7073 /* Output name of base vector of the alternatives number table for given
7076 output_state_alts_base_vect_name (f
, automaton
)
7078 automaton_t automaton
;
7080 if (automaton
->corresponding_automaton_decl
== NULL
)
7081 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
7083 fprintf (f
, "%s_base_state_alts",
7084 automaton
->corresponding_automaton_decl
->name
);
7087 /* Output name of simple min issue delay table representation. */
7089 output_min_issue_delay_vect_name (f
, automaton
)
7091 automaton_t automaton
;
7093 if (automaton
->corresponding_automaton_decl
== NULL
)
7094 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
7096 fprintf (f
, "%s_min_issue_delay",
7097 automaton
->corresponding_automaton_decl
->name
);
7100 /* Output name of deadlock vector for given automaton. */
7102 output_dead_lock_vect_name (f
, automaton
)
7104 automaton_t automaton
;
7106 if (automaton
->corresponding_automaton_decl
== NULL
)
7107 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
7109 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
7112 /* Output name of reserved units table for AUTOMATON into file F. */
7114 output_reserved_units_table_name (f
, automaton
)
7116 automaton_t automaton
;
7118 if (automaton
->corresponding_automaton_decl
== NULL
)
7119 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
7121 fprintf (f
, "%s_reserved_units",
7122 automaton
->corresponding_automaton_decl
->name
);
7125 /* Name of the PHR interface macro. */
7126 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7128 /* Name of the PHR interface macro. */
7129 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7131 /* Names of an internal functions: */
7132 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7134 /* This is external type of DFA(s) state. */
7135 #define STATE_TYPE_NAME "state_t"
7137 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7139 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7141 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7143 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7145 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7147 /* Name of cache of insn dfa codes. */
7148 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7150 /* Name of length of cache of insn dfa codes. */
7151 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7153 /* Names of the PHR interface functions: */
7154 #define SIZE_FUNC_NAME "state_size"
7156 #define TRANSITION_FUNC_NAME "state_transition"
7158 #define STATE_ALTS_FUNC_NAME "state_alts"
7160 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7162 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7164 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7166 #define RESET_FUNC_NAME "state_reset"
7168 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7170 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7172 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7174 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7176 #define DFA_START_FUNC_NAME "dfa_start"
7178 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7180 /* Names of parameters of the PHR interface functions. */
7181 #define STATE_NAME "state"
7183 #define INSN_PARAMETER_NAME "insn"
7185 #define INSN2_PARAMETER_NAME "insn2"
7187 #define CHIP_PARAMETER_NAME "chip"
7189 #define FILE_PARAMETER_NAME "f"
7191 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7193 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7195 /* Names of the variables whose values are internal insn code of rtx
7197 #define INTERNAL_INSN_CODE_NAME "insn_code"
7199 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7201 /* Names of temporary variables in some functions. */
7202 #define TEMPORARY_VARIABLE_NAME "temp"
7204 #define I_VARIABLE_NAME "i"
7206 /* Name of result variable in some functions. */
7207 #define RESULT_VARIABLE_NAME "res"
7209 /* Name of function (attribute) to translate insn into number of insn
7210 alternatives reservation. */
7211 #define INSN_ALTS_FUNC_NAME "insn_alts"
7213 /* Name of function (attribute) to translate insn into internal insn
7215 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7217 /* Name of function (attribute) to translate insn into internal insn
7218 code with caching. */
7219 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7221 /* Name of function (attribute) to translate insn into internal insn
7223 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7225 /* Name of function (attribute) to translate insn into internal insn
7227 #define BYPASS_P_FUNC_NAME "bypass_p"
7229 /* Output C type which is used for representation of codes of states
7232 output_state_member_type (f
, automaton
)
7234 automaton_t automaton
;
7236 output_range_type (f
, 0, automaton
->achieved_states_num
);
7239 /* Output definition of the structure representing current DFA(s)
7242 output_chip_definitions ()
7244 automaton_t automaton
;
7246 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
7247 for (automaton
= description
->first_automaton
;
7249 automaton
= automaton
->next_automaton
)
7251 fprintf (output_file
, " ");
7252 output_state_member_type (output_file
, automaton
);
7253 fprintf (output_file
, " ");
7254 output_chip_member_name (output_file
, automaton
);
7255 fprintf (output_file
, ";\n");
7257 fprintf (output_file
, "};\n\n");
7259 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
7264 /* The function outputs translate vector of internal insn code into
7265 insn equivalence class number. The equivalence class number is
7266 used to access to table and vectors reprewsenting DFA(s). */
7268 output_translate_vect (automaton
)
7269 automaton_t automaton
;
7273 vla_hwint_t translate_vect
;
7275 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
7276 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
7277 for (insn_value
= 0; insn_value
<= description
->insns_num
; insn_value
++)
7278 /* Undefined value */
7279 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
7280 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7281 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
7282 = ainsn
->insn_equiv_class_num
;
7283 fprintf (output_file
,
7284 "/* Vector translating external insn codes to internal ones.*/\n");
7285 fprintf (output_file
, "static const ");
7286 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
7287 fprintf (output_file
, " ");
7288 output_translate_vect_name (output_file
, automaton
);
7289 fprintf (output_file
, "[] = {\n");
7290 output_vect (VLA_HWINT_BEGIN (translate_vect
),
7291 VLA_HWINT_LENGTH (translate_vect
));
7292 fprintf (output_file
, "};\n\n");
7293 VLA_HWINT_DELETE (translate_vect
);
7296 /* The value in a table state x ainsn -> something which represents
7298 static int undefined_vect_el_value
;
7300 /* The following function returns nonzero value if the best
7301 representation of the table is comb vector. */
7304 state_ainsn_table_t tab
;
7306 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
7307 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
7310 /* The following function creates new table for AUTOMATON. */
7311 static state_ainsn_table_t
7312 create_state_ainsn_table (automaton
)
7313 automaton_t automaton
;
7315 state_ainsn_table_t tab
;
7316 int full_vect_length
;
7319 tab
= create_node (sizeof (struct state_ainsn_table
));
7320 tab
->automaton
= automaton
;
7321 VLA_HWINT_CREATE (tab
->comb_vect
, 10000, "comb vector");
7322 VLA_HWINT_CREATE (tab
->check_vect
, 10000, "check vector");
7323 VLA_HWINT_CREATE (tab
->base_vect
, 1000, "base vector");
7324 VLA_HWINT_EXPAND (tab
->base_vect
, automaton
->achieved_states_num
);
7325 VLA_HWINT_CREATE (tab
->full_vect
, 10000, "full vector");
7326 full_vect_length
= (automaton
->insn_equiv_classes_num
7327 * automaton
->achieved_states_num
);
7328 VLA_HWINT_EXPAND (tab
->full_vect
, full_vect_length
);
7329 for (i
= 0; i
< full_vect_length
; i
++)
7330 VLA_HWINT (tab
->full_vect
, i
) = undefined_vect_el_value
;
7331 tab
->min_base_vect_el_value
= 0;
7332 tab
->max_base_vect_el_value
= 0;
7333 tab
->min_comb_vect_el_value
= 0;
7334 tab
->max_comb_vect_el_value
= 0;
7338 /* The following function outputs the best C representation of the
7339 table TAB of given TABLE_NAME. */
7341 output_state_ainsn_table (tab
, table_name
, output_full_vect_name_func
,
7342 output_comb_vect_name_func
,
7343 output_check_vect_name_func
,
7344 output_base_vect_name_func
)
7345 state_ainsn_table_t tab
;
7347 void (*output_full_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7348 void (*output_comb_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7349 void (*output_check_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7350 void (*output_base_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7352 if (!comb_vect_p (tab
))
7354 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7355 fprintf (output_file
, "static const ");
7356 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7357 tab
->max_comb_vect_el_value
);
7358 fprintf (output_file
, " ");
7359 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7360 fprintf (output_file
, "[] = {\n");
7361 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7362 VLA_HWINT_LENGTH (tab
->full_vect
));
7363 fprintf (output_file
, "};\n\n");
7367 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7368 fprintf (output_file
, "static const ");
7369 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7370 tab
->max_comb_vect_el_value
);
7371 fprintf (output_file
, " ");
7372 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7373 fprintf (output_file
, "[] = {\n");
7374 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7375 VLA_HWINT_LENGTH (tab
->comb_vect
));
7376 fprintf (output_file
, "};\n\n");
7377 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7378 fprintf (output_file
, "static const ");
7379 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7380 fprintf (output_file
, " ");
7381 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7382 fprintf (output_file
, "[] = {\n");
7383 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7384 VLA_HWINT_LENGTH (tab
->check_vect
));
7385 fprintf (output_file
, "};\n\n");
7386 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7387 fprintf (output_file
, "static const ");
7388 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7389 tab
->max_base_vect_el_value
);
7390 fprintf (output_file
, " ");
7391 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7392 fprintf (output_file
, "[] = {\n");
7393 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7394 VLA_HWINT_LENGTH (tab
->base_vect
));
7395 fprintf (output_file
, "};\n\n");
7399 /* The following function adds vector with length VECT_LENGTH and
7400 elements pointed by VECT to table TAB as its line with number
7403 add_vect (tab
, vect_num
, vect
, vect_length
)
7404 state_ainsn_table_t tab
;
7409 int real_vect_length
;
7410 vect_el_t
*comb_vect_start
;
7411 vect_el_t
*check_vect_start
;
7412 int comb_vect_index
;
7413 int comb_vect_els_num
;
7415 int first_unempty_vect_index
;
7416 int additional_els_num
;
7421 if (vect_length
== 0)
7423 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7424 if (vect
[vect_length
- 1] == undefined_vect_el_value
)
7426 /* Form full vector in the table: */
7427 for (i
= 0; i
< vect_length
; i
++)
7428 VLA_HWINT (tab
->full_vect
,
7429 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
7431 /* Form comb vector in the table: */
7432 if (VLA_HWINT_LENGTH (tab
->comb_vect
) != VLA_HWINT_LENGTH (tab
->check_vect
))
7434 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7435 comb_vect_els_num
= VLA_HWINT_LENGTH (tab
->comb_vect
);
7436 for (first_unempty_vect_index
= 0;
7437 first_unempty_vect_index
< vect_length
;
7438 first_unempty_vect_index
++)
7439 if (vect
[first_unempty_vect_index
] != undefined_vect_el_value
)
7441 /* Search for the place in comb vect for the inserted vect. */
7442 for (comb_vect_index
= 0;
7443 comb_vect_index
< comb_vect_els_num
;
7446 for (vect_index
= first_unempty_vect_index
;
7447 vect_index
< vect_length
7448 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7450 if (vect
[vect_index
] != undefined_vect_el_value
7451 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7452 != undefined_vect_el_value
))
7454 if (vect_index
>= vect_length
7455 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7458 /* Slot was found. */
7459 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7460 if (additional_els_num
< 0)
7461 additional_els_num
= 0;
7462 /* Expand comb and check vectors. */
7463 vect_el
= undefined_vect_el_value
;
7464 no_state_value
= tab
->automaton
->achieved_states_num
;
7465 while (additional_els_num
> 0)
7467 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7468 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7469 additional_els_num
--;
7471 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7472 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7473 if (VLA_HWINT_LENGTH (tab
->comb_vect
)
7474 < (size_t) (comb_vect_index
+ real_vect_length
))
7476 /* Fill comb and check vectors. */
7477 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7478 if (vect
[vect_index
] != undefined_vect_el_value
)
7480 if (comb_vect_start
[comb_vect_index
+ vect_index
]
7481 != undefined_vect_el_value
)
7483 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7484 if (vect
[vect_index
] < 0)
7486 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7487 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7488 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7489 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7490 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7492 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7493 tab
->max_base_vect_el_value
= comb_vect_index
;
7494 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7495 tab
->min_base_vect_el_value
= comb_vect_index
;
7496 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7499 /* Return number of out arcs of STATE. */
7501 out_state_arcs_num (state
)
7508 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7510 if (arc
->insn
== NULL
)
7512 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7518 /* Compare number of possible transitions from the states. */
7520 compare_transition_els_num (state_ptr_1
, state_ptr_2
)
7521 const void *state_ptr_1
;
7522 const void *state_ptr_2
;
7524 int transition_els_num_1
;
7525 int transition_els_num_2
;
7527 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7528 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7529 if (transition_els_num_1
< transition_els_num_2
)
7531 else if (transition_els_num_1
== transition_els_num_2
)
7537 /* The function adds element EL_VALUE to vector VECT for a table state
7540 add_vect_el (vect
, ainsn
, el_value
)
7545 int equiv_class_num
;
7550 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7551 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7552 vect_index
<= equiv_class_num
;
7554 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7555 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7558 /* This is for forming vector of states of an automaton. */
7559 static vla_ptr_t output_states_vect
;
7561 /* The function is called by function pass_states. The function adds
7562 STATE to `output_states_vect'. */
7564 add_states_vect_el (state
)
7567 VLA_PTR_ADD (output_states_vect
, state
);
7570 /* Form and output vectors (comb, check, base or full vector)
7571 representing transition table of AUTOMATON. */
7573 output_trans_table (automaton
)
7574 automaton_t automaton
;
7578 vla_hwint_t transition_vect
;
7580 undefined_vect_el_value
= automaton
->achieved_states_num
;
7581 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7582 /* Create vect of pointers to states ordered by num of transitions
7583 from the state (state with the maximum num is the first). */
7584 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7585 pass_states (automaton
, add_states_vect_el
);
7586 qsort (VLA_PTR_BEGIN (output_states_vect
),
7587 VLA_PTR_LENGTH (output_states_vect
),
7588 sizeof (state_t
), compare_transition_els_num
);
7589 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7590 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7591 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7594 VLA_HWINT_NULLIFY (transition_vect
);
7595 for (arc
= first_out_arc (*state_ptr
);
7597 arc
= next_out_arc (arc
))
7599 if (arc
->insn
== NULL
)
7601 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7602 add_vect_el (&transition_vect
, arc
->insn
,
7603 arc
->to_state
->order_state_num
);
7605 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7606 VLA_HWINT_BEGIN (transition_vect
),
7607 VLA_HWINT_LENGTH (transition_vect
));
7609 output_state_ainsn_table
7610 (automaton
->trans_table
, (char *) "state transitions",
7611 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7612 output_trans_check_vect_name
, output_trans_base_vect_name
);
7613 VLA_PTR_DELETE (output_states_vect
);
7614 VLA_HWINT_DELETE (transition_vect
);
7617 /* Form and output vectors (comb, check, base or simple vect)
7618 representing alts number table of AUTOMATON. The table is state x
7619 ainsn -> number of possible alternative reservations by the
7622 output_state_alts_table (automaton
)
7623 automaton_t automaton
;
7627 vla_hwint_t state_alts_vect
;
7629 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7630 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7631 /* Create vect of pointers to states ordered by num of transitions
7632 from the state (state with the maximum num is the first). */
7633 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7634 pass_states (automaton
, add_states_vect_el
);
7635 qsort (VLA_PTR_BEGIN (output_states_vect
),
7636 VLA_PTR_LENGTH (output_states_vect
),
7637 sizeof (state_t
), compare_transition_els_num
);
7638 /* Create base, comb, and check vectors. */
7639 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7640 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7641 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7644 VLA_HWINT_NULLIFY (state_alts_vect
);
7645 for (arc
= first_out_arc (*state_ptr
);
7647 arc
= next_out_arc (arc
))
7649 if (arc
->insn
== NULL
)
7651 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7652 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7654 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7655 VLA_HWINT_BEGIN (state_alts_vect
),
7656 VLA_HWINT_LENGTH (state_alts_vect
));
7658 output_state_ainsn_table
7659 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7660 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7661 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7662 VLA_PTR_DELETE (output_states_vect
);
7663 VLA_HWINT_DELETE (state_alts_vect
);
7666 /* The current number of passing states to find minimal issue delay
7667 value for an ainsn and state. */
7668 static int curr_state_pass_num
;
7671 /* This recursive function passes states to find minimal issue delay
7672 value for AINSN. The state being visited is STATE. The function
7673 returns minimal issue delay value for AINSN in STATE or -1 if we
7674 enter into a loop. */
7676 min_issue_delay_pass_states (state
, ainsn
)
7681 int min_insn_issue_delay
, insn_issue_delay
;
7683 if (state
->state_pass_num
== curr_state_pass_num
7684 || state
->min_insn_issue_delay
!= -1)
7685 /* We've entered into a loop or already have the correct value for
7686 given state and ainsn. */
7687 return state
->min_insn_issue_delay
;
7688 state
->state_pass_num
= curr_state_pass_num
;
7689 min_insn_issue_delay
= -1;
7690 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7691 if (arc
->insn
== ainsn
)
7693 min_insn_issue_delay
= 0;
7698 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7699 if (insn_issue_delay
!= -1)
7701 if (arc
->insn
->insn_reserv_decl
7702 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
7704 if (min_insn_issue_delay
== -1
7705 || min_insn_issue_delay
> insn_issue_delay
)
7707 min_insn_issue_delay
= insn_issue_delay
;
7708 if (insn_issue_delay
== 0)
7713 return min_insn_issue_delay
;
7716 /* The function searches minimal issue delay value for AINSN in STATE.
7717 The function can return negative value if we can not issue AINSN. We
7718 will report about it later. */
7720 min_issue_delay (state
, ainsn
)
7724 curr_state_pass_num
++;
7725 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7726 return state
->min_insn_issue_delay
;
7729 /* The function initiates code for finding minimal issue delay values.
7730 It should be called only once. */
7732 initiate_min_issue_delay_pass_states ()
7734 curr_state_pass_num
= 0;
7737 /* Form and output vectors representing minimal issue delay table of
7738 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7741 output_min_issue_delay_table (automaton
)
7742 automaton_t automaton
;
7744 vla_hwint_t min_issue_delay_vect
;
7745 vla_hwint_t compressed_min_issue_delay_vect
;
7746 vect_el_t min_delay
;
7751 /* Create vect of pointers to states ordered by num of transitions
7752 from the state (state with the maximum num is the first). */
7753 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7754 pass_states (automaton
, add_states_vect_el
);
7755 VLA_HWINT_CREATE (min_issue_delay_vect
, 1500, "min issue delay vector");
7756 VLA_HWINT_EXPAND (min_issue_delay_vect
,
7757 VLA_HWINT_LENGTH (output_states_vect
)
7758 * automaton
->insn_equiv_classes_num
);
7760 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
7761 * automaton
->insn_equiv_classes_num
);
7763 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
7764 automaton
->max_min_delay
= 0;
7765 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7766 if (ainsn
->first_ainsn_with_given_equialence_num
)
7768 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7769 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7771 (*state_ptr
)->min_insn_issue_delay
= -1;
7772 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7773 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7776 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
7777 if (automaton
->max_min_delay
< min_delay
)
7778 automaton
->max_min_delay
= min_delay
;
7779 VLA_HWINT (min_issue_delay_vect
,
7780 (*state_ptr
)->order_state_num
7781 * automaton
->insn_equiv_classes_num
7782 + ainsn
->insn_equiv_class_num
) = min_delay
;
7785 fprintf (output_file
, "/* Vector of min issue delay of insns.*/\n");
7786 fprintf (output_file
, "static const ");
7787 output_range_type (output_file
, 0, automaton
->max_min_delay
);
7788 fprintf (output_file
, " ");
7789 output_min_issue_delay_vect_name (output_file
, automaton
);
7790 fprintf (output_file
, "[] = {\n");
7791 /* Compress the vector */
7792 if (automaton
->max_min_delay
< 2)
7793 automaton
->min_issue_delay_table_compression_factor
= 8;
7794 else if (automaton
->max_min_delay
< 4)
7795 automaton
->min_issue_delay_table_compression_factor
= 4;
7796 else if (automaton
->max_min_delay
< 16)
7797 automaton
->min_issue_delay_table_compression_factor
= 2;
7799 automaton
->min_issue_delay_table_compression_factor
= 1;
7800 VLA_HWINT_CREATE (compressed_min_issue_delay_vect
, 1500,
7801 "compressed min issue delay vector");
7802 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect
,
7803 (VLA_HWINT_LENGTH (min_issue_delay_vect
)
7804 + automaton
->min_issue_delay_table_compression_factor
7806 / automaton
->min_issue_delay_table_compression_factor
);
7808 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
7810 VLA_HWINT (compressed_min_issue_delay_vect
, i
) = 0;
7811 for (i
= 0; i
< (int) VLA_HWINT_LENGTH (min_issue_delay_vect
); i
++)
7812 VLA_HWINT (compressed_min_issue_delay_vect
,
7813 i
/ automaton
->min_issue_delay_table_compression_factor
)
7814 |= (VLA_HWINT (min_issue_delay_vect
, i
)
7815 << (8 - (i
% automaton
->min_issue_delay_table_compression_factor
7817 * (8 / automaton
->min_issue_delay_table_compression_factor
)));
7818 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect
),
7819 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
));
7820 fprintf (output_file
, "};\n\n");
7821 VLA_PTR_DELETE (output_states_vect
);
7822 VLA_HWINT_DELETE (min_issue_delay_vect
);
7823 VLA_HWINT_DELETE (compressed_min_issue_delay_vect
);
7827 /* Number of states which contains transition only by advancing cpu
7829 static int locked_states_num
;
7832 /* Form and output vector representing the locked states of
7835 output_dead_lock_vect (automaton
)
7836 automaton_t automaton
;
7840 vla_hwint_t dead_lock_vect
;
7842 /* Create vect of pointers to states ordered by num of
7843 transitions from the state (state with the maximum num is the
7845 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7846 pass_states (automaton
, add_states_vect_el
);
7847 VLA_HWINT_CREATE (dead_lock_vect
, 1500, "is dead locked vector");
7848 VLA_HWINT_EXPAND (dead_lock_vect
, VLA_HWINT_LENGTH (output_states_vect
));
7849 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7850 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7853 arc
= first_out_arc (*state_ptr
);
7856 VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
)
7857 = (next_out_arc (arc
) == NULL
7858 && (arc
->insn
->insn_reserv_decl
7859 == DECL_INSN_RESERV (advance_cycle_insn_decl
)) ? 1 : 0);
7861 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
7862 locked_states_num
++;
7865 fprintf (output_file
, "/* Vector for locked state flags. */\n");
7866 fprintf (output_file
, "static const ");
7867 output_range_type (output_file
, 0, 1);
7868 fprintf (output_file
, " ");
7869 output_dead_lock_vect_name (output_file
, automaton
);
7870 fprintf (output_file
, "[] = {\n");
7871 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
7872 VLA_HWINT_LENGTH (dead_lock_vect
));
7873 fprintf (output_file
, "};\n\n");
7874 VLA_HWINT_DELETE (dead_lock_vect
);
7875 VLA_PTR_DELETE (output_states_vect
);
7878 /* Form and output vector representing reserved units of the states of
7881 output_reserved_units_table (automaton
)
7882 automaton_t automaton
;
7884 state_t
*curr_state_ptr
;
7885 vla_hwint_t reserved_units_table
;
7886 size_t state_byte_size
;
7889 /* Create vect of pointers to states. */
7890 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7891 pass_states (automaton
, add_states_vect_el
);
7892 /* Create vector. */
7893 VLA_HWINT_CREATE (reserved_units_table
, 1500, "reserved units vector");
7894 state_byte_size
= (description
->query_units_num
+ 7) / 8;
7895 VLA_HWINT_EXPAND (reserved_units_table
,
7896 VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7898 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7900 VLA_HWINT (reserved_units_table
, i
) = 0;
7901 for (curr_state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7902 curr_state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7905 for (i
= 0; i
< description
->units_num
; i
++)
7906 if (units_array
[i
]->query_p
)
7908 if (test_unit_reserv ((*curr_state_ptr
)->reservs
, 0, i
))
7909 VLA_HWINT (reserved_units_table
,
7910 (*curr_state_ptr
)->order_state_num
* state_byte_size
7911 + units_array
[i
]->query_num
/ 8)
7912 += (1 << (units_array
[i
]->query_num
% 8));
7915 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
7916 fprintf (output_file
, "static const ");
7917 output_range_type (output_file
, 0, 255);
7918 fprintf (output_file
, " ");
7919 output_reserved_units_table_name (output_file
, automaton
);
7920 fprintf (output_file
, "[] = {\n");
7921 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
7922 VLA_HWINT_LENGTH (reserved_units_table
));
7923 fprintf (output_file
, "};\n\n");
7924 VLA_HWINT_DELETE (reserved_units_table
);
7925 VLA_PTR_DELETE (output_states_vect
);
7928 /* The function outputs all tables representing DFA(s) used for fast
7929 pipeline hazards recognition. */
7933 automaton_t automaton
;
7936 locked_states_num
= 0;
7938 initiate_min_issue_delay_pass_states ();
7939 for (automaton
= description
->first_automaton
;
7941 automaton
= automaton
->next_automaton
)
7943 output_translate_vect (automaton
);
7944 output_trans_table (automaton
);
7945 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
7946 output_state_alts_table (automaton
);
7947 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7948 AUTOMATON_STATE_ALTS_MACRO_NAME
);
7949 output_min_issue_delay_table (automaton
);
7950 output_dead_lock_vect (automaton
);
7951 if (no_minimization_flag
)
7953 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
7954 output_reserved_units_table (automaton
);
7955 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7956 CPU_UNITS_QUERY_MACRO_NAME
);
7959 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
7960 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
7963 /* The function outputs definition and value of PHR interface variable
7964 `max_insn_queue_index' */
7966 output_max_insn_queue_index_def ()
7970 for (i
= 0; (1 << i
) <= description
->max_insn_reserv_cycles
; i
++)
7974 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
7978 /* The function outputs switch cases for insn reseravtions using
7979 function *output_automata_list_code. */
7981 output_insn_code_cases (output_automata_list_code
)
7982 void (*output_automata_list_code
) (automata_list_el_t
);
7987 for (i
= 0; i
< description
->decls_num
; i
++)
7989 decl
= description
->decls
[i
];
7990 if (decl
->mode
== dm_insn_reserv
)
7991 DECL_INSN_RESERV (decl
)->processed_p
= FALSE
;
7993 for (i
= 0; i
< description
->decls_num
; i
++)
7995 decl
= description
->decls
[i
];
7996 if (decl
->mode
== dm_insn_reserv
7997 && !DECL_INSN_RESERV (decl
)->processed_p
)
7999 for (j
= i
; j
< description
->decls_num
; j
++)
8001 decl2
= description
->decls
[j
];
8002 if (decl2
->mode
== dm_insn_reserv
8003 && (DECL_INSN_RESERV (decl2
)->important_automata_list
8004 == DECL_INSN_RESERV (decl
)->important_automata_list
))
8006 DECL_INSN_RESERV (decl2
)->processed_p
= TRUE
;
8007 fprintf (output_file
, " case %d: /* %s */\n",
8008 DECL_INSN_RESERV (decl2
)->insn_num
,
8009 DECL_INSN_RESERV (decl2
)->name
);
8012 (*output_automata_list_code
)
8013 (DECL_INSN_RESERV (decl
)->important_automata_list
);
8019 /* The function outputs a code for evaluation of a minimal delay of
8020 issue of insns which have reservations in given AUTOMATA_LIST. */
8022 output_automata_list_min_issue_delay_code (automata_list
)
8023 automata_list_el_t automata_list
;
8025 automata_list_el_t el
;
8026 automaton_t automaton
;
8028 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8030 automaton
= el
->automaton
;
8031 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8032 output_min_issue_delay_vect_name (output_file
, automaton
);
8033 fprintf (output_file
,
8034 (automaton
->min_issue_delay_table_compression_factor
!= 1
8036 output_translate_vect_name (output_file
, automaton
);
8037 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8038 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8039 output_chip_member_name (output_file
, automaton
);
8040 fprintf (output_file
, " * %d", automaton
->insn_equiv_classes_num
);
8041 if (automaton
->min_issue_delay_table_compression_factor
== 1)
8042 fprintf (output_file
, "];\n");
8045 fprintf (output_file
, ") / %d];\n",
8046 automaton
->min_issue_delay_table_compression_factor
);
8047 fprintf (output_file
, " %s = (%s >> (8 - (",
8048 TEMPORARY_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8049 output_translate_vect_name (output_file
, automaton
);
8051 (output_file
, " [%s] %% %d + 1) * %d)) & %d;\n",
8052 INTERNAL_INSN_CODE_NAME
,
8053 automaton
->min_issue_delay_table_compression_factor
,
8054 8 / automaton
->min_issue_delay_table_compression_factor
,
8055 (1 << (8 / automaton
->min_issue_delay_table_compression_factor
))
8058 if (el
== automata_list
)
8059 fprintf (output_file
, " %s = %s;\n",
8060 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8063 fprintf (output_file
, " if (%s > %s)\n",
8064 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8065 fprintf (output_file
, " %s = %s;\n",
8066 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8069 fprintf (output_file
, " break;\n\n");
8072 /* Output function `internal_min_issue_delay'. */
8074 output_internal_min_issue_delay_func ()
8076 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8077 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, CHIP_NAME
);
8078 fprintf (output_file
,
8079 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8080 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8081 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8082 CHIP_PARAMETER_NAME
);
8083 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n int %s;\n",
8084 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8085 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8086 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
8087 fprintf (output_file
,
8088 "\n default:\n %s = -1;\n break;\n }\n",
8089 RESULT_VARIABLE_NAME
);
8090 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8091 fprintf (output_file
, "}\n\n");
8094 /* The function outputs a code changing state after issue of insns
8095 which have reservations in given AUTOMATA_LIST. */
8097 output_automata_list_transition_code (automata_list
)
8098 automata_list_el_t automata_list
;
8100 automata_list_el_t el
, next_el
;
8102 fprintf (output_file
, " {\n");
8103 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8104 for (el
= automata_list
;; el
= next_el
)
8106 next_el
= el
->next_automata_list_el
;
8107 if (next_el
== NULL
)
8109 fprintf (output_file
, " ");
8110 output_state_member_type (output_file
, el
->automaton
);
8111 fprintf (output_file
, " ");
8112 output_temp_chip_member_name (output_file
, el
->automaton
);
8113 fprintf (output_file
, ";\n");
8115 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8116 if (comb_vect_p (el
->automaton
->trans_table
))
8118 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8119 output_trans_base_vect_name (output_file
, el
->automaton
);
8120 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8121 output_chip_member_name (output_file
, el
->automaton
);
8122 fprintf (output_file
, "] + ");
8123 output_translate_vect_name (output_file
, el
->automaton
);
8124 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8125 fprintf (output_file
, " if (");
8126 output_trans_check_vect_name (output_file
, el
->automaton
);
8127 fprintf (output_file
, " [%s] != %s->",
8128 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8129 output_chip_member_name (output_file
, el
->automaton
);
8130 fprintf (output_file
, ")\n");
8131 fprintf (output_file
, " return %s (%s, %s);\n",
8132 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8133 CHIP_PARAMETER_NAME
);
8134 fprintf (output_file
, " else\n");
8135 fprintf (output_file
, " ");
8136 if (el
->next_automata_list_el
!= NULL
)
8137 output_temp_chip_member_name (output_file
, el
->automaton
);
8140 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8141 output_chip_member_name (output_file
, el
->automaton
);
8143 fprintf (output_file
, " = ");
8144 output_trans_comb_vect_name (output_file
, el
->automaton
);
8145 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8149 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8150 output_trans_full_vect_name (output_file
, el
->automaton
);
8151 fprintf (output_file
, " [");
8152 output_translate_vect_name (output_file
, el
->automaton
);
8153 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8154 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8155 output_chip_member_name (output_file
, el
->automaton
);
8156 fprintf (output_file
, " * %d];\n",
8157 el
->automaton
->insn_equiv_classes_num
);
8158 fprintf (output_file
, " if (%s >= %d)\n",
8159 TEMPORARY_VARIABLE_NAME
, el
->automaton
->achieved_states_num
);
8160 fprintf (output_file
, " return %s (%s, %s);\n",
8161 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8162 CHIP_PARAMETER_NAME
);
8163 fprintf (output_file
, " else\n ");
8164 if (el
->next_automata_list_el
!= NULL
)
8165 output_temp_chip_member_name (output_file
, el
->automaton
);
8168 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8169 output_chip_member_name (output_file
, el
->automaton
);
8171 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
8173 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8174 for (el
= automata_list
;; el
= next_el
)
8176 next_el
= el
->next_automata_list_el
;
8177 if (next_el
== NULL
)
8179 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
8180 output_chip_member_name (output_file
, el
->automaton
);
8181 fprintf (output_file
, " = ");
8182 output_temp_chip_member_name (output_file
, el
->automaton
);
8183 fprintf (output_file
, ";\n");
8185 fprintf (output_file
, " return -1;\n");
8186 fprintf (output_file
, " }\n");
8189 /* Output function `internal_state_transition'. */
8191 output_internal_trans_func ()
8193 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8194 INTERNAL_TRANSITION_FUNC_NAME
, CHIP_NAME
);
8195 fprintf (output_file
,
8196 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8197 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8198 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
,
8199 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8200 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME
);
8201 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8202 output_insn_code_cases (output_automata_list_transition_code
);
8203 fprintf (output_file
, "\n default:\n return -1;\n }\n");
8204 fprintf (output_file
, "}\n\n");
8211 insn_code = dfa_insn_code (insn);
8212 if (insn_code > DFA__ADVANCE_CYCLE)
8216 insn_code = DFA__ADVANCE_CYCLE;
8218 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8219 code denotes CODE. */
8221 output_internal_insn_code_evaluation (insn_name
, insn_code_name
, code
)
8222 const char *insn_name
;
8223 const char *insn_code_name
;
8226 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
8227 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
8228 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
8229 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
8230 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
8231 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
8232 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
8236 /* The function outputs function `dfa_insn_code'. */
8238 output_dfa_insn_code_func ()
8240 fprintf (output_file
, "#ifdef __GNUC__\n__inline__\n#endif\n");
8241 fprintf (output_file
, "static int %s PARAMS ((rtx));\n",
8242 DFA_INSN_CODE_FUNC_NAME
);
8243 fprintf (output_file
, "static int\n%s (%s)\n\trtx %s;\n",
8244 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN_PARAMETER_NAME
);
8245 fprintf (output_file
, "{\n int %s;\n int %s;\n\n",
8246 INTERNAL_INSN_CODE_NAME
, TEMPORARY_VARIABLE_NAME
);
8247 fprintf (output_file
, " if (INSN_UID (%s) >= %s)\n {\n",
8248 INSN_PARAMETER_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8249 fprintf (output_file
, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
8250 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8251 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, INSN_PARAMETER_NAME
);
8252 fprintf (output_file
, " %s = xrealloc (%s, %s * sizeof (int));\n",
8253 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8254 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8255 fprintf (output_file
,
8256 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
8257 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8258 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8259 TEMPORARY_VARIABLE_NAME
);
8260 fprintf (output_file
, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
8261 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8262 INSN_PARAMETER_NAME
);
8263 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8264 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8265 fprintf (output_file
, " %s [INSN_UID (%s)] = %s;\n",
8266 DFA_INSN_CODES_VARIABLE_NAME
, INSN_PARAMETER_NAME
,
8267 INTERNAL_INSN_CODE_NAME
);
8268 fprintf (output_file
, " }\n return %s;\n}\n\n",
8269 INTERNAL_INSN_CODE_NAME
);
8272 /* The function outputs PHR interface function `state_transition'. */
8274 output_trans_func ()
8276 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8277 TRANSITION_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8278 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8279 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8280 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8281 INTERNAL_INSN_CODE_NAME
, -1);
8282 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8283 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8286 /* The function outputs a code for evaluation of alternative states
8287 number for insns which have reservations in given AUTOMATA_LIST. */
8289 output_automata_list_state_alts_code (automata_list
)
8290 automata_list_el_t automata_list
;
8292 automata_list_el_t el
;
8293 automaton_t automaton
;
8295 fprintf (output_file
, " {\n");
8296 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8297 if (comb_vect_p (el
->automaton
->state_alts_table
))
8299 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
8302 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8304 automaton
= el
->automaton
;
8305 if (comb_vect_p (automaton
->state_alts_table
))
8307 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8308 output_state_alts_base_vect_name (output_file
, automaton
);
8309 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8310 output_chip_member_name (output_file
, automaton
);
8311 fprintf (output_file
, "] + ");
8312 output_translate_vect_name (output_file
, automaton
);
8313 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8314 fprintf (output_file
, " if (");
8315 output_state_alts_check_vect_name (output_file
, automaton
);
8316 fprintf (output_file
, " [%s] != %s->",
8317 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8318 output_chip_member_name (output_file
, automaton
);
8319 fprintf (output_file
, ")\n");
8320 fprintf (output_file
, " return 0;\n");
8321 fprintf (output_file
, " else\n");
8322 fprintf (output_file
,
8323 (el
== automata_list
8324 ? " %s = " : " %s += "),
8325 RESULT_VARIABLE_NAME
);
8326 output_state_alts_comb_vect_name (output_file
, automaton
);
8327 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8331 fprintf (output_file
,
8332 (el
== automata_list
8333 ? "\n %s = " : " %s += "),
8334 RESULT_VARIABLE_NAME
);
8335 output_state_alts_full_vect_name (output_file
, automaton
);
8336 fprintf (output_file
, " [");
8337 output_translate_vect_name (output_file
, automaton
);
8338 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8339 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8340 output_chip_member_name (output_file
, automaton
);
8341 fprintf (output_file
, " * %d];\n",
8342 automaton
->insn_equiv_classes_num
);
8345 fprintf (output_file
, " break;\n }\n\n");
8348 /* Output function `internal_state_alts'. */
8350 output_internal_state_alts_func ()
8352 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8353 INTERNAL_STATE_ALTS_FUNC_NAME
, CHIP_NAME
);
8354 fprintf (output_file
,
8355 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8356 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8357 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8358 CHIP_PARAMETER_NAME
);
8359 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8360 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8361 output_insn_code_cases (output_automata_list_state_alts_code
);
8362 fprintf (output_file
,
8363 "\n default:\n %s = 0;\n break;\n }\n",
8364 RESULT_VARIABLE_NAME
);
8365 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8366 fprintf (output_file
, "}\n\n");
8369 /* The function outputs PHR interface function `state_alts'. */
8371 output_state_alts_func ()
8373 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8374 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8375 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8376 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8377 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8378 INTERNAL_INSN_CODE_NAME
, 0);
8379 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8380 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8383 /* Output function `min_issue_delay'. */
8385 output_min_issue_delay_func ()
8387 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8388 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8389 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8390 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8391 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8392 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8393 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8394 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8395 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8396 fprintf (output_file
, " }\n else\n %s = %s;\n",
8397 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8398 fprintf (output_file
, "\n return %s (%s, %s);\n",
8399 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8401 fprintf (output_file
, "}\n\n");
8404 /* Output function `internal_dead_lock'. */
8406 output_internal_dead_lock_func ()
8408 automaton_t automaton
;
8410 fprintf (output_file
, "static int %s PARAMS ((struct %s *));\n",
8411 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
);
8412 fprintf (output_file
, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8413 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_PARAMETER_NAME
, CHIP_NAME
,
8414 CHIP_PARAMETER_NAME
);
8415 fprintf (output_file
, "{\n");
8416 for (automaton
= description
->first_automaton
;
8418 automaton
= automaton
->next_automaton
)
8420 fprintf (output_file
, " if (");
8421 output_dead_lock_vect_name (output_file
, automaton
);
8422 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8423 output_chip_member_name (output_file
, automaton
);
8424 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8426 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8429 /* The function outputs PHR interface function `state_dead_lock_p'. */
8431 output_dead_lock_func ()
8433 fprintf (output_file
, "int\n%s (%s)\n\t%s %s;\n",
8434 DEAD_LOCK_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8435 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8436 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8439 /* Output function `internal_reset'. */
8441 output_internal_reset_func ()
8443 fprintf (output_file
, "static void %s PARAMS ((struct %s *));\n",
8444 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8445 fprintf (output_file
, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8446 INTERNAL_RESET_FUNC_NAME
, CHIP_PARAMETER_NAME
,
8447 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8448 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8449 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8452 /* The function outputs PHR interface function `state_size'. */
8456 fprintf (output_file
, "int\n%s ()\n", SIZE_FUNC_NAME
);
8457 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8460 /* The function outputs PHR interface function `state_reset'. */
8462 output_reset_func ()
8464 fprintf (output_file
, "void\n%s (%s)\n\t %s %s;\n",
8465 RESET_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8466 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8470 /* Output function `min_insn_conflict_delay'. */
8472 output_min_insn_conflict_delay_func ()
8474 fprintf (output_file
,
8475 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8476 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
,
8477 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8478 STATE_TYPE_NAME
, STATE_NAME
,
8479 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8480 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s;\n",
8481 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8482 INTERNAL_INSN2_CODE_NAME
);
8483 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8484 INTERNAL_INSN_CODE_NAME
, 0);
8485 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8486 INTERNAL_INSN2_CODE_NAME
, 0);
8487 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8488 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8489 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8490 fprintf (output_file
, " if (%s (%s, &%s) > 0)\n abort ();\n",
8491 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8492 fprintf (output_file
, " return %s (%s, &%s);\n",
8493 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8495 fprintf (output_file
, "}\n\n");
8498 /* Output function `internal_insn_latency'. */
8500 output_internal_insn_latency_func ()
8503 struct bypass_decl
*bypass
;
8506 fprintf (output_file
, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8507 INTERNAL_INSN_LATENCY_FUNC_NAME
);
8508 fprintf (output_file
, "static int\n%s (%s, %s, %s, %s)",
8509 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8510 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8511 INSN2_PARAMETER_NAME
);
8512 fprintf (output_file
, "\n\tint %s;\n\tint %s;\n",
8513 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8514 fprintf (output_file
,
8515 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8516 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8517 fprintf (output_file
, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8518 for (i
= 0; i
< description
->decls_num
; i
++)
8520 decl
= description
->decls
[i
];
8521 if (decl
->mode
== dm_insn_reserv
)
8523 fprintf (output_file
, " case %d:\n",
8524 DECL_INSN_RESERV (decl
)->insn_num
);
8525 if (DECL_INSN_RESERV (decl
)->bypass_list
== NULL
)
8526 fprintf (output_file
, " return (%s != %s ? %d : 0);\n",
8527 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8528 DECL_INSN_RESERV (decl
)->default_latency
);
8531 fprintf (output_file
, " switch (%s)\n {\n",
8532 INTERNAL_INSN2_CODE_NAME
);
8533 for (bypass
= DECL_INSN_RESERV (decl
)->bypass_list
;
8535 bypass
= bypass
->next
)
8537 fprintf (output_file
, " case %d:\n",
8538 bypass
->in_insn_reserv
->insn_num
);
8539 if (bypass
->bypass_guard_name
== NULL
)
8540 fprintf (output_file
, " return %d;\n",
8543 fprintf (output_file
,
8544 " return (%s (%s, %s) ? %d : %d);\n",
8545 bypass
->bypass_guard_name
, INSN_PARAMETER_NAME
,
8546 INSN2_PARAMETER_NAME
, bypass
->latency
,
8547 DECL_INSN_RESERV (decl
)->default_latency
);
8549 fprintf (output_file
, " default:\n");
8550 fprintf (output_file
,
8551 " return (%s != %s ? %d : 0);\n }\n",
8552 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8553 DECL_INSN_RESERV (decl
)->default_latency
);
8558 fprintf (output_file
, " default:\n return 0;\n }\n}\n\n");
8561 /* The function outputs PHR interface function `insn_latency'. */
8563 output_insn_latency_func ()
8565 fprintf (output_file
, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8566 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8567 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8568 fprintf (output_file
, "{\n int %s, %s;\n",
8569 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8570 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8571 INTERNAL_INSN_CODE_NAME
, 0);
8572 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8573 INTERNAL_INSN2_CODE_NAME
, 0);
8574 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8575 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8576 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8577 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8580 /* The function outputs PHR interface function `print_reservation'. */
8582 output_print_reservation_func ()
8587 fprintf (output_file
, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8588 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8589 INSN_PARAMETER_NAME
, FILE_PARAMETER_NAME
,
8590 INSN_PARAMETER_NAME
);
8591 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8592 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8593 fprintf (output_file
, " %s = %s (%s);\n",
8594 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8595 INSN_PARAMETER_NAME
);
8596 fprintf (output_file
, " if (%s > %s)\n",
8597 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8598 fprintf (output_file
, " {\n fprintf (%s, \"%s\");\n",
8599 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8600 fprintf (output_file
, " return;\n }\n");
8601 fprintf (output_file
, " }\n else\n");
8602 fprintf (output_file
,
8603 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8604 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8605 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8606 for (i
= 0; i
< description
->decls_num
; i
++)
8608 decl
= description
->decls
[i
];
8609 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8611 fprintf (output_file
,
8612 " case %d:\n", DECL_INSN_RESERV (decl
)->insn_num
);
8613 fprintf (output_file
,
8614 " fprintf (%s, \"%s\");\n break;\n",
8615 FILE_PARAMETER_NAME
,
8616 regexp_representation (DECL_INSN_RESERV (decl
)->regexp
));
8617 finish_regexp_representation ();
8620 fprintf (output_file
, " default:\n fprintf (%s, \"%s\");\n }\n",
8621 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8622 fprintf (output_file
, "}\n\n");
8625 /* The following function is used to sort unit declaration by their
8628 units_cmp (unit1
, unit2
)
8629 const void *unit1
, *unit2
;
8631 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8632 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8634 return strcmp (u1
->name
, u2
->name
);
8637 /* The following macro value is name of struct containing unit name
8639 #define NAME_CODE_STRUCT_NAME "name_code"
8641 /* The following macro value is name of table of struct name_code. */
8642 #define NAME_CODE_TABLE_NAME "name_code_table"
8644 /* The following macro values are member names for struct name_code. */
8645 #define NAME_MEMBER_NAME "name"
8646 #define CODE_MEMBER_NAME "code"
8648 /* The following macro values are local variable names for function
8649 `get_cpu_unit_code'. */
8650 #define CMP_VARIABLE_NAME "cmp"
8651 #define LOW_VARIABLE_NAME "l"
8652 #define MIDDLE_VARIABLE_NAME "m"
8653 #define HIGH_VARIABLE_NAME "h"
8655 /* The following function outputs function to obtain internal cpu unit
8656 code by the cpu unit name. */
8658 output_get_cpu_unit_code_func ()
8663 fprintf (output_file
, "int\n%s (%s)\n\tconst char *%s;\n",
8664 GET_CPU_UNIT_CODE_FUNC_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8665 CPU_UNIT_NAME_PARAMETER_NAME
);
8666 fprintf (output_file
, "{\n struct %s {const char *%s; int %s;};\n",
8667 NAME_CODE_STRUCT_NAME
, NAME_MEMBER_NAME
, CODE_MEMBER_NAME
);
8668 fprintf (output_file
, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME
,
8669 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8670 fprintf (output_file
, " static struct %s %s [] =\n {\n",
8671 NAME_CODE_STRUCT_NAME
, NAME_CODE_TABLE_NAME
);
8672 units
= (unit_decl_t
*) xmalloc (sizeof (unit_decl_t
)
8673 * description
->units_num
);
8674 memcpy (units
, units_array
, sizeof (unit_decl_t
) * description
->units_num
);
8675 qsort (units
, description
->units_num
, sizeof (unit_decl_t
), units_cmp
);
8676 for (i
= 0; i
< description
->units_num
; i
++)
8677 if (units
[i
]->query_p
)
8678 fprintf (output_file
, " {\"%s\", %d},\n",
8679 units
[i
]->name
, units
[i
]->query_num
);
8680 fprintf (output_file
, " };\n\n");
8681 fprintf (output_file
, " /* The following is binary search: */\n");
8682 fprintf (output_file
, " %s = 0;\n", LOW_VARIABLE_NAME
);
8683 fprintf (output_file
, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8684 HIGH_VARIABLE_NAME
, NAME_CODE_TABLE_NAME
, NAME_CODE_STRUCT_NAME
);
8685 fprintf (output_file
, " while (%s <= %s)\n {\n",
8686 LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8687 fprintf (output_file
, " %s = (%s + %s) / 2;\n",
8688 MIDDLE_VARIABLE_NAME
, LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8689 fprintf (output_file
, " %s = strcmp (%s, %s [%s].%s);\n",
8690 CMP_VARIABLE_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8691 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, NAME_MEMBER_NAME
);
8692 fprintf (output_file
, " if (%s < 0)\n", CMP_VARIABLE_NAME
);
8693 fprintf (output_file
, " %s = %s - 1;\n",
8694 HIGH_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8695 fprintf (output_file
, " else if (%s > 0)\n", CMP_VARIABLE_NAME
);
8696 fprintf (output_file
, " %s = %s + 1;\n",
8697 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8698 fprintf (output_file
, " else\n");
8699 fprintf (output_file
, " return %s [%s].%s;\n }\n",
8700 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, CODE_MEMBER_NAME
);
8701 fprintf (output_file
, " return -1;\n}\n\n");
8705 /* The following function outputs function to check reservation of cpu
8706 unit (its internal code will be passed as the function argument) in
8709 output_cpu_unit_reservation_p ()
8711 automaton_t automaton
;
8713 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8714 CPU_UNIT_RESERVATION_P_FUNC_NAME
, STATE_NAME
,
8715 CPU_CODE_PARAMETER_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8716 CPU_CODE_PARAMETER_NAME
);
8717 fprintf (output_file
, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8718 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
8719 description
->query_units_num
);
8720 for (automaton
= description
->first_automaton
;
8722 automaton
= automaton
->next_automaton
)
8724 fprintf (output_file
, " if ((");
8725 output_reserved_units_table_name (output_file
, automaton
);
8726 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
8727 output_chip_member_name (output_file
, automaton
);
8728 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8729 (description
->query_units_num
+ 7) / 8,
8730 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
8731 fprintf (output_file
, " return 1;\n");
8733 fprintf (output_file
, " return 0;\n}\n\n");
8736 /* The function outputs PHR interface function `dfa_start'. */
8738 output_dfa_start_func ()
8740 fprintf (output_file
,
8741 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8742 DFA_START_FUNC_NAME
, I_VARIABLE_NAME
,
8743 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8744 fprintf (output_file
, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8745 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8746 fprintf (output_file
,
8747 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8748 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
8749 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
8750 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
8753 /* The function outputs PHR interface function `dfa_finish'. */
8755 output_dfa_finish_func ()
8757 fprintf (output_file
, "void\n%s ()\n{\n free (%s);\n}\n\n",
8758 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8763 /* The page contains code for output description file (readable
8764 representation of original description and generated DFA(s). */
8766 /* The function outputs string representation of IR reservation. */
8768 output_regexp (regexp
)
8771 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
8772 finish_regexp_representation ();
8775 /* Output names of units in LIST separated by comma. */
8777 output_unit_set_el_list (list
)
8782 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
8785 fprintf (output_description_file
, ",");
8786 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
8790 /* The function outputs string representation of IR define_reservation
8791 and define_insn_reservation. */
8793 output_description ()
8798 for (i
= 0; i
< description
->decls_num
; i
++)
8800 decl
= description
->decls
[i
];
8801 if (decl
->mode
== dm_unit
)
8803 if (DECL_UNIT (decl
)->excl_list
!= NULL
)
8805 fprintf (output_description_file
, "unit %s exlusion_set: ",
8806 DECL_UNIT (decl
)->name
);
8807 output_unit_set_el_list (DECL_UNIT (decl
)->excl_list
);
8808 fprintf (output_description_file
, "\n");
8810 if (DECL_UNIT (decl
)->presence_list
!= NULL
)
8812 fprintf (output_description_file
, "unit %s presence_set: ",
8813 DECL_UNIT (decl
)->name
);
8814 output_unit_set_el_list (DECL_UNIT (decl
)->presence_list
);
8815 fprintf (output_description_file
, "\n");
8817 if (DECL_UNIT (decl
)->absence_list
!= NULL
)
8819 fprintf (output_description_file
, "unit %s absence_set: ",
8820 DECL_UNIT (decl
)->name
);
8821 output_unit_set_el_list (DECL_UNIT (decl
)->absence_list
);
8822 fprintf (output_description_file
, "\n");
8826 fprintf (output_description_file
, "\n");
8827 for (i
= 0; i
< description
->decls_num
; i
++)
8829 decl
= description
->decls
[i
];
8830 if (decl
->mode
== dm_reserv
)
8832 fprintf (output_description_file
, "reservation ");
8833 fprintf (output_description_file
, DECL_RESERV (decl
)->name
);
8834 fprintf (output_description_file
, ": ");
8835 output_regexp (DECL_RESERV (decl
)->regexp
);
8836 fprintf (output_description_file
, "\n");
8838 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8840 fprintf (output_description_file
, "insn reservation %s ",
8841 DECL_INSN_RESERV (decl
)->name
);
8842 print_rtl (output_description_file
,
8843 DECL_INSN_RESERV (decl
)->condexp
);
8844 fprintf (output_description_file
, ": ");
8845 output_regexp (DECL_INSN_RESERV (decl
)->regexp
);
8846 fprintf (output_description_file
, "\n");
8848 else if (decl
->mode
== dm_bypass
)
8849 fprintf (output_description_file
, "bypass %d %s %s\n",
8850 DECL_BYPASS (decl
)->latency
,
8851 DECL_BYPASS (decl
)->out_insn_name
,
8852 DECL_BYPASS (decl
)->in_insn_name
);
8854 fprintf (output_description_file
, "\n\f\n");
8857 /* The function outputs name of AUTOMATON. */
8859 output_automaton_name (f
, automaton
)
8861 automaton_t automaton
;
8863 if (automaton
->corresponding_automaton_decl
== NULL
)
8864 fprintf (f
, "#%d", automaton
->automaton_order_num
);
8866 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
8869 /* Maximal length of line for pretty printing into description
8871 #define MAX_LINE_LENGTH 70
8873 /* The function outputs units name belonging to AUTOMATON. */
8875 output_automaton_units (automaton
)
8876 automaton_t automaton
;
8880 int curr_line_length
;
8881 int there_is_an_automaton_unit
;
8884 fprintf (output_description_file
, "\n Coresponding units:\n");
8885 fprintf (output_description_file
, " ");
8886 curr_line_length
= 4;
8887 there_is_an_automaton_unit
= 0;
8888 for (i
= 0; i
< description
->decls_num
; i
++)
8890 decl
= description
->decls
[i
];
8891 if (decl
->mode
== dm_unit
8892 && (DECL_UNIT (decl
)->corresponding_automaton_num
8893 == automaton
->automaton_order_num
))
8895 there_is_an_automaton_unit
= 1;
8896 name
= DECL_UNIT (decl
)->name
;
8897 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
8899 curr_line_length
= strlen (name
) + 4;
8900 fprintf (output_description_file
, "\n ");
8904 curr_line_length
+= strlen (name
) + 1;
8905 fprintf (output_description_file
, " ");
8907 fprintf (output_description_file
, name
);
8910 if (!there_is_an_automaton_unit
)
8911 fprintf (output_description_file
, "<None>");
8912 fprintf (output_description_file
, "\n\n");
8915 /* The following variable is used for forming array of all possible cpu unit
8916 reservations described by the current DFA state. */
8917 static vla_ptr_t state_reservs
;
8919 /* The function forms `state_reservs' for STATE. */
8921 add_state_reservs (state
)
8924 alt_state_t curr_alt_state
;
8925 reserv_sets_t reservs
;
8927 if (state
->component_states
!= NULL
)
8928 for (curr_alt_state
= state
->component_states
;
8929 curr_alt_state
!= NULL
;
8930 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
8931 add_state_reservs (curr_alt_state
->state
);
8934 reservs
= state
->reservs
;
8935 VLA_PTR_ADD (state_reservs
, reservs
);
8939 /* The function outputs readable represenatation of all out arcs of
8942 output_state_arcs (state
)
8948 int curr_line_length
;
8950 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
8953 if (!ainsn
->first_insn_with_same_reservs
)
8955 fprintf (output_description_file
, " ");
8956 curr_line_length
= 7;
8957 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
8960 insn_name
= ainsn
->insn_reserv_decl
->name
;
8961 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
8963 if (ainsn
!= arc
->insn
)
8965 fprintf (output_description_file
, ",\n ");
8966 curr_line_length
= strlen (insn_name
) + 6;
8969 curr_line_length
+= strlen (insn_name
);
8973 curr_line_length
+= strlen (insn_name
);
8974 if (ainsn
!= arc
->insn
)
8976 curr_line_length
+= 2;
8977 fprintf (output_description_file
, ", ");
8980 fprintf (output_description_file
, insn_name
);
8981 ainsn
= ainsn
->next_same_reservs_insn
;
8983 while (ainsn
!= NULL
);
8984 fprintf (output_description_file
, " %d (%d)\n",
8985 arc
->to_state
->order_state_num
, arc
->state_alts
);
8987 fprintf (output_description_file
, "\n");
8990 /* The following function is used for sorting possible cpu unit
8991 reservation of a DFA state. */
8993 state_reservs_cmp (reservs_ptr_1
, reservs_ptr_2
)
8994 const void *reservs_ptr_1
;
8995 const void *reservs_ptr_2
;
8997 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
8998 *(reserv_sets_t
*) reservs_ptr_2
);
9001 /* The following function is used for sorting possible cpu unit
9002 reservation of a DFA state. */
9004 remove_state_duplicate_reservs ()
9006 reserv_sets_t
*reservs_ptr
;
9007 reserv_sets_t
*last_formed_reservs_ptr
;
9009 last_formed_reservs_ptr
= NULL
;
9010 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9011 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9013 if (last_formed_reservs_ptr
== NULL
)
9014 last_formed_reservs_ptr
= reservs_ptr
;
9015 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
9017 ++last_formed_reservs_ptr
;
9018 *last_formed_reservs_ptr
= *reservs_ptr
;
9020 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
9023 /* The following function output readable representation of DFA(s)
9024 state used for fast recognition of pipeline hazards. State is
9025 described by possible (current and scehduled) cpu unit
9028 output_state (state
)
9031 reserv_sets_t
*reservs_ptr
;
9033 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
9034 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
9035 fprintf (output_description_file
,
9036 state
->new_cycle_p
? " (new cycle)\n" : "\n");
9037 add_state_reservs (state
);
9038 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
9039 sizeof (reserv_sets_t
), state_reservs_cmp
);
9040 remove_state_duplicate_reservs ();
9041 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9042 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9045 fprintf (output_description_file
, " ");
9046 output_reserv_sets (output_description_file
, *reservs_ptr
);
9047 fprintf (output_description_file
, "\n");
9049 fprintf (output_description_file
, "\n");
9050 output_state_arcs (state
);
9051 VLA_PTR_DELETE (state_reservs
);
9054 /* The following function output readable representation of
9055 DFAs used for fast recognition of pipeline hazards. */
9057 output_automaton_descriptions ()
9059 automaton_t automaton
;
9061 for (automaton
= description
->first_automaton
;
9063 automaton
= automaton
->next_automaton
)
9065 fprintf (output_description_file
, "\nAutomaton ");
9066 output_automaton_name (output_description_file
, automaton
);
9067 fprintf (output_description_file
, "\n");
9068 output_automaton_units (automaton
);
9069 pass_states (automaton
, output_state
);
9075 /* The page contains top level function for generation DFA(s) used for
9078 /* The function outputs statistics about work of different phases of
9081 output_statistics (f
)
9084 automaton_t automaton
;
9086 int transition_comb_vect_els
= 0;
9087 int transition_full_vect_els
= 0;
9088 int state_alts_comb_vect_els
= 0;
9089 int state_alts_full_vect_els
= 0;
9090 int min_issue_delay_vect_els
= 0;
9093 for (automaton
= description
->first_automaton
;
9095 automaton
= automaton
->next_automaton
)
9097 fprintf (f
, "\nAutomaton ");
9098 output_automaton_name (f
, automaton
);
9099 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
9100 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
9101 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
9102 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
9103 if (!no_minimization_flag
)
9104 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9105 automaton
->minimal_DFA_states_num
,
9106 automaton
->minimal_DFA_arcs_num
);
9107 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
9108 description
->insns_num
, automaton
->insn_equiv_classes_num
);
9111 (f
, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9112 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
),
9113 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
),
9114 (comb_vect_p (automaton
->trans_table
)
9115 ? "use comb vect" : "use simple vect"));
9117 (f
, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9118 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
),
9119 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
),
9120 (comb_vect_p (automaton
->state_alts_table
)
9121 ? "use comb vect" : "use simple vect"));
9123 (f
, "%5ld min delay table els, compression factor %d\n",
9124 (long) automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
,
9125 automaton
->min_issue_delay_table_compression_factor
);
9126 transition_comb_vect_els
9127 += VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
);
9128 transition_full_vect_els
9129 += VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
);
9130 state_alts_comb_vect_els
9131 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
);
9132 state_alts_full_vect_els
9133 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
);
9134 min_issue_delay_vect_els
9135 += automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
;
9139 fprintf (f
, "\n%5d all allocated states, %5d all allocated arcs\n",
9140 allocated_states_num
, allocated_arcs_num
);
9141 fprintf (f
, "%5d all allocated alternative states\n",
9142 allocated_alt_states_num
);
9143 fprintf (f
, "%5d all transition comb vector els, %5d all trans table els\n",
9144 transition_comb_vect_els
, transition_full_vect_els
);
9146 (f
, "%5d all state alts comb vector els, %5d all state alts table els\n",
9147 state_alts_comb_vect_els
, state_alts_full_vect_els
);
9148 fprintf (f
, "%5d all min delay table els\n", min_issue_delay_vect_els
);
9149 fprintf (f
, "%5d locked states num\n", locked_states_num
);
9153 /* The function output times of work of different phases of DFA
9156 output_time_statistics (f
)
9159 fprintf (f
, "\n transformation: ");
9160 print_active_time (f
, transform_time
);
9161 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
9162 print_active_time (f
, NDFA_time
);
9165 fprintf (f
, ", NDFA -> DFA: ");
9166 print_active_time (f
, NDFA_to_DFA_time
);
9168 fprintf (f
, "\n DFA minimization: ");
9169 print_active_time (f
, minimize_time
);
9170 fprintf (f
, ", making insn equivalence: ");
9171 print_active_time (f
, equiv_time
);
9172 fprintf (f
, "\n all automaton generation: ");
9173 print_active_time (f
, automaton_generation_time
);
9174 fprintf (f
, ", output: ");
9175 print_active_time (f
, output_time
);
9179 /* The function generates DFA (deterministic finate state automaton)
9180 for fast recognition of pipeline hazards. No errors during
9181 checking must be fixed before this function call. */
9185 automata_num
= split_argument
;
9186 if (description
->units_num
< automata_num
)
9187 automata_num
= description
->units_num
;
9190 initiate_automata_lists ();
9191 initiate_pass_states ();
9192 initiate_excl_sets ();
9193 initiate_presence_absence_sets ();
9194 automaton_generation_time
= create_ticker ();
9196 ticker_off (&automaton_generation_time
);
9201 /* The following function creates insn attribute whose values are
9202 number alternatives in insn reservations. */
9204 make_insn_alts_attr ()
9210 condexp
= rtx_alloc (COND
);
9211 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9212 XEXP (condexp
, 1) = make_numeric_value (0);
9213 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9215 decl
= description
->decls
[i
];
9216 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9218 XVECEXP (condexp
, 0, 2 * insn_num
)
9219 = DECL_INSN_RESERV (decl
)->condexp
;
9220 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9221 = make_numeric_value
9222 (DECL_INSN_RESERV (decl
)->transformed_regexp
->mode
!= rm_oneof
9223 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl
)
9224 ->transformed_regexp
)->regexps_num
);
9228 if (description
->insns_num
!= insn_num
+ 1)
9230 make_internal_attr (attr_printf (sizeof ("*")
9231 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
9232 "*%s", INSN_ALTS_FUNC_NAME
),
9238 /* The following function creates attribute which is order number of
9239 insn in pipeline hazard description translator. */
9241 make_internal_dfa_insn_code_attr ()
9247 condexp
= rtx_alloc (COND
);
9248 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9250 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl
)
9252 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9254 decl
= description
->decls
[i
];
9255 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9257 XVECEXP (condexp
, 0, 2 * insn_num
)
9258 = DECL_INSN_RESERV (decl
)->condexp
;
9259 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9260 = make_numeric_value (DECL_INSN_RESERV (decl
)->insn_num
);
9264 if (description
->insns_num
!= insn_num
+ 1)
9267 (attr_printf (sizeof ("*")
9268 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
9269 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
9275 /* The following function creates attribute which order number of insn
9276 in pipeline hazard description translator. */
9278 make_default_insn_latency_attr ()
9284 condexp
= rtx_alloc (COND
);
9285 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9286 XEXP (condexp
, 1) = make_numeric_value (0);
9287 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9289 decl
= description
->decls
[i
];
9290 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9292 XVECEXP (condexp
, 0, 2 * insn_num
)
9293 = DECL_INSN_RESERV (decl
)->condexp
;
9294 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9295 = make_numeric_value (DECL_INSN_RESERV (decl
)->default_latency
);
9299 if (description
->insns_num
!= insn_num
+ 1)
9301 make_internal_attr (attr_printf (sizeof ("*")
9302 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
9303 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
9309 /* The following function creates attribute which returns 1 if given
9310 output insn has bypassing and 0 otherwise. */
9315 int bypass_insns_num
= 0;
9319 for (i
= 0; i
< description
->decls_num
; i
++)
9321 decl
= description
->decls
[i
];
9322 if (decl
->mode
== dm_insn_reserv
9323 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9324 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9327 if (bypass_insns_num
== 0)
9328 result_rtx
= make_numeric_value (0);
9331 result_rtx
= rtx_alloc (COND
);
9332 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
9333 XEXP (result_rtx
, 1) = make_numeric_value (0);
9335 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
9337 decl
= description
->decls
[i
];
9338 if (decl
->mode
== dm_insn_reserv
9339 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9340 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9342 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9343 = DECL_INSN_RESERV (decl
)->condexp
;
9344 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9345 = make_numeric_value (1);
9350 make_internal_attr (attr_printf (sizeof ("*")
9351 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9352 "*%s", BYPASS_P_FUNC_NAME
),
9358 /* This page mainly contains top level functions of pipeline hazards
9359 description translator. */
9361 /* The following macro value is suffix of name of description file of
9362 pipeline hazards description translator. */
9363 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9365 /* The function returns suffix of given file name. The returned
9366 string can not be changed. */
9368 file_name_suffix (file_name
)
9369 const char *file_name
;
9371 const char *last_period
;
9373 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9374 if (*file_name
== '.')
9375 last_period
= file_name
;
9376 return (last_period
== NULL
? file_name
: last_period
);
9379 /* The function returns base name of given file name, i.e. pointer to
9380 first char after last `/' (or `\' for WIN32) in given file name,
9381 given file name itself if the directory name is absent. The
9382 returned string can not be changed. */
9384 base_file_name (file_name
)
9385 const char *file_name
;
9387 int directory_name_length
;
9389 directory_name_length
= strlen (file_name
);
9391 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9392 && file_name
[directory_name_length
] != '\\')
9394 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9396 directory_name_length
--;
9397 return file_name
+ directory_name_length
+ 1;
9400 /* The following is top level function to initialize the work of
9401 pipeline hazards description translator. */
9403 initiate_automaton_gen (argc
, argv
)
9407 const char *base_name
;
9411 split_argument
= 0; /* default value */
9412 no_minimization_flag
= 0;
9416 for (i
= 2; i
< argc
; i
++)
9417 if (strcmp (argv
[i
], NO_MINIMIZATION_OPTION
) == 0)
9418 no_minimization_flag
= 1;
9419 else if (strcmp (argv
[i
], TIME_OPTION
) == 0)
9421 else if (strcmp (argv
[i
], V_OPTION
) == 0)
9423 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9425 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9427 else if (strcmp (argv
[i
], "-split") == 0)
9430 fatal ("-split has no argument.");
9431 fatal ("option `-split' has not been implemented yet\n");
9432 /* split_argument = atoi (argument_vect [i + 1]); */
9434 VLA_PTR_CREATE (decls
, 150, "decls");
9435 /* Initialize IR storage. */
9436 obstack_init (&irp
);
9437 initiate_automaton_decl_table ();
9438 initiate_insn_decl_table ();
9439 initiate_decl_table ();
9440 output_file
= stdout
;
9441 output_description_file
= NULL
;
9442 base_name
= base_file_name (argv
[1]);
9443 obstack_grow (&irp
, base_name
,
9444 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9445 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9446 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9447 obstack_1grow (&irp
, '\0');
9448 output_description_file_name
= obstack_base (&irp
);
9449 obstack_finish (&irp
);
9452 /* The following function checks existence at least one arc marked by
9455 check_automata_insn_issues ()
9457 automaton_t automaton
;
9458 ainsn_t ainsn
, reserv_ainsn
;
9460 for (automaton
= description
->first_automaton
;
9462 automaton
= automaton
->next_automaton
)
9464 for (ainsn
= automaton
->ainsn_list
;
9466 ainsn
= ainsn
->next_ainsn
)
9467 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9469 for (reserv_ainsn
= ainsn
;
9470 reserv_ainsn
!= NULL
;
9471 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9472 if (automaton
->corresponding_automaton_decl
!= NULL
)
9475 error ("Automaton `%s': Insn `%s' will never be issued",
9476 automaton
->corresponding_automaton_decl
->name
,
9477 reserv_ainsn
->insn_reserv_decl
->name
);
9480 ("Automaton `%s': Insn `%s' will never be issued",
9481 automaton
->corresponding_automaton_decl
->name
,
9482 reserv_ainsn
->insn_reserv_decl
->name
);
9487 error ("Insn `%s' will never be issued",
9488 reserv_ainsn
->insn_reserv_decl
->name
);
9490 warning ("Insn `%s' will never be issued",
9491 reserv_ainsn
->insn_reserv_decl
->name
);
9497 /* The following vla is used for storing pointers to all achieved
9499 static vla_ptr_t automaton_states
;
9501 /* This function is called by function pass_states to add an achieved
9504 add_automaton_state (state
)
9507 VLA_PTR_ADD (automaton_states
, state
);
9510 /* The following function forms list of important automata (whose
9511 states may be changed after the insn issue) for each insn. */
9513 form_important_insn_automata_lists ()
9515 automaton_t automaton
;
9522 VLA_PTR_CREATE (automaton_states
, 1500,
9523 "automaton states for forming important insn automata sets");
9524 /* Mark important ainsns. */
9525 for (automaton
= description
->first_automaton
;
9527 automaton
= automaton
->next_automaton
)
9529 VLA_PTR_NULLIFY (automaton_states
);
9530 pass_states (automaton
, add_automaton_state
);
9531 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9532 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9535 for (arc
= first_out_arc (*state_ptr
);
9537 arc
= next_out_arc (arc
))
9538 if (arc
->to_state
!= *state_ptr
)
9540 if (!arc
->insn
->first_insn_with_same_reservs
)
9542 for (ainsn
= arc
->insn
;
9544 ainsn
= ainsn
->next_same_reservs_insn
)
9545 ainsn
->important_p
= TRUE
;
9549 VLA_PTR_DELETE (automaton_states
);
9550 /* Create automata sets for the insns. */
9551 for (i
= 0; i
< description
->decls_num
; i
++)
9553 decl
= description
->decls
[i
];
9554 if (decl
->mode
== dm_insn_reserv
)
9556 automata_list_start ();
9557 for (automaton
= description
->first_automaton
;
9559 automaton
= automaton
->next_automaton
)
9560 for (ainsn
= automaton
->ainsn_list
;
9562 ainsn
= ainsn
->next_ainsn
)
9563 if (ainsn
->important_p
9564 && ainsn
->insn_reserv_decl
== DECL_INSN_RESERV (decl
))
9566 automata_list_add (automaton
);
9569 DECL_INSN_RESERV (decl
)->important_automata_list
9570 = automata_list_finish ();
9576 /* The following is top level function to generate automat(a,on) for
9577 fast recognition of pipeline hazards. */
9583 description
= create_node (sizeof (struct description
)
9584 /* One entry for cycle advancing insn. */
9585 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9586 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9587 description
->query_units_num
= 0;
9588 for (i
= 0; i
< description
->decls_num
; i
++)
9590 description
->decls
[i
] = VLA_PTR (decls
, i
);
9591 if (description
->decls
[i
]->mode
== dm_unit
9592 && DECL_UNIT (description
->decls
[i
])->query_p
)
9593 DECL_UNIT (description
->decls
[i
])->query_num
9594 = description
->query_units_num
++;
9596 all_time
= create_ticker ();
9597 check_time
= create_ticker ();
9598 fprintf (stderr
, "Check description...");
9600 check_all_description ();
9601 fprintf (stderr
, "done\n");
9602 ticker_off (&check_time
);
9603 generation_time
= create_ticker ();
9606 transform_insn_regexps ();
9607 check_unit_distributions_to_automata ();
9612 check_automata_insn_issues ();
9616 form_important_insn_automata_lists ();
9617 fprintf (stderr
, "Generation of attributes...");
9619 make_internal_dfa_insn_code_attr ();
9620 make_insn_alts_attr ();
9621 make_default_insn_latency_attr ();
9622 make_bypass_attr ();
9623 fprintf (stderr
, "done\n");
9625 ticker_off (&generation_time
);
9626 ticker_off (&all_time
);
9627 fprintf (stderr
, "All other genattrtab stuff...");
9631 /* The following is top level function to output PHR and to finish
9632 work with pipeline description translator. */
9636 fprintf (stderr
, "done\n");
9638 fatal ("Errors in DFA description");
9639 ticker_on (&all_time
);
9640 output_time
= create_ticker ();
9641 fprintf (stderr
, "Forming and outputing automata tables...");
9643 output_dfa_max_issue_rate ();
9645 fprintf (stderr
, "done\n");
9646 fprintf (stderr
, "Output functions to work with automata...");
9648 output_chip_definitions ();
9649 output_max_insn_queue_index_def ();
9650 output_internal_min_issue_delay_func ();
9651 output_internal_trans_func ();
9652 /* Cache of insn dfa codes: */
9653 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9654 fprintf (output_file
, "\nstatic int %s;\n\n",
9655 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9656 output_dfa_insn_code_func ();
9657 output_trans_func ();
9658 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
9659 output_internal_state_alts_func ();
9660 output_state_alts_func ();
9661 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9662 AUTOMATON_STATE_ALTS_MACRO_NAME
);
9663 output_min_issue_delay_func ();
9664 output_internal_dead_lock_func ();
9665 output_dead_lock_func ();
9666 output_size_func ();
9667 output_internal_reset_func ();
9668 output_reset_func ();
9669 output_min_insn_conflict_delay_func ();
9670 output_internal_insn_latency_func ();
9671 output_insn_latency_func ();
9672 output_print_reservation_func ();
9673 if (no_minimization_flag
)
9675 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
9676 output_get_cpu_unit_code_func ();
9677 output_cpu_unit_reservation_p ();
9678 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9679 CPU_UNITS_QUERY_MACRO_NAME
);
9681 output_dfa_start_func ();
9682 output_dfa_finish_func ();
9683 fprintf (stderr
, "done\n");
9686 output_description_file
= fopen (output_description_file_name
, "w");
9687 if (output_description_file
== NULL
)
9689 perror (output_description_file_name
);
9690 exit (FATAL_EXIT_CODE
);
9692 fprintf (stderr
, "Output automata description...");
9694 output_description ();
9695 output_automaton_descriptions ();
9696 fprintf (stderr
, "done\n");
9697 output_statistics (output_description_file
);
9699 output_statistics (stderr
);
9700 ticker_off (&output_time
);
9701 output_time_statistics (stderr
);
9704 finish_automata_lists ();
9707 fprintf (stderr
, "Summary:\n");
9708 fprintf (stderr
, " check time ");
9709 print_active_time (stderr
, check_time
);
9710 fprintf (stderr
, ", generation time ");
9711 print_active_time (stderr
, generation_time
);
9712 fprintf (stderr
, ", all time ");
9713 print_active_time (stderr
, all_time
);
9714 fprintf (stderr
, "\n");
9716 /* Finish all work. */
9717 if (output_description_file
!= NULL
)
9719 fflush (output_description_file
);
9720 if (ferror (stdout
) != 0)
9721 fatal ("Error in writing DFA description file %s",
9722 output_description_file_name
);
9723 fclose (output_description_file
);
9725 finish_automaton_decl_table ();
9726 finish_insn_decl_table ();
9727 finish_decl_table ();
9728 obstack_free (&irp
, NULL
);
9729 if (have_error
&& output_description_file
!= NULL
)
9730 remove (output_description_file_name
);