1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 Written by Vladimir Makarov <vmakarov@redhat.com>
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 GNU CC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 1. Detecting pipeline structural hazards quickly. T. Proebsting,
26 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
27 Principles of Programming Languages, pages 280--286, 1994.
29 This article is a good start point to understand usage of finite
30 state automata for pipeline hazard recognizers. But I'd
31 recommend the 2nd article for more deep understanding.
33 2. Efficient Instruction Scheduling Using Finite State Automata:
34 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
35 article about usage of finite state automata for pipeline hazard
38 The current implementation is different from the 2nd article in the
41 1. New operator `|' (alternative) is permitted in functional unit
42 reservation which can be treated deterministicly and
45 2. Possibility of usage of nondeterministic automata too.
47 3. Possibility to query functional unit reservations for given
50 4. Several constructions to describe impossible reservations
51 (`exclusion_set', `presence_set', and `absence_set').
53 5. No reverse automata are generated. Trace instruction scheduling
54 requires this. It can be easily added in the future if we
57 6. Union of automaton states are not generated yet. It is planned
58 to be implemented. Such feature is needed to make more accurate
59 interlock insn scheduling to get state describing functional
60 unit reservation in a joint CFG point.
63 /* This file code processes constructions of machine description file
64 which describes automaton used for recognition of processor pipeline
65 hazards by insn scheduler and can be used for other tasks (such as
68 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
69 `gen_bypass', `gen_excl_set', `gen_presence_set',
70 `gen_absence_set', `gen_automaton', `gen_automata_option',
71 `gen_reserv', `gen_insn_reserv' are called from file
72 `genattrtab.c'. They transform RTL constructions describing
73 automata in .md file into internal representation convenient for
76 The translator major function `expand_automata' processes the
77 description internal representation into finite state automaton.
80 o checking correctness of the automaton pipeline description
81 (major function is `check_all_description').
83 o generating automaton (automata) from the description (major
84 function is `make_automaton').
86 o optional transformation of nondeterministic finite state
87 automata into deterministic ones if the alternative operator
88 `|' is treated nondeterministicly in the description (major
89 function is NDFA_to_DFA).
91 o optional minimization of the finite state automata by merging
92 equivalent automaton states (major function is `minimize_DFA').
94 o forming tables (some as comb vectors) and attributes
95 representing the automata (functions output_..._table).
97 Function `write_automata' outputs the created finite state
98 automaton as different tables and functions which works with the
99 automata to inquire automaton state and to change its state. These
100 function are used by gcc instruction scheduler and may be some
122 #include "genattrtab.h"
124 #define obstack_chunk_alloc xmalloc
125 #define obstack_chunk_free free
127 /* Positions in machine description file. Now they are not used. But
128 they could be used in the future for better diagnostic messages. */
131 /* The following is element of vector of current (and planned in the
132 future) functional unit reservations. */
133 typedef unsigned HOST_WIDE_INT set_el_t
;
135 /* Reservations of function units are represented by value of the following
137 typedef set_el_t
*reserv_sets_t
;
139 /* The following structure represents variable length array (vla) of
140 pointers and HOST WIDE INTs. We could be use only varray. But we
141 add new lay because we add elements very frequently and this could
142 stress OS allocator when varray is used only. */
144 size_t length
; /* current size of vla. */
145 varray_type varray
; /* container for vla. */
148 typedef vla_ptr_t vla_hwint_t
;
150 /* The following structure describes a ticker. */
153 /* The following member value is time of the ticker creation with
154 taking into account time when the ticker is off. Active time of
155 the ticker is current time minus the value. */
156 int modified_creation_time
;
157 /* The following member value is time (incremented by one) when the
158 ticker was off. Zero value means that now the ticker is on. */
159 int incremented_off_time
;
162 /* The ticker is represented by the following type. */
163 typedef struct ticker ticker_t
;
165 /* The following type describes elements of output vectors. */
166 typedef HOST_WIDE_INT vect_el_t
;
168 /* Forward declaration of structures of internal representation of
169 pipeline description based on NDFA. */
174 struct automaton_decl
;
175 struct unit_rel_decl
;
177 struct insn_reserv_decl
;
180 struct result_regexp
;
181 struct reserv_regexp
;
182 struct nothing_regexp
;
183 struct sequence_regexp
;
184 struct repeat_regexp
;
195 struct state_ainsn_table
;
197 /* The following typedefs are for brevity. */
198 typedef struct unit_decl
*unit_decl_t
;
199 typedef struct decl
*decl_t
;
200 typedef struct regexp
*regexp_t
;
201 typedef struct unit_set_el
*unit_set_el_t
;
202 typedef struct alt_state
*alt_state_t
;
203 typedef struct state
*state_t
;
204 typedef struct arc
*arc_t
;
205 typedef struct ainsn
*ainsn_t
;
206 typedef struct automaton
*automaton_t
;
207 typedef struct automata_list_el
*automata_list_el_t
;
208 typedef struct state_ainsn_table
*state_ainsn_table_t
;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
213 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
214 initiate_automaton_gen, expand_automata, write_automata are
215 described on the file top because the functions are called from
218 static void *create_node
PARAMS ((size_t));
219 static void *copy_node
PARAMS ((void *, size_t));
220 static char *check_name
PARAMS ((char *, pos_t
));
221 static char *next_sep_el
PARAMS ((char **, int, int));
222 static int n_sep_els
PARAMS ((char *, int, int));
223 static char **get_str_vect
PARAMS ((char *, int *, int, int));
224 static regexp_t gen_regexp_el
PARAMS ((char *));
225 static regexp_t gen_regexp_repeat
PARAMS ((char *));
226 static regexp_t gen_regexp_allof
PARAMS ((char *));
227 static regexp_t gen_regexp_oneof
PARAMS ((char *));
228 static regexp_t gen_regexp_sequence
PARAMS ((char *));
229 static regexp_t gen_regexp
PARAMS ((char *));
231 static unsigned string_hash
PARAMS ((const char *));
232 static unsigned automaton_decl_hash
PARAMS ((const void *));
233 static int automaton_decl_eq_p
PARAMS ((const void *,
235 static decl_t insert_automaton_decl
PARAMS ((decl_t
));
236 static decl_t find_automaton_decl
PARAMS ((char *));
237 static void initiate_automaton_decl_table
PARAMS ((void));
238 static void finish_automaton_decl_table
PARAMS ((void));
240 static unsigned insn_decl_hash
PARAMS ((const void *));
241 static int insn_decl_eq_p
PARAMS ((const void *,
243 static decl_t insert_insn_decl
PARAMS ((decl_t
));
244 static decl_t find_insn_decl
PARAMS ((char *));
245 static void initiate_insn_decl_table
PARAMS ((void));
246 static void finish_insn_decl_table
PARAMS ((void));
248 static unsigned decl_hash
PARAMS ((const void *));
249 static int decl_eq_p
PARAMS ((const void *,
251 static decl_t insert_decl
PARAMS ((decl_t
));
252 static decl_t find_decl
PARAMS ((char *));
253 static void initiate_decl_table
PARAMS ((void));
254 static void finish_decl_table
PARAMS ((void));
256 static unit_set_el_t process_excls
PARAMS ((char **, int, pos_t
));
257 static void add_excls
PARAMS ((unit_set_el_t
, unit_set_el_t
,
259 static unit_set_el_t process_presence_absence
260 PARAMS ((char **, int, pos_t
, int));
261 static void add_presence_absence
PARAMS ((unit_set_el_t
, unit_set_el_t
,
263 static void process_decls
PARAMS ((void));
264 static struct bypass_decl
*find_bypass
PARAMS ((struct bypass_decl
*,
265 struct insn_reserv_decl
*));
266 static void check_automaton_usage
PARAMS ((void));
267 static regexp_t process_regexp
PARAMS ((regexp_t
));
268 static void process_regexp_decls
PARAMS ((void));
269 static void check_usage
PARAMS ((void));
270 static int loop_in_regexp
PARAMS ((regexp_t
, decl_t
));
271 static void check_loops_in_regexps
PARAMS ((void));
272 static int process_regexp_cycles
PARAMS ((regexp_t
, int));
273 static void evaluate_max_reserv_cycles
PARAMS ((void));
274 static void check_all_description
PARAMS ((void));
276 static ticker_t create_ticker
PARAMS ((void));
277 static void ticker_off
PARAMS ((ticker_t
*));
278 static void ticker_on
PARAMS ((ticker_t
*));
279 static int active_time
PARAMS ((ticker_t
));
280 static void print_active_time
PARAMS ((FILE *, ticker_t
));
282 static void add_advance_cycle_insn_decl
PARAMS ((void));
284 static alt_state_t get_free_alt_state
PARAMS ((void));
285 static void free_alt_state
PARAMS ((alt_state_t
));
286 static void free_alt_states
PARAMS ((alt_state_t
));
287 static int alt_state_cmp
PARAMS ((const void *alt_state_ptr_1
,
288 const void *alt_state_ptr_2
));
289 static alt_state_t uniq_sort_alt_states
PARAMS ((alt_state_t
));
290 static int alt_states_eq
PARAMS ((alt_state_t
, alt_state_t
));
291 static void initiate_alt_states
PARAMS ((void));
292 static void finish_alt_states
PARAMS ((void));
294 static reserv_sets_t alloc_empty_reserv_sets
PARAMS ((void));
295 static unsigned reserv_sets_hash_value
PARAMS ((reserv_sets_t
));
296 static int reserv_sets_cmp
PARAMS ((reserv_sets_t
, reserv_sets_t
));
297 static int reserv_sets_eq
PARAMS ((reserv_sets_t
, reserv_sets_t
));
298 static void set_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
299 static int test_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
300 static int it_is_empty_reserv_sets
PARAMS ((reserv_sets_t
))
302 static int reserv_sets_are_intersected
PARAMS ((reserv_sets_t
, reserv_sets_t
));
303 static void reserv_sets_shift
PARAMS ((reserv_sets_t
, reserv_sets_t
));
304 static void reserv_sets_or
PARAMS ((reserv_sets_t
, reserv_sets_t
,
306 static void reserv_sets_and
PARAMS ((reserv_sets_t
, reserv_sets_t
,
309 static void output_cycle_reservs
PARAMS ((FILE *, reserv_sets_t
,
311 static void output_reserv_sets
PARAMS ((FILE *, reserv_sets_t
));
312 static state_t get_free_state
PARAMS ((int, automaton_t
));
313 static void free_state
PARAMS ((state_t
));
314 static unsigned state_hash
PARAMS ((const void *));
315 static int state_eq_p
PARAMS ((const void *, const void *));
316 static state_t insert_state
PARAMS ((state_t
));
317 static void set_state_reserv
PARAMS ((state_t
, int, int));
318 static int intersected_state_reservs_p
PARAMS ((state_t
, state_t
));
319 static state_t states_union
PARAMS ((state_t
, state_t
));
320 static state_t state_shift
PARAMS ((state_t
));
321 static void initiate_states
PARAMS ((void));
322 static void finish_states
PARAMS ((void));
324 static void free_arc
PARAMS ((arc_t
));
325 static void remove_arc
PARAMS ((state_t
, arc_t
));
326 static arc_t find_arc
PARAMS ((state_t
, state_t
, ainsn_t
));
327 static arc_t add_arc
PARAMS ((state_t
, state_t
, ainsn_t
, int));
328 static arc_t first_out_arc
PARAMS ((state_t
));
329 static arc_t next_out_arc
PARAMS ((arc_t
));
330 static void initiate_arcs
PARAMS ((void));
331 static void finish_arcs
PARAMS ((void));
333 static automata_list_el_t get_free_automata_list_el
PARAMS ((void));
334 static void free_automata_list_el
PARAMS ((automata_list_el_t
));
335 static void free_automata_list
PARAMS ((automata_list_el_t
));
336 static unsigned automata_list_hash
PARAMS ((const void *));
337 static int automata_list_eq_p
PARAMS ((const void *, const void *));
338 static void initiate_automata_lists
PARAMS ((void));
339 static void automata_list_start
PARAMS ((void));
340 static void automata_list_add
PARAMS ((automaton_t
));
341 static automata_list_el_t automata_list_finish
PARAMS ((void));
342 static void finish_automata_lists
PARAMS ((void));
344 static void initiate_excl_sets
PARAMS ((void));
345 static reserv_sets_t get_excl_set
PARAMS ((reserv_sets_t
));
347 static void initiate_presence_absence_sets
PARAMS ((void));
348 static reserv_sets_t get_presence_absence_set
PARAMS ((reserv_sets_t
, int));
350 static regexp_t copy_insn_regexp
PARAMS ((regexp_t
));
351 static regexp_t transform_1
PARAMS ((regexp_t
));
352 static regexp_t transform_2
PARAMS ((regexp_t
));
353 static regexp_t transform_3
PARAMS ((regexp_t
));
354 static regexp_t regexp_transform_func
355 PARAMS ((regexp_t
, regexp_t (*) (regexp_t
)));
356 static regexp_t transform_regexp
PARAMS ((regexp_t
));
357 static void transform_insn_regexps
PARAMS ((void));
359 static void process_unit_to_form_the_same_automaton_unit_lists
360 PARAMS ((regexp_t
, regexp_t
, int));
361 static void form_the_same_automaton_unit_lists_from_regexp
PARAMS ((regexp_t
));
362 static void form_the_same_automaton_unit_lists
PARAMS ((void));
363 static void check_unit_distributions_to_automata
PARAMS ((void));
365 static int process_seq_for_forming_states
PARAMS ((regexp_t
, automaton_t
,
367 static void finish_forming_alt_state
PARAMS ((alt_state_t
,
369 static void process_alts_for_forming_states
PARAMS ((regexp_t
,
371 static void create_alt_states
PARAMS ((automaton_t
));
373 static void form_ainsn_with_same_reservs
PARAMS ((automaton_t
));
375 static void make_automaton
PARAMS ((automaton_t
));
376 static void form_arcs_marked_by_insn
PARAMS ((state_t
));
377 static void create_composed_state
PARAMS ((state_t
, arc_t
, vla_ptr_t
*));
378 static void NDFA_to_DFA
PARAMS ((automaton_t
));
379 static void pass_state_graph
PARAMS ((state_t
, void (*) (state_t
)));
380 static void pass_states
PARAMS ((automaton_t
,
381 void (*) (state_t
)));
382 static void initiate_pass_states
PARAMS ((void));
383 static void add_achieved_state
PARAMS ((state_t
));
384 static int set_out_arc_insns_equiv_num
PARAMS ((state_t
, int));
385 static void clear_arc_insns_equiv_num
PARAMS ((state_t
));
386 static void copy_equiv_class
PARAMS ((vla_ptr_t
*to
,
387 const vla_ptr_t
*from
));
388 static int state_is_differed
PARAMS ((state_t
, int, int));
389 static state_t init_equiv_class
PARAMS ((state_t
*states
, int));
390 static int partition_equiv_class
PARAMS ((state_t
*, int,
391 vla_ptr_t
*, int *));
392 static void evaluate_equiv_classes
PARAMS ((automaton_t
, vla_ptr_t
*));
393 static void merge_states
PARAMS ((automaton_t
, vla_ptr_t
*));
394 static void set_new_cycle_flags
PARAMS ((state_t
));
395 static void minimize_DFA
PARAMS ((automaton_t
));
396 static void incr_states_and_arcs_nums
PARAMS ((state_t
));
397 static void count_states_and_arcs
PARAMS ((automaton_t
, int *, int *));
398 static void build_automaton
PARAMS ((automaton_t
));
400 static void set_order_state_num
PARAMS ((state_t
));
401 static void enumerate_states
PARAMS ((automaton_t
));
403 static ainsn_t insert_ainsn_into_equiv_class
PARAMS ((ainsn_t
, ainsn_t
));
404 static void delete_ainsn_from_equiv_class
PARAMS ((ainsn_t
));
405 static void process_insn_equiv_class
PARAMS ((ainsn_t
, arc_t
*));
406 static void process_state_for_insn_equiv_partition
PARAMS ((state_t
));
407 static void set_insn_equiv_classes
PARAMS ((automaton_t
));
409 static double estimate_one_automaton_bound
PARAMS ((void));
410 static int compare_max_occ_cycle_nums
PARAMS ((const void *,
412 static void units_to_automata_heuristic_distr
PARAMS ((void));
413 static ainsn_t create_ainsns
PARAMS ((void));
414 static void units_to_automata_distr
PARAMS ((void));
415 static void create_automata
PARAMS ((void));
417 static void form_regexp
PARAMS ((regexp_t
));
418 static const char *regexp_representation
PARAMS ((regexp_t
));
419 static void finish_regexp_representation
PARAMS ((void));
421 static void output_range_type
PARAMS ((FILE *, long int, long int));
422 static int longest_path_length
PARAMS ((state_t
));
423 static void process_state_longest_path_length
PARAMS ((state_t
));
424 static void output_dfa_max_issue_rate
PARAMS ((void));
425 static void output_vect
PARAMS ((vect_el_t
*, int));
426 static void output_chip_member_name
PARAMS ((FILE *, automaton_t
));
427 static void output_temp_chip_member_name
PARAMS ((FILE *, automaton_t
));
428 static void output_translate_vect_name
PARAMS ((FILE *, automaton_t
));
429 static void output_trans_full_vect_name
PARAMS ((FILE *, automaton_t
));
430 static void output_trans_comb_vect_name
PARAMS ((FILE *, automaton_t
));
431 static void output_trans_check_vect_name
PARAMS ((FILE *, automaton_t
));
432 static void output_trans_base_vect_name
PARAMS ((FILE *, automaton_t
));
433 static void output_state_alts_full_vect_name
PARAMS ((FILE *, automaton_t
));
434 static void output_state_alts_comb_vect_name
PARAMS ((FILE *, automaton_t
));
435 static void output_state_alts_check_vect_name
PARAMS ((FILE *, automaton_t
));
436 static void output_state_alts_base_vect_name
PARAMS ((FILE *, automaton_t
));
437 static void output_min_issue_delay_vect_name
PARAMS ((FILE *, automaton_t
));
438 static void output_dead_lock_vect_name
PARAMS ((FILE *, automaton_t
));
439 static void output_reserved_units_table_name
PARAMS ((FILE *, automaton_t
));
440 static void output_state_member_type
PARAMS ((FILE *, automaton_t
));
441 static void output_chip_definitions
PARAMS ((void));
442 static void output_translate_vect
PARAMS ((automaton_t
));
443 static int comb_vect_p
PARAMS ((state_ainsn_table_t
));
444 static state_ainsn_table_t create_state_ainsn_table
PARAMS ((automaton_t
));
445 static void output_state_ainsn_table
446 PARAMS ((state_ainsn_table_t
, char *, void (*) (FILE *, automaton_t
),
447 void (*) (FILE *, automaton_t
), void (*) (FILE *, automaton_t
),
448 void (*) (FILE *, automaton_t
)));
449 static void add_vect
PARAMS ((state_ainsn_table_t
,
450 int, vect_el_t
*, int));
451 static int out_state_arcs_num
PARAMS ((state_t
));
452 static int compare_transition_els_num
PARAMS ((const void *, const void *));
453 static void add_vect_el
PARAMS ((vla_hwint_t
*,
455 static void add_states_vect_el
PARAMS ((state_t
));
456 static void output_trans_table
PARAMS ((automaton_t
));
457 static void output_state_alts_table
PARAMS ((automaton_t
));
458 static int min_issue_delay_pass_states
PARAMS ((state_t
, ainsn_t
));
459 static int min_issue_delay
PARAMS ((state_t
, ainsn_t
));
460 static void initiate_min_issue_delay_pass_states
PARAMS ((void));
461 static void output_min_issue_delay_table
PARAMS ((automaton_t
));
462 static void output_dead_lock_vect
PARAMS ((automaton_t
));
463 static void output_reserved_units_table
PARAMS ((automaton_t
));
464 static void output_tables
PARAMS ((void));
465 static void output_max_insn_queue_index_def
PARAMS ((void));
466 static void output_insn_code_cases
PARAMS ((void (*) (automata_list_el_t
)));
467 static void output_automata_list_min_issue_delay_code
PARAMS ((automata_list_el_t
));
468 static void output_internal_min_issue_delay_func
PARAMS ((void));
469 static void output_automata_list_transition_code
PARAMS ((automata_list_el_t
));
470 static void output_internal_trans_func
PARAMS ((void));
471 static void output_internal_insn_code_evaluation
PARAMS ((const char *,
473 static void output_dfa_insn_code_func
PARAMS ((void));
474 static void output_trans_func
PARAMS ((void));
475 static void output_automata_list_state_alts_code
PARAMS ((automata_list_el_t
));
476 static void output_internal_state_alts_func
PARAMS ((void));
477 static void output_state_alts_func
PARAMS ((void));
478 static void output_min_issue_delay_func
PARAMS ((void));
479 static void output_internal_dead_lock_func
PARAMS ((void));
480 static void output_dead_lock_func
PARAMS ((void));
481 static void output_internal_reset_func
PARAMS ((void));
482 static void output_size_func
PARAMS ((void));
483 static void output_reset_func
PARAMS ((void));
484 static void output_min_insn_conflict_delay_func
PARAMS ((void));
485 static void output_internal_insn_latency_func
PARAMS ((void));
486 static void output_insn_latency_func
PARAMS ((void));
487 static void output_print_reservation_func
PARAMS ((void));
488 static int units_cmp
PARAMS ((const void *,
490 static void output_get_cpu_unit_code_func
PARAMS ((void));
491 static void output_cpu_unit_reservation_p
PARAMS ((void));
492 static void output_dfa_start_func
PARAMS ((void));
493 static void output_dfa_finish_func
PARAMS ((void));
495 static void output_regexp
PARAMS ((regexp_t
));
496 static void output_unit_set_el_list
PARAMS ((unit_set_el_t
));
497 static void output_description
PARAMS ((void));
498 static void output_automaton_name
PARAMS ((FILE *, automaton_t
));
499 static void output_automaton_units
PARAMS ((automaton_t
));
500 static void add_state_reservs
PARAMS ((state_t
));
501 static void output_state_arcs
PARAMS ((state_t
));
502 static int state_reservs_cmp
PARAMS ((const void *,
504 static void remove_state_duplicate_reservs
PARAMS ((void));
505 static void output_state
PARAMS ((state_t
));
506 static void output_automaton_descriptions
PARAMS ((void));
507 static void output_statistics
PARAMS ((FILE *));
508 static void output_time_statistics
PARAMS ((FILE *));
509 static void generate
PARAMS ((void));
511 static void make_insn_alts_attr
PARAMS ((void));
512 static void make_internal_dfa_insn_code_attr
PARAMS ((void));
513 static void make_default_insn_latency_attr
PARAMS ((void));
514 static void make_bypass_attr
PARAMS ((void));
515 static const char *file_name_suffix
PARAMS ((const char *));
516 static const char *base_file_name
PARAMS ((const char *));
517 static void check_automata_insn_issues
PARAMS ((void));
518 static void add_automaton_state
PARAMS ((state_t
));
519 static void form_important_insn_automata_lists
PARAMS ((void));
521 /* Undefined position. */
522 static pos_t no_pos
= 0;
524 /* All IR is stored in the following obstack. */
525 static struct obstack irp
;
529 /* This page contains code for work with variable length array (vla)
530 of pointers. We could be use only varray. But we add new lay
531 because we add elements very frequently and this could stress OS
532 allocator when varray is used only. */
534 /* Start work with vla. */
535 #define VLA_PTR_CREATE(vla, allocated_length, name) \
538 vla_ptr_t *vla_ptr = &(vla); \
540 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
541 vla_ptr->length = 0; \
545 /* Finish work with the vla. */
546 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
548 /* Return start address of the vla. */
549 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
551 /* Address of the last element of the vla. Do not use side effects in
552 the macro argument. */
553 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
555 /* Nullify the vla. */
556 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
558 /* Shorten the vla on given number bytes. */
559 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
561 /* Expand the vla on N elements. The values of new elements are
563 #define VLA_PTR_EXPAND(vla, n) \
565 vla_ptr_t *expand_vla_ptr = &(vla); \
566 size_t new_length = (n) + expand_vla_ptr->length; \
568 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
569 VARRAY_GROW (expand_vla_ptr->varray, \
570 (new_length - expand_vla_ptr->length < 128 \
571 ? expand_vla_ptr->length + 128 : new_length)); \
572 expand_vla_ptr->length = new_length; \
575 /* Add element to the end of the vla. */
576 #define VLA_PTR_ADD(vla, ptr) \
578 vla_ptr_t *vla_ptr = &(vla); \
580 VLA_PTR_EXPAND (*vla_ptr, 1); \
581 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
584 /* Length of the vla in elements. */
585 #define VLA_PTR_LENGTH(vla) ((vla).length)
587 /* N-th element of the vla. */
588 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
591 /* The following macros are analogous to the previous ones but for
592 VLAs of HOST WIDE INTs. */
594 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
596 vla_hwint_t *vla_ptr = &(vla); \
598 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
599 vla_ptr->length = 0; \
602 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
604 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
606 /* Do not use side effects in the macro argument. */
607 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
610 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
612 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
614 #define VLA_HWINT_EXPAND(vla, n) \
616 vla_hwint_t *expand_vla_ptr = &(vla); \
617 size_t new_length = (n) + expand_vla_ptr->length; \
619 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
620 VARRAY_GROW (expand_vla_ptr->varray, \
621 (new_length - expand_vla_ptr->length < 128 \
622 ? expand_vla_ptr->length + 128 : new_length)); \
623 expand_vla_ptr->length = new_length; \
626 #define VLA_HWINT_ADD(vla, ptr) \
628 vla_hwint_t *vla_ptr = &(vla); \
630 VLA_HWINT_EXPAND (*vla_ptr, 1); \
631 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
634 #define VLA_HWINT_LENGTH(vla) ((vla).length)
636 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
640 /* Options with the following names can be set up in automata_option
641 construction. Because the strings occur more one time we use the
644 #define NO_MINIMIZATION_OPTION "-no-minimization"
646 #define W_OPTION "-w"
648 #define NDFA_OPTION "-ndfa"
650 /* The following flags are set up by function `initiate_automaton_gen'. */
652 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
653 static int ndfa_flag
;
655 /* Do not make minimization of DFA (`-no-minimization'). */
656 static int no_minimization_flag
;
658 /* Value of this variable is number of automata being generated. The
659 actual number of automata may be less this value if there is not
660 sufficient number of units. This value is defined by argument of
661 option `-split' or by constructions automaton if the value is zero
662 (it is default value of the argument). */
663 static int split_argument
;
665 /* Flag of output time statistics (`-time'). */
666 static int time_flag
;
668 /* Flag of creation of description file which contains description of
669 result automaton and statistics information (`-v'). */
672 /* Flag of generating warning instead of error for non-critical errors
677 /* Output file for pipeline hazard recognizer (PHR) being generated.
678 The value is NULL if the file is not defined. */
679 static FILE *output_file
;
681 /* Description file of PHR. The value is NULL if the file is not
683 static FILE *output_description_file
;
685 /* PHR description file name. */
686 static char *output_description_file_name
;
688 /* Value of the following variable is node representing description
689 being processed. This is start point of IR. */
690 static struct description
*description
;
694 /* This page contains description of IR structure (nodes). */
708 /* This describes define_cpu_unit and define_query_cpu_unit (see file
713 /* NULL if the automaton name is absent. */
714 char *automaton_name
;
715 /* If the following value is not zero, the cpu unit reservation is
716 described in define_query_cpu_unit. */
719 /* The following fields are defined by checker. */
721 /* The following field value is nonzero if the unit is used in an
725 /* The following field value is used to form cyclic lists of units
726 which should be in the same automaton because the unit is
727 reserved not on all alternatives of a regexp on a cycle. */
728 unit_decl_t the_same_automaton_unit
;
729 /* The following field is TRUE if we already reported that the unit
730 is not in the same automaton. */
731 int the_same_automaton_message_reported_p
;
733 /* The following field value is order number (0, 1, ...) of given
736 /* The following field value is corresponding declaration of
737 automaton which was given in description. If the field value is
738 NULL then automaton in the unit declaration was absent. */
739 struct automaton_decl
*automaton_decl
;
740 /* The following field value is maximal cycle number (1, ...) on
741 which given unit occurs in insns. Zero value means that given
742 unit is not used in insns. */
743 int max_occ_cycle_num
;
744 /* The following list contains units which conflict with given
746 unit_set_el_t excl_list
;
747 /* The following list contains units which are required to
748 reservation of given unit. */
749 unit_set_el_t presence_list
;
750 /* The following list contains units which should be not present in
751 reservation for given unit. */
752 unit_set_el_t absence_list
;
753 /* The following is used only when `query_p' has nonzero value.
754 This is query number for the unit. */
757 /* The following fields are defined by automaton generator. */
759 /* The following field value is number of the automaton to which
760 given unit belongs. */
761 int corresponding_automaton_num
;
764 /* This describes define_bypass (see file rtl.def). */
770 char *bypass_guard_name
;
772 /* The following fields are defined by checker. */
774 /* output and input insns of given bypass. */
775 struct insn_reserv_decl
*out_insn_reserv
;
776 struct insn_reserv_decl
*in_insn_reserv
;
777 /* The next bypass for given output insn. */
778 struct bypass_decl
*next
;
781 /* This describes define_automaton (see file rtl.def). */
782 struct automaton_decl
786 /* The following fields are defined by automaton generator. */
788 /* The following field value is nonzero if the automaton is used in
789 an regexp definition. */
790 char automaton_is_used
;
792 /* The following fields are defined by checker. */
794 /* The following field value is the corresponding automaton. This
795 field is not NULL only if the automaton is present in unit
796 declarations and the automatic partition on automata is not
798 automaton_t corresponding_automaton
;
801 /* This describes unit relations: exclusion_set, presence_set, or
802 absence_set (see file rtl.def). */
806 int first_list_length
;
810 /* This describes define_reservation (see file rtl.def). */
816 /* The following fields are defined by checker. */
818 /* The following field value is nonzero if the unit is used in an
821 /* The following field is used to check up cycle in expression
826 /* This describes define_insn_reservartion (see file rtl.def). */
827 struct insn_reserv_decl
834 /* The following fields are defined by checker. */
836 /* The following field value is order number (0, 1, ...) of given
839 /* The following field value is list of bypasses in which given insn
841 struct bypass_decl
*bypass_list
;
843 /* The following fields are defined by automaton generator. */
845 /* The following field is the insn regexp transformed that
846 the regexp has not optional regexp, repetition regexp, and an
847 reservation name (i.e. reservation identifiers are changed by the
848 corresponding regexp) and all alternations are the topest level
849 of the regexp. The value can be NULL only if it is special
850 insn `cycle advancing'. */
851 regexp_t transformed_regexp
;
852 /* The following field value is list of arcs marked given
853 insn. The field is used in transfromation NDFA -> DFA. */
854 arc_t arcs_marked_by_insn
;
855 /* The two following fields are used during minimization of a finite state
857 /* The field value is number of equivalence class of state into
858 which arc marked by given insn enters from a state (fixed during
859 an automaton minimization). */
861 /* The field value is state_alts of arc leaving a state (fixed
862 during an automaton minimization) and marked by given insn
865 /* The following member value is the list to automata which can be
866 changed by the insn issue. */
867 automata_list_el_t important_automata_list
;
868 /* The following member is used to process insn once for output. */
872 /* This contains a declaration mentioned above. */
875 /* What node in the union? */
880 struct unit_decl unit
;
881 struct bypass_decl bypass
;
882 struct automaton_decl automaton
;
883 struct unit_rel_decl excl
;
884 struct unit_rel_decl presence
;
885 struct unit_rel_decl absence
;
886 struct reserv_decl reserv
;
887 struct insn_reserv_decl insn_reserv
;
891 /* The following structures represent parsed reservation strings. */
903 /* Cpu unit in reservation. */
907 unit_decl_t unit_decl
;
910 /* Define_reservation in a reservation. */
914 struct reserv_decl
*reserv_decl
;
917 /* Absence of reservation (represented by string `nothing'). */
918 struct nothing_regexp
920 /* This used to be empty but ISO C doesn't allow that. */
924 /* Representation of reservations separated by ',' (see file
926 struct sequence_regexp
929 regexp_t regexps
[1];
932 /* Representation of construction `repeat' (see file rtl.def). */
939 /* Representation of reservations separated by '+' (see file
944 regexp_t regexps
[1];
947 /* Representation of reservations separated by '|' (see file
952 regexp_t regexps
[1];
955 /* Representation of a reservation string. */
958 /* What node in the union? */
959 enum regexp_mode mode
;
963 struct unit_regexp unit
;
964 struct reserv_regexp reserv
;
965 struct nothing_regexp nothing
;
966 struct sequence_regexp sequence
;
967 struct repeat_regexp repeat
;
968 struct allof_regexp allof
;
969 struct oneof_regexp oneof
;
973 /* Reperesents description of pipeline hazard description based on
979 /* The following fields are defined by checker. */
981 /* The following fields values are correspondingly number of all
982 units, query units, and insns in the description. */
986 /* The following field value is max length (in cycles) of
987 reservations of insns. The field value is defined only for
989 int max_insn_reserv_cycles
;
991 /* The following fields are defined by automaton generator. */
993 /* The following field value is the first automaton. */
994 automaton_t first_automaton
;
996 /* The following field is created by pipeline hazard parser and
997 contains all declarations. We allocate additional entry for
998 special insn "cycle advancing" which is added by the automaton
1005 /* The following nodes are created in automaton checker. */
1007 /* The following nodes represent exclusion, presence, absence set for
1008 cpu units. Each element are accessed through only one excl_list,
1009 presence_list, absence_list. */
1012 unit_decl_t unit_decl
;
1013 unit_set_el_t next_unit_set_el
;
1018 /* The following nodes are created in automaton generator. */
1020 /* The following node type describes state automaton. The state may
1021 be deterministic or non-deterministic. Non-deterministic state has
1022 several component states which represent alternative cpu units
1023 reservations. The state also is used for describing a
1024 deterministic reservation of automaton insn. */
1027 /* The following member value is nonzero if there is a transition by
1030 /* The following field is list of processor unit reservations on
1032 reserv_sets_t reservs
;
1033 /* The following field is unique number of given state between other
1036 /* The following field value is automaton to which given state
1038 automaton_t automaton
;
1039 /* The following field value is the first arc output from given
1041 arc_t first_out_arc
;
1042 /* The following field is used to form NDFA. */
1043 char it_was_placed_in_stack_for_NDFA_forming
;
1044 /* The following field is used to form DFA. */
1045 char it_was_placed_in_stack_for_DFA_forming
;
1046 /* The following field is used to transform NDFA to DFA. The field
1047 value is not NULL if the state is a compound state. In this case
1048 the value of field `unit_sets_list' is NULL. All states in the
1049 list are in the hash table. The list is formed through field
1050 `next_sorted_alt_state'. */
1051 alt_state_t component_states
;
1052 /* The following field is used for passing graph of states. */
1054 /* The list of states belonging to one equivalence class is formed
1055 with the aid of the following field. */
1056 state_t next_equiv_class_state
;
1057 /* The two following fields are used during minimization of a finite
1059 int equiv_class_num_1
, equiv_class_num_2
;
1060 /* The following field is used during minimization of a finite state
1061 automaton. The field value is state corresponding to equivalence
1062 class to which given state belongs. */
1063 state_t equiv_class_state
;
1064 /* The following field value is the order number of given state.
1065 The states in final DFA is enumerated with the aid of the
1067 int order_state_num
;
1068 /* This member is used for passing states for searching minimal
1071 /* The following member is used to evaluate min issue delay of insn
1073 int min_insn_issue_delay
;
1074 /* The following member is used to evaluate max issue rate of the
1075 processor. The value of the member is maximal length of the path
1076 from given state no containing arcs marked by special insn `cycle
1078 int longest_path_length
;
1081 /* The following macro is an initial value of member
1082 `longest_path_length' of a state. */
1083 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1085 /* Automaton arc. */
1088 /* The following field refers for the state into which given arc
1091 /* The following field describes that the insn issue (with cycle
1092 advancing for special insn `cycle advancing' and without cycle
1093 advancing for others) makes transition from given state to
1094 another given state. */
1096 /* The following field value is the next arc output from the same
1099 /* List of arcs marked given insn is formed with the following
1100 field. The field is used in transfromation NDFA -> DFA. */
1101 arc_t next_arc_marked_by_insn
;
1102 /* The following field is defined if NDFA_FLAG is zero. The member
1103 value is number of alternative reservations which can be used for
1104 transition for given state by given insn. */
1108 /* The following node type describes a deterministic alternative in
1109 non-deterministic state which characterizes cpu unit reservations
1110 of automaton insn or which is part of NDFA. */
1113 /* The following field is a determinist state which characterizes
1114 unit reservations of the instruction. */
1116 /* The following field refers to the next state which characterizes
1117 unit reservations of the instruction. */
1118 alt_state_t next_alt_state
;
1119 /* The following field refers to the next state in sorted list. */
1120 alt_state_t next_sorted_alt_state
;
1123 /* The following node type describes insn of automaton. They are
1124 labels of FA arcs. */
1127 /* The following field value is the corresponding insn declaration
1129 struct insn_reserv_decl
*insn_reserv_decl
;
1130 /* The following field value is the next insn declaration for an
1133 /* The following field is states which characterize automaton unit
1134 reservations of the instruction. The value can be NULL only if it
1135 is special insn `cycle advancing'. */
1136 alt_state_t alt_states
;
1137 /* The following field is sorted list of states which characterize
1138 automaton unit reservations of the instruction. The value can be
1139 NULL only if it is special insn `cycle advancing'. */
1140 alt_state_t sorted_alt_states
;
1141 /* The following field refers the next automaton insn with
1142 the same reservations. */
1143 ainsn_t next_same_reservs_insn
;
1144 /* The following field is flag of the first automaton insn with the
1145 same reservations in the declaration list. Only arcs marked such
1146 insn is present in the automaton. This significantly decreases
1147 memory requirements especially when several automata are
1149 char first_insn_with_same_reservs
;
1150 /* The following member has nonzero value if there is arc from state of
1151 the automaton marked by the ainsn. */
1153 /* Cyclic list of insns of an equivalence class is formed with the
1154 aid of the following field. */
1155 ainsn_t next_equiv_class_insn
;
1156 /* The following field value is nonzero if the insn declaration is
1157 the first insn declaration with given equivalence number. */
1158 char first_ainsn_with_given_equialence_num
;
1159 /* The following field is number of class of equivalence of insns.
1160 It is necessary because many insns may be equivalent with the
1161 point of view of pipeline hazards. */
1162 int insn_equiv_class_num
;
1163 /* The following member value is TRUE if there is an arc in the
1164 automaton marked by the insn into another state. In other
1165 words, the insn can change the state of the automaton. */
1169 /* The folowing describes an automaton for PHR. */
1172 /* The following field value is the list of insn declarations for
1175 /* The following field value is the corresponding automaton
1176 declaration. This field is not NULL only if the automatic
1177 partition on automata is not used. */
1178 struct automaton_decl
*corresponding_automaton_decl
;
1179 /* The following field value is the next automaton. */
1180 automaton_t next_automaton
;
1181 /* The following field is start state of FA. There are not unit
1182 reservations in the state. */
1183 state_t start_state
;
1184 /* The following field value is number of equivalence classes of
1185 insns (see field `insn_equiv_class_num' in
1186 `insn_reserv_decl'). */
1187 int insn_equiv_classes_num
;
1188 /* The following field value is number of states of final DFA. */
1189 int achieved_states_num
;
1190 /* The following field value is the order number (0, 1, ...) of
1192 int automaton_order_num
;
1193 /* The following fields contain statistics information about
1194 building automaton. */
1195 int NDFA_states_num
, DFA_states_num
;
1196 /* The following field value is defined only if minimization of DFA
1198 int minimal_DFA_states_num
;
1199 int NDFA_arcs_num
, DFA_arcs_num
;
1200 /* The following field value is defined only if minimization of DFA
1202 int minimal_DFA_arcs_num
;
1203 /* The following two members refer for two table state x ainsn ->
1205 state_ainsn_table_t trans_table
;
1206 state_ainsn_table_t state_alts_table
;
1207 /* The following member value is maximal value of min issue delay
1208 for insns of the automaton. */
1210 /* Usually min issue delay is small and we can place several (2, 4,
1211 8) elements in one vector element. So the compression factor can
1212 be 1 (no compression), 2, 4, 8. */
1213 int min_issue_delay_table_compression_factor
;
1216 /* The following is the element of the list of automata. */
1217 struct automata_list_el
1219 /* The automaton itself. */
1220 automaton_t automaton
;
1221 /* The next automata set element. */
1222 automata_list_el_t next_automata_list_el
;
1225 /* The following structure describes a table state X ainsn -> int(>= 0). */
1226 struct state_ainsn_table
1228 /* Automaton to which given table belongs. */
1229 automaton_t automaton
;
1230 /* The following tree vectors for comb vector implementation of the
1232 vla_hwint_t comb_vect
;
1233 vla_hwint_t check_vect
;
1234 vla_hwint_t base_vect
;
1235 /* This is simple implementation of the table. */
1236 vla_hwint_t full_vect
;
1237 /* Minimal and maximal values of the previous vectors. */
1238 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1239 int min_base_vect_el_value
, max_base_vect_el_value
;
1242 /* Create IR structure (node). */
1249 obstack_blank (&irp
, size
);
1250 result
= obstack_base (&irp
);
1251 obstack_finish (&irp
);
1252 /* Default values of members are NULL and zero. */
1253 memset (result
, 0, size
);
1257 /* Copy IR structure (node). */
1259 copy_node (from
, size
)
1264 result
= create_node (size
);
1265 memcpy (result
, from
, size
);
1269 /* The function checks that NAME does not contain quotes (`"'). */
1271 check_name (name
, pos
)
1273 pos_t pos ATTRIBUTE_UNUSED
;
1277 for (str
= name
; *str
!= '\0'; str
++)
1279 error ("Name `%s' contains quotes", name
);
1283 /* Pointers top all declartions during IR generation are stored in the
1285 static vla_ptr_t decls
;
1287 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1288 string containing the next separated element, taking parentheses
1289 into account if PAR_FLAG has nonzero value. Advance the pointer to
1290 after the string scanned, or the end-of-string. Return NULL if at
1293 next_sep_el (pstr
, sep
, par_flag
)
1303 /* Remove leading whitespaces. */
1304 while (isspace ((int) **pstr
))
1311 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1313 if (par_flag
&& *p
== '(')
1315 else if (par_flag
&& *p
== ')')
1317 else if (pars_num
== 0 && *p
== sep
)
1319 if (pars_num
== 0 && isspace ((int) *p
))
1323 for (; n_spaces
!= 0; n_spaces
--)
1324 obstack_1grow (&irp
, p
[-n_spaces
]);
1325 obstack_1grow (&irp
, *p
);
1328 obstack_1grow (&irp
, '\0');
1329 out_str
= obstack_base (&irp
);
1330 obstack_finish (&irp
);
1339 /* Given a string and a separator, return the number of separated
1340 elements in it, taking parentheses into account if PAR_FLAG has
1341 nonzero value. Return 0 for the null string, -1 if parantheses is
1344 n_sep_els (s
, sep
, par_flag
)
1355 for (pars_num
= 0, n
= 1; *s
; s
++)
1356 if (par_flag
&& *s
== '(')
1358 else if (par_flag
&& *s
== ')')
1360 else if (pars_num
== 0 && *s
== sep
)
1363 return (pars_num
!= 0 ? -1 : n
);
1366 /* Given a string and a separator, return vector of strings which are
1367 elements in the string and number of elements through els_num.
1368 Take parentheses into account if PAR_FLAG has nonzero value.
1369 Return 0 for the null string, -1 if parantheses are not balanced. */
1371 get_str_vect (str
, els_num
, sep
, par_flag
)
1381 *els_num
= n_sep_els (str
, sep
, par_flag
);
1384 obstack_blank (&irp
, sizeof (char *) * (*els_num
));
1385 vect
= (char **) obstack_base (&irp
);
1386 obstack_finish (&irp
);
1388 for (i
= 0; i
< *els_num
; i
++)
1389 vect
[i
] = next_sep_el (pstr
, sep
, par_flag
);
1390 if (next_sep_el (pstr
, sep
, par_flag
) != NULL
)
1395 /* Process a DEFINE_CPU_UNIT.
1397 This gives information about a unit contained in CPU. We fill a
1398 struct unit_decl with information used later by `expand_automata'. */
1404 char **str_cpu_units
;
1408 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1409 if (str_cpu_units
== NULL
)
1410 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1411 for (i
= 0; i
< vect_length
; i
++)
1413 decl
= create_node (sizeof (struct decl
));
1414 decl
->mode
= dm_unit
;
1416 decl
->decl
.unit
.name
= check_name (str_cpu_units
[i
], decl
->pos
);
1417 decl
->decl
.unit
.automaton_name
= (char *) XSTR (def
, 1);
1418 decl
->decl
.unit
.query_p
= 0;
1419 VLA_PTR_ADD (decls
, decl
);
1424 /* Process a DEFINE_QUERY_CPU_UNIT.
1426 This gives information about a unit contained in CPU. We fill a
1427 struct unit_decl with information used later by `expand_automata'. */
1429 gen_query_cpu_unit (def
)
1433 char **str_cpu_units
;
1437 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1438 if (str_cpu_units
== NULL
)
1439 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1440 for (i
= 0; i
< vect_length
; i
++)
1442 decl
= create_node (sizeof (struct decl
));
1443 decl
->mode
= dm_unit
;
1445 decl
->decl
.unit
.name
= check_name (str_cpu_units
[i
], decl
->pos
);
1446 decl
->decl
.unit
.automaton_name
= (char *) XSTR (def
, 1);
1447 decl
->decl
.unit
.query_p
= 1;
1448 VLA_PTR_ADD (decls
, decl
);
1453 /* Process a DEFINE_BYPASS.
1455 This gives information about a unit contained in the CPU. We fill
1456 in a struct bypass_decl with information used later by
1457 `expand_automata'. */
1469 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', 0);
1470 if (out_insns
== NULL
)
1471 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1472 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', 0);
1473 if (in_insns
== NULL
)
1474 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1475 for (i
= 0; i
< out_length
; i
++)
1476 for (j
= 0; j
< in_length
; j
++)
1478 decl
= create_node (sizeof (struct decl
));
1479 decl
->mode
= dm_bypass
;
1481 decl
->decl
.bypass
.latency
= XINT (def
, 0);
1482 decl
->decl
.bypass
.out_insn_name
= out_insns
[i
];
1483 decl
->decl
.bypass
.in_insn_name
= in_insns
[j
];
1484 decl
->decl
.bypass
.bypass_guard_name
= (char *) XSTR (def
, 3);
1485 VLA_PTR_ADD (decls
, decl
);
1490 /* Process an EXCLUSION_SET.
1492 This gives information about a cpu unit conflicts. We fill a
1493 struct unit_rel_decl (excl) with information used later by
1494 `expand_automata'. */
1500 char **first_str_cpu_units
;
1501 char **second_str_cpu_units
;
1502 int first_vect_length
;
1507 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1508 if (first_str_cpu_units
== NULL
)
1509 fatal ("invalid first string `%s' in exclusion_set", XSTR (def
, 0));
1510 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1512 if (second_str_cpu_units
== NULL
)
1513 fatal ("invalid second string `%s' in exclusion_set", XSTR (def
, 1));
1514 length
+= first_vect_length
;
1515 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1516 decl
->mode
= dm_excl
;
1518 decl
->decl
.excl
.names_num
= length
;
1519 decl
->decl
.excl
.first_list_length
= first_vect_length
;
1520 for (i
= 0; i
< length
; i
++)
1521 if (i
< first_vect_length
)
1522 decl
->decl
.excl
.names
[i
] = first_str_cpu_units
[i
];
1524 decl
->decl
.excl
.names
[i
] = second_str_cpu_units
[i
- first_vect_length
];
1525 VLA_PTR_ADD (decls
, decl
);
1529 /* Process a PRESENCE_SET.
1531 This gives information about a cpu unit reservation requirements.
1532 We fill a struct unit_rel_decl (presence) with information used
1533 later by `expand_automata'. */
1535 gen_presence_set (def
)
1539 char **first_str_cpu_units
;
1540 char **second_str_cpu_units
;
1541 int first_vect_length
;
1546 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1547 if (first_str_cpu_units
== NULL
)
1548 fatal ("invalid first string `%s' in presence_set", XSTR (def
, 0));
1549 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1551 if (second_str_cpu_units
== NULL
)
1552 fatal ("invalid second string `%s' in presence_set", XSTR (def
, 1));
1553 length
+= first_vect_length
;
1554 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1555 decl
->mode
= dm_presence
;
1557 decl
->decl
.presence
.names_num
= length
;
1558 decl
->decl
.presence
.first_list_length
= first_vect_length
;
1559 for (i
= 0; i
< length
; i
++)
1560 if (i
< first_vect_length
)
1561 decl
->decl
.presence
.names
[i
] = first_str_cpu_units
[i
];
1563 decl
->decl
.presence
.names
[i
]
1564 = second_str_cpu_units
[i
- first_vect_length
];
1565 VLA_PTR_ADD (decls
, decl
);
1569 /* Process an ABSENCE_SET.
1571 This gives information about a cpu unit reservation requirements.
1572 We fill a struct unit_rel_decl (absence) with information used
1573 later by `expand_automata'. */
1575 gen_absence_set (def
)
1579 char **first_str_cpu_units
;
1580 char **second_str_cpu_units
;
1581 int first_vect_length
;
1586 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1587 if (first_str_cpu_units
== NULL
)
1588 fatal ("invalid first string `%s' in absence_set", XSTR (def
, 0));
1589 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1591 if (second_str_cpu_units
== NULL
)
1592 fatal ("invalid second string `%s' in absence_set", XSTR (def
, 1));
1593 length
+= first_vect_length
;
1594 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1595 decl
->mode
= dm_absence
;
1597 decl
->decl
.absence
.names_num
= length
;
1598 decl
->decl
.absence
.first_list_length
= first_vect_length
;
1599 for (i
= 0; i
< length
; i
++)
1600 if (i
< first_vect_length
)
1601 decl
->decl
.absence
.names
[i
] = first_str_cpu_units
[i
];
1603 decl
->decl
.absence
.names
[i
]
1604 = second_str_cpu_units
[i
- first_vect_length
];
1605 VLA_PTR_ADD (decls
, decl
);
1609 /* Process a DEFINE_AUTOMATON.
1611 This gives information about a finite state automaton used for
1612 recognizing pipeline hazards. We fill a struct automaton_decl
1613 with information used later by `expand_automata'. */
1619 char **str_automata
;
1623 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1624 if (str_automata
== NULL
)
1625 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1626 for (i
= 0; i
< vect_length
; i
++)
1628 decl
= create_node (sizeof (struct decl
));
1629 decl
->mode
= dm_automaton
;
1631 decl
->decl
.automaton
.name
= check_name (str_automata
[i
], decl
->pos
);
1632 VLA_PTR_ADD (decls
, decl
);
1637 /* Process an AUTOMATA_OPTION.
1639 This gives information how to generate finite state automaton used
1640 for recognizing pipeline hazards. */
1642 gen_automata_option (def
)
1645 if (strcmp ((char *) XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1646 no_minimization_flag
= 1;
1647 else if (strcmp ((char *) XSTR (def
, 0), W_OPTION
+ 1) == 0)
1649 else if (strcmp ((char *) XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1652 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1655 /* Name in reservation to denote absence reservation. */
1656 #define NOTHING_NAME "nothing"
1658 /* The following string contains original reservation string being
1660 static char *reserv_str
;
1662 /* Parse an element in STR. */
1673 if (str
[len
- 1] != ')')
1674 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1675 str
[len
- 1] = '\0';
1676 regexp
= gen_regexp_sequence (str
+ 1);
1678 else if (strcmp (str
, NOTHING_NAME
) == 0)
1680 regexp
= create_node (sizeof (struct decl
));
1681 regexp
->mode
= rm_nothing
;
1685 regexp
= create_node (sizeof (struct decl
));
1686 regexp
->mode
= rm_unit
;
1687 regexp
->regexp
.unit
.name
= str
;
1692 /* Parse construction `repeat' in STR. */
1694 gen_regexp_repeat (str
)
1703 repeat_vect
= get_str_vect (str
, &els_num
, '*', 1);
1704 if (repeat_vect
== NULL
)
1705 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1708 regexp
= gen_regexp_el (repeat_vect
[0]);
1709 for (i
= 1; i
< els_num
; i
++)
1711 repeat
= create_node (sizeof (struct regexp
));
1712 repeat
->mode
= rm_repeat
;
1713 repeat
->regexp
.repeat
.regexp
= regexp
;
1714 repeat
->regexp
.repeat
.repeat_num
= atoi (repeat_vect
[i
]);
1715 if (repeat
->regexp
.repeat
.repeat_num
<= 1)
1716 fatal ("repetition `%s' <= 1 in reservation `%s'",
1723 return gen_regexp_el (str
);
1726 /* Parse reservation STR which possibly contains separator '+'. */
1728 gen_regexp_allof (str
)
1736 allof_vect
= get_str_vect (str
, &els_num
, '+', 1);
1737 if (allof_vect
== NULL
)
1738 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1741 allof
= create_node (sizeof (struct regexp
)
1742 + sizeof (regexp_t
) * (els_num
- 1));
1743 allof
->mode
= rm_allof
;
1744 allof
->regexp
.allof
.regexps_num
= els_num
;
1745 for (i
= 0; i
< els_num
; i
++)
1746 allof
->regexp
.allof
.regexps
[i
] = gen_regexp_repeat (allof_vect
[i
]);
1750 return gen_regexp_repeat (str
);
1753 /* Parse reservation STR which possibly contains separator '|'. */
1755 gen_regexp_oneof (str
)
1763 oneof_vect
= get_str_vect (str
, &els_num
, '|', 1);
1764 if (oneof_vect
== NULL
)
1765 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1768 oneof
= create_node (sizeof (struct regexp
)
1769 + sizeof (regexp_t
) * (els_num
- 1));
1770 oneof
->mode
= rm_oneof
;
1771 oneof
->regexp
.oneof
.regexps_num
= els_num
;
1772 for (i
= 0; i
< els_num
; i
++)
1773 oneof
->regexp
.oneof
.regexps
[i
] = gen_regexp_allof (oneof_vect
[i
]);
1777 return gen_regexp_allof (str
);
1780 /* Parse reservation STR which possibly contains separator ','. */
1782 gen_regexp_sequence (str
)
1786 char **sequence_vect
;
1790 sequence_vect
= get_str_vect (str
, &els_num
, ',', 1);
1793 sequence
= create_node (sizeof (struct regexp
)
1794 + sizeof (regexp_t
) * (els_num
- 1));
1795 sequence
->mode
= rm_sequence
;
1796 sequence
->regexp
.sequence
.regexps_num
= els_num
;
1797 for (i
= 0; i
< els_num
; i
++)
1798 sequence
->regexp
.sequence
.regexps
[i
]
1799 = gen_regexp_oneof (sequence_vect
[i
]);
1803 return gen_regexp_oneof (str
);
1806 /* Parse construction reservation STR. */
1812 return gen_regexp_sequence (str
);;
1815 /* Process a DEFINE_RESERVATION.
1817 This gives information about a reservation of cpu units. We fill
1818 in a struct reserv_decl with information used later by
1819 `expand_automata'. */
1826 decl
= create_node (sizeof (struct decl
));
1827 decl
->mode
= dm_reserv
;
1829 decl
->decl
.reserv
.name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
1830 decl
->decl
.reserv
.regexp
= gen_regexp ((char *) XSTR (def
, 1));
1831 VLA_PTR_ADD (decls
, decl
);
1835 /* Process a DEFINE_INSN_RESERVATION.
1837 This gives information about the reservation of cpu units by an
1838 insn. We fill a struct insn_reserv_decl with information used
1839 later by `expand_automata'. */
1841 gen_insn_reserv (def
)
1846 decl
= create_node (sizeof (struct decl
));
1847 decl
->mode
= dm_insn_reserv
;
1849 decl
->decl
.insn_reserv
.name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
1850 decl
->decl
.insn_reserv
.default_latency
= XINT (def
, 1);
1851 decl
->decl
.insn_reserv
.condexp
= XEXP (def
, 2);
1852 decl
->decl
.insn_reserv
.regexp
= gen_regexp ((char *) XSTR (def
, 3));
1853 VLA_PTR_ADD (decls
, decl
);
1859 /* The function evaluates hash value (0..UINT_MAX) of string. */
1861 string_hash (string
)
1866 for (result
= i
= 0;*string
++ != '\0'; i
++)
1867 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
1873 /* This page contains abstract data `table of automaton declarations'.
1874 Elements of the table is nodes representing automaton declarations.
1875 Key of the table elements is name of given automaton. Rememeber
1876 that automaton names have own space. */
1878 /* The function evaluates hash value of an automaton declaration. The
1879 function is used by abstract data `hashtab'. The function returns
1880 hash value (0..UINT_MAX) of given automaton declaration. */
1882 automaton_decl_hash (automaton_decl
)
1883 const void *automaton_decl
;
1885 const decl_t decl
= (decl_t
) automaton_decl
;
1887 if (decl
->mode
== dm_automaton
&& decl
->decl
.automaton
.name
== NULL
)
1889 return string_hash (decl
->decl
.automaton
.name
);
1892 /* The function tests automaton declarations on equality of their
1893 keys. The function is used by abstract data `hashtab'. The
1894 function returns 1 if the declarations have the same key, 0
1897 automaton_decl_eq_p (automaton_decl_1
, automaton_decl_2
)
1898 const void* automaton_decl_1
;
1899 const void* automaton_decl_2
;
1901 const decl_t decl1
= (decl_t
) automaton_decl_1
;
1902 const decl_t decl2
= (decl_t
) automaton_decl_2
;
1904 if (decl1
->mode
!= dm_automaton
|| decl1
->decl
.automaton
.name
== NULL
1905 || decl2
->mode
!= dm_automaton
|| decl2
->decl
.automaton
.name
== NULL
)
1907 return strcmp (decl1
->decl
.automaton
.name
, decl2
->decl
.automaton
.name
) == 0;
1910 /* The automaton declaration table itself is represented by the
1911 following variable. */
1912 static htab_t automaton_decl_table
;
1914 /* The function inserts automaton declaration into the table. The
1915 function does nothing if an automaton declaration with the same key
1916 exists already in the table. The function returns automaton
1917 declaration node in the table with the same key as given automaton
1918 declaration node. */
1920 insert_automaton_decl (automaton_decl
)
1921 decl_t automaton_decl
;
1925 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
1926 if (*entry_ptr
== NULL
)
1927 *entry_ptr
= (void *) automaton_decl
;
1928 return (decl_t
) *entry_ptr
;
1931 /* The following variable value is node representing automaton
1932 declaration. The node used for searching automaton declaration
1934 static struct decl work_automaton_decl
;
1936 /* The function searches for automaton declaration in the table with
1937 the same key as node representing name of the automaton
1938 declaration. The function returns node found in the table, NULL if
1939 such node does not exist in the table. */
1941 find_automaton_decl (name
)
1946 work_automaton_decl
.decl
.automaton
.name
= name
;
1947 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
1948 return (decl_t
) entry
;
1951 /* The function creates empty automaton declaration table and node
1952 representing automaton declaration and used for searching automaton
1953 declaration with given name. The function must be called only once
1954 before any work with the automaton declaration table. */
1956 initiate_automaton_decl_table ()
1958 work_automaton_decl
.mode
= dm_automaton
;
1959 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
1960 automaton_decl_eq_p
, (htab_del
) 0);
1963 /* The function deletes the automaton declaration table. Only call of
1964 function `initiate_automaton_decl_table' is possible immediately
1965 after this function call. */
1967 finish_automaton_decl_table ()
1969 htab_delete (automaton_decl_table
);
1974 /* This page contains abstract data `table of insn declarations'.
1975 Elements of the table is nodes representing insn declarations. Key
1976 of the table elements is name of given insn (in corresponding
1977 define_insn_reservation). Rememeber that insn names have own
1980 /* The function evaluates hash value of an insn declaration. The
1981 function is used by abstract data `hashtab'. The function returns
1982 hash value (0..UINT_MAX) of given insn declaration. */
1984 insn_decl_hash (insn_decl
)
1985 const void *insn_decl
;
1987 const decl_t decl
= (decl_t
) insn_decl
;
1989 if (decl
->mode
!= dm_insn_reserv
|| decl
->decl
.insn_reserv
.name
== NULL
)
1991 return string_hash (decl
->decl
.insn_reserv
.name
);
1994 /* The function tests insn declarations on equality of their keys.
1995 The function is used by abstract data `hashtab'. The function
1996 returns 1 if declarations have the same key, 0 otherwise. */
1998 insn_decl_eq_p (insn_decl_1
, insn_decl_2
)
1999 const void *insn_decl_1
;
2000 const void *insn_decl_2
;
2002 const decl_t decl1
= (decl_t
) insn_decl_1
;
2003 const decl_t decl2
= (decl_t
) insn_decl_2
;
2005 if (decl1
->mode
!= dm_insn_reserv
|| decl1
->decl
.insn_reserv
.name
== NULL
2006 || decl2
->mode
!= dm_insn_reserv
|| decl2
->decl
.insn_reserv
.name
== NULL
)
2008 return strcmp (decl1
->decl
.insn_reserv
.name
,
2009 decl2
->decl
.insn_reserv
.name
) == 0;
2012 /* The insn declaration table itself is represented by the following
2013 variable. The table does not contain insn reservation
2015 static htab_t insn_decl_table
;
2017 /* The function inserts insn declaration into the table. The function
2018 does nothing if an insn declaration with the same key exists
2019 already in the table. The function returns insn declaration node
2020 in the table with the same key as given insn declaration node. */
2022 insert_insn_decl (insn_decl
)
2027 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2028 if (*entry_ptr
== NULL
)
2029 *entry_ptr
= (void *) insn_decl
;
2030 return (decl_t
) *entry_ptr
;
2033 /* The following variable value is node representing insn reservation
2034 declaration. The node used for searching insn reservation
2035 declaration with given name. */
2036 static struct decl work_insn_decl
;
2038 /* The function searches for insn reservation declaration in the table
2039 with the same key as node representing name of the insn reservation
2040 declaration. The function returns node found in the table, NULL if
2041 such node does not exist in the table. */
2043 find_insn_decl (name
)
2048 work_insn_decl
.decl
.insn_reserv
.name
= name
;
2049 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2050 return (decl_t
) entry
;
2053 /* The function creates empty insn declaration table and node
2054 representing insn declaration and used for searching insn
2055 declaration with given name. The function must be called only once
2056 before any work with the insn declaration table. */
2058 initiate_insn_decl_table ()
2060 work_insn_decl
.mode
= dm_insn_reserv
;
2061 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
2065 /* The function deletes the insn declaration table. Only call of
2066 function `initiate_insn_decl_table' is possible immediately after
2067 this function call. */
2069 finish_insn_decl_table ()
2071 htab_delete (insn_decl_table
);
2076 /* This page contains abstract data `table of declarations'. Elements
2077 of the table is nodes representing declarations (of units and
2078 reservations). Key of the table elements is names of given
2081 /* The function evaluates hash value of a declaration. The function
2082 is used by abstract data `hashtab'. The function returns hash
2083 value (0..UINT_MAX) of given declaration. */
2088 const decl_t d
= (const decl_t
) decl
;
2090 if ((d
->mode
!= dm_unit
|| d
->decl
.unit
.name
== NULL
)
2091 && (d
->mode
!= dm_reserv
|| d
->decl
.reserv
.name
== NULL
))
2093 return string_hash (d
->mode
== dm_unit
2094 ? d
->decl
.unit
.name
: d
->decl
.reserv
.name
);
2097 /* The function tests declarations on equality of their keys. The
2098 function is used by abstract data `hashtab'. The function
2099 returns 1 if the declarations have the same key, 0 otherwise. */
2101 decl_eq_p (decl_1
, decl_2
)
2105 const decl_t d1
= (const decl_t
) decl_1
;
2106 const decl_t d2
= (const decl_t
) decl_2
;
2108 if (((d1
->mode
!= dm_unit
|| d1
->decl
.unit
.name
== NULL
)
2109 && (d1
->mode
!= dm_reserv
|| d1
->decl
.reserv
.name
== NULL
))
2110 || ((d2
->mode
!= dm_unit
|| d2
->decl
.unit
.name
== NULL
)
2111 && (d2
->mode
!= dm_reserv
|| d2
->decl
.reserv
.name
== NULL
)))
2113 return strcmp ((d1
->mode
== dm_unit
2114 ? d1
->decl
.unit
.name
: d1
->decl
.reserv
.name
),
2115 (d2
->mode
== dm_unit
2116 ? d2
->decl
.unit
.name
: d2
->decl
.reserv
.name
)) == 0;
2119 /* The declaration table itself is represented by the following
2121 static htab_t decl_table
;
2123 /* The function inserts declaration into the table. The function does
2124 nothing if a declaration with the same key exists already in the
2125 table. The function returns declaration node in the table with the
2126 same key as given declaration node. */
2134 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2135 if (*entry_ptr
== NULL
)
2136 *entry_ptr
= (void *) decl
;
2137 return (decl_t
) *entry_ptr
;
2140 /* The following variable value is node representing declaration. The
2141 node used for searching declaration with given name. */
2142 static struct decl work_decl
;
2144 /* The function searches for declaration in the table with the same
2145 key as node representing name of the declaration. The function
2146 returns node found in the table, NULL if such node does not exist
2154 work_decl
.decl
.unit
.name
= name
;
2155 entry
= htab_find (decl_table
, &work_decl
);
2156 return (decl_t
) entry
;
2159 /* The function creates empty declaration table and node representing
2160 declaration and used for searching declaration with given name.
2161 The function must be called only once before any work with the
2162 declaration table. */
2164 initiate_decl_table ()
2166 work_decl
.mode
= dm_unit
;
2167 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2170 /* The function deletes the declaration table. Only call of function
2171 `initiate_declaration_table' is possible immediately after this
2174 finish_decl_table ()
2176 htab_delete (decl_table
);
2181 /* This page contains checker of pipeline hazard description. */
2183 /* Checking NAMES in an exclusion clause vector and returning formed
2184 unit_set_el_list. */
2185 static unit_set_el_t
2186 process_excls (names
, num
, excl_pos
)
2189 pos_t excl_pos ATTRIBUTE_UNUSED
;
2191 unit_set_el_t el_list
;
2192 unit_set_el_t last_el
;
2193 unit_set_el_t new_el
;
2194 decl_t decl_in_table
;
2199 for (i
= 0; i
< num
; i
++)
2201 decl_in_table
= find_decl (names
[i
]);
2202 if (decl_in_table
== NULL
)
2203 error ("unit `%s' in exclusion is not declared", names
[i
]);
2204 else if (decl_in_table
->mode
!= dm_unit
)
2205 error ("`%s' in exclusion is not unit", names
[i
]);
2208 new_el
= create_node (sizeof (struct unit_set_el
));
2209 new_el
->unit_decl
= &decl_in_table
->decl
.unit
;
2210 new_el
->next_unit_set_el
= NULL
;
2211 if (last_el
== NULL
)
2212 el_list
= last_el
= new_el
;
2215 last_el
->next_unit_set_el
= new_el
;
2216 last_el
= last_el
->next_unit_set_el
;
2223 /* The function adds each element from SOURCE_LIST to the exclusion
2224 list of the each element from DEST_LIST. Checking situation "unit
2225 excludes itself". */
2227 add_excls (dest_list
, source_list
, excl_pos
)
2228 unit_set_el_t dest_list
;
2229 unit_set_el_t source_list
;
2230 pos_t excl_pos ATTRIBUTE_UNUSED
;
2234 unit_set_el_t curr_el
;
2235 unit_set_el_t prev_el
;
2238 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2239 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2241 if (dst
->unit_decl
== src
->unit_decl
)
2243 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2246 if (dst
->unit_decl
->automaton_name
!= NULL
2247 && src
->unit_decl
->automaton_name
!= NULL
2248 && strcmp (dst
->unit_decl
->automaton_name
,
2249 src
->unit_decl
->automaton_name
) != 0)
2251 error ("units `%s' and `%s' in exclusion set belong to different automata",
2252 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2255 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2257 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2258 if (curr_el
->unit_decl
== src
->unit_decl
)
2260 if (curr_el
== NULL
)
2262 /* Element not found - insert. */
2263 copy
= copy_node (src
, sizeof (*src
));
2264 copy
->next_unit_set_el
= NULL
;
2265 if (prev_el
== NULL
)
2266 dst
->unit_decl
->excl_list
= copy
;
2268 prev_el
->next_unit_set_el
= copy
;
2273 /* Checking NAMES in an presence clause vector and returning formed
2274 unit_set_el_list. The function is called only after processing all
2276 static unit_set_el_t
2277 process_presence_absence (names
, num
, req_pos
, presence_p
)
2280 pos_t req_pos ATTRIBUTE_UNUSED
;
2283 unit_set_el_t el_list
;
2284 unit_set_el_t last_el
;
2285 unit_set_el_t new_el
;
2286 decl_t decl_in_table
;
2291 for (i
= 0; i
< num
; i
++)
2293 decl_in_table
= find_decl (names
[i
]);
2294 if (decl_in_table
== NULL
)
2296 ? "unit `%s' in presence set is not declared"
2297 : "unit `%s' in absence set is not declared"), names
[i
]);
2298 else if (decl_in_table
->mode
!= dm_unit
)
2300 ? "`%s' in presence set is not unit"
2301 : "`%s' in absence set is not unit"), names
[i
]);
2304 new_el
= create_node (sizeof (struct unit_set_el
));
2305 new_el
->unit_decl
= &decl_in_table
->decl
.unit
;
2306 new_el
->next_unit_set_el
= NULL
;
2307 if (last_el
== NULL
)
2308 el_list
= last_el
= new_el
;
2311 last_el
->next_unit_set_el
= new_el
;
2312 last_el
= last_el
->next_unit_set_el
;
2319 /* The function adds each element from SOURCE_LIST to presence (if
2320 PRESENCE_P) or absence list of the each element from DEST_LIST.
2321 Checking situations "unit requires own presence", "unit requires
2322 own absence", and "unit excludes and requires presence of ...".
2323 Remember that we process absence sets only after all presence
2326 add_presence_absence (dest_list
, source_list
, req_pos
, presence_p
)
2327 unit_set_el_t dest_list
;
2328 unit_set_el_t source_list
;
2329 pos_t req_pos ATTRIBUTE_UNUSED
;
2334 unit_set_el_t curr_el
;
2335 unit_set_el_t prev_el
;
2338 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2339 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2341 if (dst
->unit_decl
== src
->unit_decl
)
2344 ? "unit `%s' requires own presence"
2345 : "unit `%s' requires own absence"), src
->unit_decl
->name
);
2348 if (dst
->unit_decl
->automaton_name
!= NULL
2349 && src
->unit_decl
->automaton_name
!= NULL
2350 && strcmp (dst
->unit_decl
->automaton_name
,
2351 src
->unit_decl
->automaton_name
) != 0)
2354 ? "units `%s' and `%s' in presence set belong to different automata"
2355 : "units `%s' and `%s' in absence set belong to different automata"),
2356 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2359 for (curr_el
= (presence_p
2360 ? dst
->unit_decl
->presence_list
2361 : dst
->unit_decl
->absence_list
), prev_el
= NULL
;
2363 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2364 if (curr_el
->unit_decl
== src
->unit_decl
)
2366 if (curr_el
== NULL
)
2368 /* Element not found - insert if there is no error. */
2369 int no_error_flag
= 1;
2372 for (curr_el
= dst
->unit_decl
->excl_list
;
2374 curr_el
= curr_el
->next_unit_set_el
)
2376 if (src
->unit_decl
== curr_el
->unit_decl
)
2381 ("unit `%s' excludes and requires presence of `%s'",
2382 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2387 ("unit `%s' excludes and requires presence of `%s'",
2388 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2392 for (curr_el
= dst
->unit_decl
->presence_list
;
2394 curr_el
= curr_el
->next_unit_set_el
)
2396 if (src
->unit_decl
== curr_el
->unit_decl
)
2401 ("unit `%s' requires absence and presence of `%s'",
2402 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2407 ("unit `%s' requires absence and presence of `%s'",
2408 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2413 copy
= copy_node (src
, sizeof (*src
));
2414 copy
->next_unit_set_el
= NULL
;
2415 if (prev_el
== NULL
)
2418 dst
->unit_decl
->presence_list
= copy
;
2420 dst
->unit_decl
->absence_list
= copy
;
2423 prev_el
->next_unit_set_el
= copy
;
2429 /* The function searches for bypass with given IN_INSN_RESERV in given
2431 static struct bypass_decl
*
2432 find_bypass (bypass_list
, in_insn_reserv
)
2433 struct bypass_decl
*bypass_list
;
2434 struct insn_reserv_decl
*in_insn_reserv
;
2436 struct bypass_decl
*bypass
;
2438 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2439 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2444 /* The function processes pipeline description declarations, checks
2445 their correctness, and forms exclusion/presence/absence sets. */
2450 decl_t automaton_decl
;
2451 decl_t decl_in_table
;
2452 decl_t out_insn_reserv
;
2453 decl_t in_insn_reserv
;
2454 struct bypass_decl
*bypass
;
2455 int automaton_presence
;
2458 /* Checking repeated automata declarations. */
2459 automaton_presence
= 0;
2460 for (i
= 0; i
< description
->decls_num
; i
++)
2462 decl
= description
->decls
[i
];
2463 if (decl
->mode
== dm_automaton
)
2465 automaton_presence
= 1;
2466 decl_in_table
= insert_automaton_decl (decl
);
2467 if (decl_in_table
!= decl
)
2470 error ("repeated declaration of automaton `%s'",
2471 decl
->decl
.automaton
.name
);
2473 warning ("repeated declaration of automaton `%s'",
2474 decl
->decl
.automaton
.name
);
2478 /* Checking undeclared automata, repeated declarations (except for
2479 automata) and correctness of their attributes (insn latency times
2481 for (i
= 0; i
< description
->decls_num
; i
++)
2483 decl
= description
->decls
[i
];
2484 if (decl
->mode
== dm_insn_reserv
)
2486 decl
->decl
.insn_reserv
.condexp
2487 = check_attr_test (decl
->decl
.insn_reserv
.condexp
, 0, 0);
2488 if (decl
->decl
.insn_reserv
.default_latency
< 0)
2489 error ("define_insn_reservation `%s' has negative latency time",
2490 decl
->decl
.insn_reserv
.name
);
2491 decl
->decl
.insn_reserv
.insn_num
= description
->insns_num
;
2492 description
->insns_num
++;
2493 decl_in_table
= insert_insn_decl (decl
);
2494 if (decl_in_table
!= decl
)
2495 error ("`%s' is already used as insn reservation name",
2496 decl
->decl
.insn_reserv
.name
);
2498 else if (decl
->mode
== dm_bypass
)
2500 if (decl
->decl
.bypass
.latency
< 0)
2501 error ("define_bypass `%s - %s' has negative latency time",
2502 decl
->decl
.bypass
.out_insn_name
,
2503 decl
->decl
.bypass
.in_insn_name
);
2505 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2507 if (decl
->mode
== dm_unit
)
2509 decl
->decl
.unit
.automaton_decl
= NULL
;
2510 if (decl
->decl
.unit
.automaton_name
!= NULL
)
2513 = find_automaton_decl (decl
->decl
.unit
.automaton_name
);
2514 if (automaton_decl
== NULL
)
2515 error ("automaton `%s' is not declared",
2516 decl
->decl
.unit
.automaton_name
);
2519 automaton_decl
->decl
.automaton
.automaton_is_used
= 1;
2520 decl
->decl
.unit
.automaton_decl
2521 = &automaton_decl
->decl
.automaton
;
2524 else if (automaton_presence
)
2525 error ("define_unit `%s' without automaton when one defined",
2526 decl
->decl
.unit
.name
);
2527 decl
->decl
.unit
.unit_num
= description
->units_num
;
2528 description
->units_num
++;
2529 if (strcmp (decl
->decl
.unit
.name
, NOTHING_NAME
) == 0)
2531 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2534 decl_in_table
= find_decl (decl
->decl
.unit
.name
);
2538 if (strcmp (decl
->decl
.reserv
.name
, NOTHING_NAME
) == 0)
2540 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2543 decl_in_table
= find_decl (decl
->decl
.reserv
.name
);
2545 if (decl_in_table
== NULL
)
2546 decl_in_table
= insert_decl (decl
);
2549 if (decl
->mode
== dm_unit
)
2550 error ("repeated declaration of unit `%s'",
2551 decl
->decl
.unit
.name
);
2553 error ("repeated declaration of reservation `%s'",
2554 decl
->decl
.reserv
.name
);
2558 /* Check bypasses and form list of bypasses for each (output)
2560 for (i
= 0; i
< description
->decls_num
; i
++)
2562 decl
= description
->decls
[i
];
2563 if (decl
->mode
== dm_bypass
)
2565 out_insn_reserv
= find_insn_decl (decl
->decl
.bypass
.out_insn_name
);
2566 in_insn_reserv
= find_insn_decl (decl
->decl
.bypass
.in_insn_name
);
2567 if (out_insn_reserv
== NULL
)
2568 error ("there is no insn reservation `%s'",
2569 decl
->decl
.bypass
.out_insn_name
);
2570 else if (in_insn_reserv
== NULL
)
2571 error ("there is no insn reservation `%s'",
2572 decl
->decl
.bypass
.in_insn_name
);
2575 decl
->decl
.bypass
.out_insn_reserv
2576 = &out_insn_reserv
->decl
.insn_reserv
;
2577 decl
->decl
.bypass
.in_insn_reserv
2578 = &in_insn_reserv
->decl
.insn_reserv
;
2580 = find_bypass (out_insn_reserv
->decl
.insn_reserv
.bypass_list
,
2581 decl
->decl
.bypass
.in_insn_reserv
);
2584 if (decl
->decl
.bypass
.latency
== bypass
->latency
)
2588 ("the same bypass `%s - %s' is already defined",
2589 decl
->decl
.bypass
.out_insn_name
,
2590 decl
->decl
.bypass
.in_insn_name
);
2593 ("the same bypass `%s - %s' is already defined",
2594 decl
->decl
.bypass
.out_insn_name
,
2595 decl
->decl
.bypass
.in_insn_name
);
2598 error ("bypass `%s - %s' is already defined",
2599 decl
->decl
.bypass
.out_insn_name
,
2600 decl
->decl
.bypass
.in_insn_name
);
2604 decl
->decl
.bypass
.next
2605 = out_insn_reserv
->decl
.insn_reserv
.bypass_list
;
2606 out_insn_reserv
->decl
.insn_reserv
.bypass_list
2607 = &decl
->decl
.bypass
;
2613 /* Check exclusion set declarations and form exclussion sets. */
2614 for (i
= 0; i
< description
->decls_num
; i
++)
2616 decl
= description
->decls
[i
];
2617 if (decl
->mode
== dm_excl
)
2619 unit_set_el_t unit_set_el_list
;
2620 unit_set_el_t unit_set_el_list_2
;
2623 = process_excls (decl
->decl
.excl
.names
,
2624 decl
->decl
.excl
.first_list_length
, decl
->pos
);
2626 = process_excls (&decl
->decl
.excl
.names
2627 [decl
->decl
.excl
.first_list_length
],
2628 decl
->decl
.excl
.names_num
2629 - decl
->decl
.excl
.first_list_length
,
2631 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2632 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2636 /* Check presence set declarations and form presence sets. */
2637 for (i
= 0; i
< description
->decls_num
; i
++)
2639 decl
= description
->decls
[i
];
2640 if (decl
->mode
== dm_presence
)
2642 unit_set_el_t unit_set_el_list
;
2643 unit_set_el_t unit_set_el_list_2
;
2646 = process_presence_absence
2647 (decl
->decl
.presence
.names
,
2648 decl
->decl
.presence
.first_list_length
, decl
->pos
, 1);
2650 = process_presence_absence
2651 (&decl
->decl
.presence
.names
2652 [decl
->decl
.presence
.first_list_length
],
2653 decl
->decl
.presence
.names_num
2654 - decl
->decl
.presence
.first_list_length
,
2656 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2661 /* Check absence set declarations and form absence sets. */
2662 for (i
= 0; i
< description
->decls_num
; i
++)
2664 decl
= description
->decls
[i
];
2665 if (decl
->mode
== dm_absence
)
2667 unit_set_el_t unit_set_el_list
;
2668 unit_set_el_t unit_set_el_list_2
;
2671 = process_presence_absence
2672 (decl
->decl
.presence
.names
,
2673 decl
->decl
.presence
.first_list_length
, decl
->pos
, 0);
2675 = process_presence_absence
2676 (&decl
->decl
.presence
.names
2677 [decl
->decl
.presence
.first_list_length
],
2678 decl
->decl
.presence
.names_num
2679 - decl
->decl
.presence
.first_list_length
,
2681 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2687 /* The following function checks that declared automaton is used. If
2688 the automaton is not used, the function fixes error/warning. The
2689 following function must be called only after `process_decls'. */
2691 check_automaton_usage ()
2696 for (i
= 0; i
< description
->decls_num
; i
++)
2698 decl
= description
->decls
[i
];
2699 if (decl
->mode
== dm_automaton
2700 && !decl
->decl
.automaton
.automaton_is_used
)
2703 error ("automaton `%s' is not used", decl
->decl
.automaton
.name
);
2705 warning ("automaton `%s' is not used", decl
->decl
.automaton
.name
);
2710 /* The following recursive function processes all regexp in order to
2711 fix usage of units or reservations and to fix errors of undeclared
2712 name. The function may change unit_regexp onto reserv_regexp.
2713 Remember that reserv_regexp does not exist before the function
2716 process_regexp (regexp
)
2719 decl_t decl_in_table
;
2720 regexp_t new_regexp
;
2723 if (regexp
->mode
== rm_unit
)
2725 decl_in_table
= find_decl (regexp
->regexp
.unit
.name
);
2726 if (decl_in_table
== NULL
)
2727 error ("undeclared unit or reservation `%s'",
2728 regexp
->regexp
.unit
.name
);
2729 else if (decl_in_table
->mode
== dm_unit
)
2731 decl_in_table
->decl
.unit
.unit_is_used
= 1;
2732 regexp
->regexp
.unit
.unit_decl
= &decl_in_table
->decl
.unit
;
2734 else if (decl_in_table
->mode
== dm_reserv
)
2736 decl_in_table
->decl
.reserv
.reserv_is_used
= 1;
2737 new_regexp
= create_node (sizeof (struct regexp
));
2738 new_regexp
->mode
= rm_reserv
;
2739 new_regexp
->pos
= regexp
->pos
;
2740 new_regexp
->regexp
.reserv
.name
= regexp
->regexp
.unit
.name
;
2741 new_regexp
->regexp
.reserv
.reserv_decl
= &decl_in_table
->decl
.reserv
;
2742 regexp
= new_regexp
;
2747 else if (regexp
->mode
== rm_sequence
)
2748 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2749 regexp
->regexp
.sequence
.regexps
[i
]
2750 = process_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
2751 else if (regexp
->mode
== rm_allof
)
2752 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2753 regexp
->regexp
.allof
.regexps
[i
]
2754 = process_regexp (regexp
->regexp
.allof
.regexps
[i
]);
2755 else if (regexp
->mode
== rm_oneof
)
2756 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2757 regexp
->regexp
.oneof
.regexps
[i
]
2758 = process_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
2759 else if (regexp
->mode
== rm_repeat
)
2760 regexp
->regexp
.repeat
.regexp
2761 = process_regexp (regexp
->regexp
.repeat
.regexp
);
2762 else if (regexp
->mode
!= rm_nothing
)
2767 /* The following function processes regexp of define_reservation and
2768 define_insn_reservation with the aid of function
2769 `process_regexp'. */
2771 process_regexp_decls ()
2776 for (i
= 0; i
< description
->decls_num
; i
++)
2778 decl
= description
->decls
[i
];
2779 if (decl
->mode
== dm_reserv
)
2780 decl
->decl
.reserv
.regexp
= process_regexp (decl
->decl
.reserv
.regexp
);
2781 else if (decl
->mode
== dm_insn_reserv
)
2782 decl
->decl
.insn_reserv
.regexp
2783 = process_regexp (decl
->decl
.insn_reserv
.regexp
);
2787 /* The following function checks that declared unit is used. If the
2788 unit is not used, the function fixes errors/warnings. The
2789 following function must be called only after `process_decls',
2790 `process_regexp_decls'. */
2797 for (i
= 0; i
< description
->decls_num
; i
++)
2799 decl
= description
->decls
[i
];
2800 if (decl
->mode
== dm_unit
&& !decl
->decl
.unit
.unit_is_used
)
2803 error ("unit `%s' is not used", decl
->decl
.unit
.name
);
2805 warning ("unit `%s' is not used", decl
->decl
.unit
.name
);
2807 else if (decl
->mode
== dm_reserv
&& !decl
->decl
.reserv
.reserv_is_used
)
2810 error ("reservation `%s' is not used", decl
->decl
.reserv
.name
);
2812 warning ("reservation `%s' is not used", decl
->decl
.reserv
.name
);
2817 /* The following variable value is number of reservation being
2818 processed on loop recognition. */
2819 static int curr_loop_pass_num
;
2821 /* The following recursive function returns nonzero value if REGEXP
2822 contains given decl or reservations in given regexp refers for
2825 loop_in_regexp (regexp
, start_decl
)
2833 if (regexp
->mode
== rm_unit
)
2835 else if (regexp
->mode
== rm_reserv
)
2837 if (start_decl
->mode
== dm_reserv
2838 && regexp
->regexp
.reserv
.reserv_decl
== &start_decl
->decl
.reserv
)
2840 else if (regexp
->regexp
.reserv
.reserv_decl
->loop_pass_num
2841 == curr_loop_pass_num
)
2842 /* declaration has been processed. */
2846 regexp
->regexp
.reserv
.reserv_decl
->loop_pass_num
2847 = curr_loop_pass_num
;
2848 return loop_in_regexp (regexp
->regexp
.reserv
.reserv_decl
->regexp
,
2852 else if (regexp
->mode
== rm_sequence
)
2854 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2855 if (loop_in_regexp (regexp
->regexp
.sequence
.regexps
[i
], start_decl
))
2859 else if (regexp
->mode
== rm_allof
)
2861 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2862 if (loop_in_regexp (regexp
->regexp
.allof
.regexps
[i
], start_decl
))
2866 else if (regexp
->mode
== rm_oneof
)
2868 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2869 if (loop_in_regexp (regexp
->regexp
.oneof
.regexps
[i
], start_decl
))
2873 else if (regexp
->mode
== rm_repeat
)
2874 return loop_in_regexp (regexp
->regexp
.repeat
.regexp
, start_decl
);
2877 if (regexp
->mode
!= rm_nothing
)
2883 /* The following function fixes errors "cycle in definition ...". The
2884 function uses function `loop_in_regexp' for that. */
2886 check_loops_in_regexps ()
2891 for (i
= 0; i
< description
->decls_num
; i
++)
2893 decl
= description
->decls
[i
];
2894 if (decl
->mode
== dm_reserv
)
2895 decl
->decl
.reserv
.loop_pass_num
= 0;
2897 for (i
= 0; i
< description
->decls_num
; i
++)
2899 decl
= description
->decls
[i
];
2900 curr_loop_pass_num
= i
;
2902 if (decl
->mode
== dm_reserv
)
2904 decl
->decl
.reserv
.loop_pass_num
= curr_loop_pass_num
;
2905 if (loop_in_regexp (decl
->decl
.reserv
.regexp
, decl
))
2907 if (decl
->decl
.reserv
.regexp
== NULL
)
2909 error ("cycle in definition of reservation `%s'",
2910 decl
->decl
.reserv
.name
);
2916 /* The function recursively processes IR of reservation and defines
2917 max and min cycle for reservation of unit and for result in the
2920 process_regexp_cycles (regexp
, start_cycle
)
2926 if (regexp
->mode
== rm_unit
)
2928 if (regexp
->regexp
.unit
.unit_decl
->max_occ_cycle_num
< start_cycle
)
2929 regexp
->regexp
.unit
.unit_decl
->max_occ_cycle_num
= start_cycle
;
2932 else if (regexp
->mode
== rm_reserv
)
2933 return process_regexp_cycles (regexp
->regexp
.reserv
.reserv_decl
->regexp
,
2935 else if (regexp
->mode
== rm_repeat
)
2937 for (i
= 0; i
< regexp
->regexp
.repeat
.repeat_num
; i
++)
2938 start_cycle
= process_regexp_cycles (regexp
->regexp
.repeat
.regexp
,
2942 else if (regexp
->mode
== rm_sequence
)
2944 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
2946 = process_regexp_cycles (regexp
->regexp
.sequence
.regexps
[i
],
2950 else if (regexp
->mode
== rm_allof
)
2952 int finish_cycle
= 0;
2955 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
2957 cycle
= process_regexp_cycles (regexp
->regexp
.allof
.regexps
[i
],
2959 if (finish_cycle
< cycle
)
2960 finish_cycle
= cycle
;
2962 return finish_cycle
;
2964 else if (regexp
->mode
== rm_oneof
)
2966 int finish_cycle
= 0;
2969 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
2971 cycle
= process_regexp_cycles (regexp
->regexp
.oneof
.regexps
[i
],
2973 if (finish_cycle
< cycle
)
2974 finish_cycle
= cycle
;
2976 return finish_cycle
;
2980 if (regexp
->mode
!= rm_nothing
)
2986 /* The following function is called only for correct program. The
2987 function defines max reservation of insns in cycles. */
2989 evaluate_max_reserv_cycles ()
2991 int max_insn_cycles_num
;
2995 description
->max_insn_reserv_cycles
= 0;
2996 for (i
= 0; i
< description
->decls_num
; i
++)
2998 decl
= description
->decls
[i
];
2999 if (decl
->mode
== dm_insn_reserv
)
3002 = process_regexp_cycles (decl
->decl
.insn_reserv
.regexp
, 0);
3003 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3004 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3007 description
->max_insn_reserv_cycles
++;
3010 /* The following function calls functions for checking all
3013 check_all_description ()
3016 check_automaton_usage ();
3017 process_regexp_decls ();
3019 check_loops_in_regexps ();
3021 evaluate_max_reserv_cycles ();
3026 /* The page contains abstract data `ticker'. This data is used to
3027 report time of different phases of building automata. It is
3028 possibly to write a description for which automata will be built
3029 during several minutes even on fast machine. */
3031 /* The following function creates ticker and makes it active. */
3037 ticker
.modified_creation_time
= get_run_time ();
3038 ticker
.incremented_off_time
= 0;
3042 /* The following function switches off given ticker. */
3047 if (ticker
->incremented_off_time
== 0)
3048 ticker
->incremented_off_time
= get_run_time () + 1;
3051 /* The following function switches on given ticker. */
3056 if (ticker
->incremented_off_time
!= 0)
3058 ticker
->modified_creation_time
3059 += get_run_time () - ticker
->incremented_off_time
+ 1;
3060 ticker
->incremented_off_time
= 0;
3064 /* The following function returns current time in milliseconds since
3065 the moment when given ticker was created. */
3067 active_time (ticker
)
3070 if (ticker
.incremented_off_time
!= 0)
3071 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3073 return get_run_time () - ticker
.modified_creation_time
;
3076 /* The following function returns string representation of active time
3077 of given ticker. The result is string representation of seconds
3078 with accuracy of 1/100 second. Only result of the last call of the
3079 function exists. Therefore the following code is not correct
3081 printf ("parser time: %s\ngeneration time: %s\n",
3082 active_time_string (parser_ticker),
3083 active_time_string (generation_ticker));
3085 Correct code has to be the following
3087 printf ("parser time: %s\n", active_time_string (parser_ticker));
3088 printf ("generation time: %s\n",
3089 active_time_string (generation_ticker));
3093 print_active_time (f
, ticker
)
3099 msecs
= active_time (ticker
);
3100 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3105 /* The following variable value is number of automaton which are
3106 really being created. This value is defined on the base of
3107 argument of option `-split'. If the variable has zero value the
3108 number of automata is defined by the constructions `%automaton'.
3109 This case occures when option `-split' is absent or has zero
3110 argument. If constructions `define_automaton' is absent only one
3111 automaton is created. */
3112 static int automata_num
;
3114 /* The following variable values are times of
3115 o transformation of regular expressions
3116 o building NDFA (DFA if !ndfa_flag)
3117 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3119 o building insn equivalence classes
3122 static ticker_t transform_time
;
3123 static ticker_t NDFA_time
;
3124 static ticker_t NDFA_to_DFA_time
;
3125 static ticker_t minimize_time
;
3126 static ticker_t equiv_time
;
3127 static ticker_t automaton_generation_time
;
3128 static ticker_t output_time
;
3130 /* The following variable values are times of
3133 all pipeline hazard translator work */
3134 static ticker_t check_time
;
3135 static ticker_t generation_time
;
3136 static ticker_t all_time
;
3140 /* Pseudo insn decl which denotes advancing cycle. */
3141 static decl_t advance_cycle_insn_decl
;
3143 add_advance_cycle_insn_decl ()
3145 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3146 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3147 advance_cycle_insn_decl
->pos
= no_pos
;
3148 advance_cycle_insn_decl
->decl
.insn_reserv
.regexp
= NULL
;
3149 advance_cycle_insn_decl
->decl
.insn_reserv
.name
= (char *) "$advance_cycle";
3150 advance_cycle_insn_decl
->decl
.insn_reserv
.insn_num
= description
->insns_num
;
3151 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3152 description
->decls_num
++;
3153 description
->insns_num
++;
3158 /* Abstract data `alternative states' which reperesents
3159 nondeterministic nature of the description (see comments for
3160 structures alt_state and state). */
3162 /* List of free states. */
3163 static alt_state_t first_free_alt_state
;
3166 /* The following variables is maximal number of allocated nodes
3168 static int allocated_alt_states_num
= 0;
3171 /* The following function returns free node alt_state. It may be new
3172 allocated node or node freed eralier. */
3174 get_free_alt_state ()
3178 if (first_free_alt_state
!= NULL
)
3180 result
= first_free_alt_state
;
3181 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3186 allocated_alt_states_num
++;
3188 result
= create_node (sizeof (struct alt_state
));
3190 result
->state
= NULL
;
3191 result
->next_alt_state
= NULL
;
3192 result
->next_sorted_alt_state
= NULL
;
3196 /* The function frees node ALT_STATE. */
3198 free_alt_state (alt_state
)
3199 alt_state_t alt_state
;
3201 if (alt_state
== NULL
)
3203 alt_state
->next_alt_state
= first_free_alt_state
;
3204 first_free_alt_state
= alt_state
;
3207 /* The function frees list started with node ALT_STATE_LIST. */
3209 free_alt_states (alt_states_list
)
3210 alt_state_t alt_states_list
;
3212 alt_state_t curr_alt_state
;
3213 alt_state_t next_alt_state
;
3215 for (curr_alt_state
= alt_states_list
;
3216 curr_alt_state
!= NULL
;
3217 curr_alt_state
= next_alt_state
)
3219 next_alt_state
= curr_alt_state
->next_alt_state
;
3220 free_alt_state (curr_alt_state
);
3224 /* The function compares unique numbers of alt states. */
3226 alt_state_cmp (alt_state_ptr_1
, alt_state_ptr_2
)
3227 const void *alt_state_ptr_1
;
3228 const void *alt_state_ptr_2
;
3230 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3231 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3233 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3234 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3240 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3241 states from the list. The comparison key is alt state unique
3244 uniq_sort_alt_states (alt_states_list
)
3245 alt_state_t alt_states_list
;
3247 alt_state_t curr_alt_state
;
3248 vla_ptr_t alt_states
;
3250 size_t prev_unique_state_ind
;
3252 alt_state_t
*result_ptr
;
3254 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3255 for (curr_alt_state
= alt_states_list
;
3256 curr_alt_state
!= NULL
;
3257 curr_alt_state
= curr_alt_state
->next_alt_state
)
3258 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3259 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3260 sizeof (alt_state_t
), alt_state_cmp
);
3261 if (VLA_PTR_LENGTH (alt_states
) == 0)
3265 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3266 prev_unique_state_ind
= 0;
3267 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3268 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3270 prev_unique_state_ind
++;
3271 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3274 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3275 free_alt_state (result_ptr
[i
]);
3277 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3278 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3279 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3280 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3281 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3282 result
= *result_ptr
;
3284 VLA_PTR_DELETE (alt_states
);
3288 /* The function checks equality of alt state lists. Remember that the
3289 lists must be already sorted by the previous function. */
3291 alt_states_eq (alt_states_1
, alt_states_2
)
3292 alt_state_t alt_states_1
;
3293 alt_state_t alt_states_2
;
3295 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3296 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3298 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3299 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3301 return alt_states_1
== alt_states_2
;
3304 /* Initialization of the abstract data. */
3306 initiate_alt_states ()
3308 first_free_alt_state
= NULL
;
3311 /* Finishing work with the abstract data. */
3313 finish_alt_states ()
3319 /* The page contains macros for work with bits strings. We could use
3320 standard gcc bitmap or sbitmap but it would result in difficulties
3321 of building canadian cross. */
3323 /* Set bit number bitno in the bit string. The macro is not side
3325 #define SET_BIT(bitstring, bitno) \
3326 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3328 /* Test if bit number bitno in the bitstring is set. The macro is not
3329 side effect proof. */
3330 #define TEST_BIT(bitstring, bitno) \
3331 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3335 /* This page contains abstract data `state'. */
3337 /* Maximal length of reservations in cycles (>= 1). */
3338 static int max_cycles_num
;
3340 /* Number of set elements (see type set_el_t) needed for
3341 representation of one cycle reservation. It is depended on units
3343 static int els_in_cycle_reserv
;
3345 /* Number of set elements (see type set_el_t) needed for
3346 representation of maximal length reservation. Deterministic
3347 reservation is stored as set (bit string) of length equal to the
3348 variable value * number of bits in set_el_t. */
3349 static int els_in_reservs
;
3351 /* VLA for representation of array of pointers to unit
3353 static vla_ptr_t units_container
;
3355 /* The start address of the array. */
3356 static unit_decl_t
*units_array
;
3358 /* Empty reservation of maximal length. */
3359 static reserv_sets_t empty_reserv
;
3361 /* The state table itself is represented by the following variable. */
3362 static htab_t state_table
;
3364 /* VLA for representation of array of pointers to free nodes
3366 static vla_ptr_t free_states
;
3368 static int curr_unique_state_num
;
3371 /* The following variables is maximal number of allocated nodes
3373 static int allocated_states_num
= 0;
3376 /* Allocate new reservation set. */
3377 static reserv_sets_t
3378 alloc_empty_reserv_sets ()
3380 reserv_sets_t result
;
3382 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3383 result
= (reserv_sets_t
) obstack_base (&irp
);
3384 obstack_finish (&irp
);
3385 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3389 /* Hash value of reservation set. */
3391 reserv_sets_hash_value (reservs
)
3392 reserv_sets_t reservs
;
3394 unsigned int hash_value
;
3396 set_el_t
*reserv_ptr
;
3399 reservs_num
= els_in_reservs
;
3400 reserv_ptr
= reservs
;
3401 while (reservs_num
!= 0)
3404 hash_value
= ((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
3405 | (hash_value
<< CHAR_BIT
)) + *reserv_ptr
;
3411 /* Comparison of given reservation sets. */
3413 reserv_sets_cmp (reservs_1
, reservs_2
)
3414 reserv_sets_t reservs_1
;
3415 reserv_sets_t reservs_2
;
3418 set_el_t
*reserv_ptr_1
;
3419 set_el_t
*reserv_ptr_2
;
3421 if (reservs_1
== NULL
|| reservs_2
== NULL
)
3423 reservs_num
= els_in_reservs
;
3424 reserv_ptr_1
= reservs_1
;
3425 reserv_ptr_2
= reservs_2
;
3426 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3432 if (reservs_num
== 0)
3434 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3440 /* The function checks equality of the reservation sets. */
3442 reserv_sets_eq (reservs_1
, reservs_2
)
3443 reserv_sets_t reservs_1
;
3444 reserv_sets_t reservs_2
;
3446 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3449 /* Set up in the reservation set that unit with UNIT_NUM is used on
3452 set_unit_reserv (reservs
, cycle_num
, unit_num
)
3453 reserv_sets_t reservs
;
3457 if (cycle_num
>= max_cycles_num
)
3459 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3460 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3463 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3464 used on CYCLE_NUM. */
3466 test_unit_reserv (reservs
, cycle_num
, unit_num
)
3467 reserv_sets_t reservs
;
3471 if (cycle_num
>= max_cycles_num
)
3473 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3474 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3477 /* The function checks that the reservation set represents no one unit
3480 it_is_empty_reserv_sets (operand
)
3481 reserv_sets_t operand
;
3483 set_el_t
*reserv_ptr
;
3486 if (operand
== NULL
)
3488 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3490 reserv_ptr
++, reservs_num
--)
3491 if (*reserv_ptr
!= 0)
3496 /* The function checks that the reservation sets are intersected,
3497 i.e. there is a unit reservation on a cycle in both reservation
3500 reserv_sets_are_intersected (operand_1
, operand_2
)
3501 reserv_sets_t operand_1
;
3502 reserv_sets_t operand_2
;
3506 set_el_t
*cycle_ptr_1
;
3507 set_el_t
*cycle_ptr_2
;
3510 if (operand_1
== NULL
|| operand_2
== NULL
)
3512 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3513 el_ptr_1
< operand_1
+ els_in_reservs
;
3514 el_ptr_1
++, el_ptr_2
++)
3515 if (*el_ptr_1
& *el_ptr_2
)
3517 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3518 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3519 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3521 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3522 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3523 el_ptr_1
++, el_ptr_2
++)
3524 if (*el_ptr_1
& *el_ptr_2
)
3527 for (el_ptr_1
= cycle_ptr_1
,
3528 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 1);
3529 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3530 el_ptr_1
++, el_ptr_2
++)
3531 if (*el_ptr_1
& *el_ptr_2
)
3533 else if (*el_ptr_2
!= 0)
3535 if (nonzero_p
&& el_ptr_1
>= cycle_ptr_1
+ els_in_cycle_reserv
)
3537 for (el_ptr_1
= cycle_ptr_1
,
3538 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 0);
3539 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3540 el_ptr_1
++, el_ptr_2
++)
3541 /* It looks like code for exclusion but exclusion set is
3542 made as symmetric relation preliminary. */
3543 if (*el_ptr_1
& *el_ptr_2
)
3549 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3550 cpu cycle. The remaining bits of OPERAND (representing the last
3551 cycle unit reservations) are not chenged. */
3553 reserv_sets_shift (result
, operand
)
3554 reserv_sets_t result
;
3555 reserv_sets_t operand
;
3559 if (result
== NULL
|| operand
== NULL
|| result
== operand
)
3561 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3562 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3565 /* OR of the reservation sets. */
3567 reserv_sets_or (result
, operand_1
, operand_2
)
3568 reserv_sets_t result
;
3569 reserv_sets_t operand_1
;
3570 reserv_sets_t operand_2
;
3574 set_el_t
*result_set_el_ptr
;
3576 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3578 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3579 el_ptr_1
< operand_1
+ els_in_reservs
;
3580 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3581 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3584 /* AND of the reservation sets. */
3586 reserv_sets_and (result
, operand_1
, operand_2
)
3587 reserv_sets_t result
;
3588 reserv_sets_t operand_1
;
3589 reserv_sets_t operand_2
;
3593 set_el_t
*result_set_el_ptr
;
3595 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3597 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3598 el_ptr_1
< operand_1
+ els_in_reservs
;
3599 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3600 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3603 /* The function outputs string representation of units reservation on
3604 cycle START_CYCLE in the reservation set. The function uses repeat
3605 construction if REPETITION_NUM > 1. */
3607 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
)
3609 reserv_sets_t reservs
;
3614 int reserved_units_num
;
3616 reserved_units_num
= 0;
3617 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3618 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3619 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3620 reserved_units_num
++;
3621 if (repetition_num
<= 0)
3623 if (repetition_num
!= 1 && reserved_units_num
> 1)
3625 reserved_units_num
= 0;
3627 unit_num
< description
->units_num
;
3629 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3630 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3632 if (reserved_units_num
!= 0)
3634 reserved_units_num
++;
3635 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3637 if (reserved_units_num
== 0)
3638 fprintf (f
, NOTHING_NAME
);
3639 if (repetition_num
<= 0)
3641 if (reserved_units_num
!= 0 && repetition_num
!= 1)
3643 if (reserved_units_num
> 1)
3645 fprintf (f
, "*%d", repetition_num
);
3649 /* The function outputs string representation of units reservation in
3650 the reservation set. */
3652 output_reserv_sets (f
, reservs
)
3654 reserv_sets_t reservs
;
3656 int start_cycle
= 0;
3661 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
3662 if (repetition_num
== 0)
3665 start_cycle
= cycle
;
3668 ((char *) reservs
+ start_cycle
* els_in_cycle_reserv
3669 * sizeof (set_el_t
),
3670 (char *) reservs
+ cycle
* els_in_cycle_reserv
3671 * sizeof (set_el_t
),
3672 els_in_cycle_reserv
* sizeof (set_el_t
)) == 0)
3676 if (start_cycle
!= 0)
3678 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3680 start_cycle
= cycle
;
3682 if (start_cycle
< max_cycles_num
)
3684 if (start_cycle
!= 0)
3686 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3690 /* The following function returns free node state for AUTOMATON. It
3691 may be new allocated node or node freed eralier. The function also
3692 allocates reservation set if WITH_RESERVS has nonzero value. */
3694 get_free_state (with_reservs
, automaton
)
3696 automaton_t automaton
;
3700 if (max_cycles_num
<= 0 || automaton
== NULL
)
3702 if (VLA_PTR_LENGTH (free_states
) != 0)
3704 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
3705 VLA_PTR_SHORTEN (free_states
, 1);
3706 result
->automaton
= automaton
;
3707 result
->first_out_arc
= NULL
;
3708 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
3709 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
3710 result
->component_states
= NULL
;
3711 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3716 allocated_states_num
++;
3718 result
= create_node (sizeof (struct state
));
3719 result
->automaton
= automaton
;
3720 result
->first_out_arc
= NULL
;
3721 result
->unique_num
= curr_unique_state_num
;
3722 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3723 curr_unique_state_num
++;
3727 if (result
->reservs
== NULL
)
3728 result
->reservs
= alloc_empty_reserv_sets ();
3730 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
3735 /* The function frees node STATE. */
3740 free_alt_states (state
->component_states
);
3741 VLA_PTR_ADD (free_states
, state
);
3744 /* Hash value of STATE. If STATE represents deterministic state it is
3745 simply hash value of the corresponding reservation set. Otherwise
3746 it is formed from hash values of the component deterministic
3747 states. One more key is order number of state automaton. */
3752 unsigned int hash_value
;
3753 alt_state_t alt_state
;
3755 if (((state_t
) state
)->component_states
== NULL
)
3756 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
3760 for (alt_state
= ((state_t
) state
)->component_states
;
3762 alt_state
= alt_state
->next_sorted_alt_state
)
3763 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
3764 | (hash_value
<< CHAR_BIT
))
3765 + alt_state
->state
->unique_num
);
3767 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
3768 | (hash_value
<< CHAR_BIT
))
3769 + ((state_t
) state
)->automaton
->automaton_order_num
);
3773 /* Return nonzero value if the states are the same. */
3775 state_eq_p (state_1
, state_2
)
3776 const void *state_1
;
3777 const void *state_2
;
3779 alt_state_t alt_state_1
;
3780 alt_state_t alt_state_2
;
3782 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
3784 else if (((state_t
) state_1
)->component_states
== NULL
3785 && ((state_t
) state_2
)->component_states
== NULL
)
3786 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
3787 ((state_t
) state_2
)->reservs
);
3788 else if (((state_t
) state_1
)->component_states
!= NULL
3789 && ((state_t
) state_2
)->component_states
!= NULL
)
3791 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
3792 alt_state_2
= ((state_t
) state_2
)->component_states
;
3793 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
3794 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
3795 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
3796 /* All state in the list must be already in the hash table.
3797 Also the lists must be sorted. */
3798 if (alt_state_1
->state
!= alt_state_2
->state
)
3800 return alt_state_1
== alt_state_2
;
3806 /* Insert STATE into the state table. */
3808 insert_state (state
)
3813 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
3814 if (*entry_ptr
== NULL
)
3815 *entry_ptr
= (void *) state
;
3816 return (state_t
) *entry_ptr
;
3819 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3820 deterministic STATE. */
3822 set_state_reserv (state
, cycle_num
, unit_num
)
3827 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
3830 /* Return nonzero value if the deterministic states contains a
3831 reservation of the same cpu unit on the same cpu cycle. */
3833 intersected_state_reservs_p (state1
, state2
)
3837 if (state1
->automaton
!= state2
->automaton
)
3839 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
3842 /* Return deterministic state (inserted into the table) which
3843 representing the automaton state whic is union of reservations of
3844 deterministic states. */
3846 states_union (state1
, state2
)
3851 state_t state_in_table
;
3853 if (state1
->automaton
!= state2
->automaton
)
3855 result
= get_free_state (1, state1
->automaton
);
3856 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
3857 state_in_table
= insert_state (result
);
3858 if (result
!= state_in_table
)
3860 free_state (result
);
3861 result
= state_in_table
;
3866 /* Return deterministic state (inserted into the table) which
3867 represent the automaton state is obtained from deterministic STATE
3868 by advancing cpu cycle. */
3874 state_t state_in_table
;
3876 result
= get_free_state (1, state
->automaton
);
3877 reserv_sets_shift (result
->reservs
, state
->reservs
);
3878 state_in_table
= insert_state (result
);
3879 if (result
!= state_in_table
)
3881 free_state (result
);
3882 result
= state_in_table
;
3887 /* Initialization of the abstract data. */
3894 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
3896 = (description
->decls_num
&& description
->units_num
3897 ? VLA_PTR_BEGIN (units_container
) : NULL
);
3898 for (i
= 0; i
< description
->decls_num
; i
++)
3900 decl
= description
->decls
[i
];
3901 if (decl
->mode
== dm_unit
)
3902 units_array
[decl
->decl
.unit
.unit_num
] = &decl
->decl
.unit
;
3904 max_cycles_num
= description
->max_insn_reserv_cycles
;
3906 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
3907 / (sizeof (set_el_t
) * CHAR_BIT
));
3908 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
3909 curr_unique_state_num
= 0;
3910 initiate_alt_states ();
3911 VLA_PTR_CREATE (free_states
, 1500, "free states");
3912 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
3913 empty_reserv
= alloc_empty_reserv_sets ();
3916 /* Finisging work with the abstract data. */
3920 VLA_PTR_DELETE (units_container
);
3921 htab_delete (state_table
);
3922 VLA_PTR_DELETE (free_states
);
3923 finish_alt_states ();
3928 /* Abstract data `arcs'. */
3930 /* List of free arcs. */
3931 static arc_t first_free_arc
;
3934 /* The following variables is maximal number of allocated nodes
3936 static int allocated_arcs_num
= 0;
3939 /* The function frees node ARC. */
3944 arc
->next_out_arc
= first_free_arc
;
3945 first_free_arc
= arc
;
3948 /* The function removes and frees ARC staring from FROM_STATE. */
3950 remove_arc (from_state
, arc
)
3959 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
3961 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
3962 if (curr_arc
== arc
)
3964 if (curr_arc
== NULL
)
3966 if (prev_arc
== NULL
)
3967 from_state
->first_out_arc
= arc
->next_out_arc
;
3969 prev_arc
->next_out_arc
= arc
->next_out_arc
;
3973 /* The functions returns arc with given characteristics (or NULL if
3974 the arc does not exist). */
3976 find_arc (from_state
, to_state
, insn
)
3983 for (arc
= first_out_arc (from_state
); arc
!= NULL
; arc
= next_out_arc (arc
))
3984 if (arc
->to_state
== to_state
&& arc
->insn
== insn
)
3989 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
3990 and with given STATE_ALTS. The function returns added arc (or
3991 already existing arc). */
3993 add_arc (from_state
, to_state
, ainsn
, state_alts
)
4001 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4002 if (new_arc
!= NULL
)
4004 if (first_free_arc
== NULL
)
4007 allocated_arcs_num
++;
4009 new_arc
= create_node (sizeof (struct arc
));
4010 new_arc
->to_state
= NULL
;
4011 new_arc
->insn
= NULL
;
4012 new_arc
->next_out_arc
= NULL
;
4016 new_arc
= first_free_arc
;
4017 first_free_arc
= first_free_arc
->next_out_arc
;
4019 new_arc
->to_state
= to_state
;
4020 new_arc
->insn
= ainsn
;
4021 ainsn
->arc_exists_p
= 1;
4022 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4023 from_state
->first_out_arc
= new_arc
;
4024 new_arc
->next_arc_marked_by_insn
= NULL
;
4025 new_arc
->state_alts
= state_alts
;
4029 /* The function returns the first arc starting from STATE. */
4031 first_out_arc (state
)
4034 return state
->first_out_arc
;
4037 /* The function returns next out arc after ARC. */
4042 return arc
->next_out_arc
;
4045 /* Initialization of the abstract data. */
4049 first_free_arc
= NULL
;
4052 /* Finishing work with the abstract data. */
4060 /* Abstract data `automata lists'. */
4062 /* List of free states. */
4063 static automata_list_el_t first_free_automata_list_el
;
4065 /* The list being formed. */
4066 static automata_list_el_t current_automata_list
;
4068 /* Hash table of automata lists. */
4069 static htab_t automata_list_table
;
4071 /* The following function returns free automata list el. It may be
4072 new allocated node or node freed earlier. */
4073 static automata_list_el_t
4074 get_free_automata_list_el ()
4076 automata_list_el_t result
;
4078 if (first_free_automata_list_el
!= NULL
)
4080 result
= first_free_automata_list_el
;
4081 first_free_automata_list_el
4082 = first_free_automata_list_el
->next_automata_list_el
;
4085 result
= create_node (sizeof (struct automata_list_el
));
4086 result
->automaton
= NULL
;
4087 result
->next_automata_list_el
= NULL
;
4091 /* The function frees node AUTOMATA_LIST_EL. */
4093 free_automata_list_el (automata_list_el
)
4094 automata_list_el_t automata_list_el
;
4096 if (automata_list_el
== NULL
)
4098 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4099 first_free_automata_list_el
= automata_list_el
;
4102 /* The function frees list AUTOMATA_LIST. */
4104 free_automata_list (automata_list
)
4105 automata_list_el_t automata_list
;
4107 automata_list_el_t curr_automata_list_el
;
4108 automata_list_el_t next_automata_list_el
;
4110 for (curr_automata_list_el
= automata_list
;
4111 curr_automata_list_el
!= NULL
;
4112 curr_automata_list_el
= next_automata_list_el
)
4114 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4115 free_automata_list_el (curr_automata_list_el
);
4119 /* Hash value of AUTOMATA_LIST. */
4121 automata_list_hash (automata_list
)
4122 const void *automata_list
;
4124 unsigned int hash_value
;
4125 automata_list_el_t curr_automata_list_el
;
4128 for (curr_automata_list_el
= (automata_list_el_t
) automata_list
;
4129 curr_automata_list_el
!= NULL
;
4130 curr_automata_list_el
= curr_automata_list_el
->next_automata_list_el
)
4131 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4132 | (hash_value
<< CHAR_BIT
))
4133 + curr_automata_list_el
->automaton
->automaton_order_num
);
4137 /* Return nonzero value if the automata_lists are the same. */
4139 automata_list_eq_p (automata_list_1
, automata_list_2
)
4140 const void *automata_list_1
;
4141 const void *automata_list_2
;
4143 automata_list_el_t automata_list_el_1
;
4144 automata_list_el_t automata_list_el_2
;
4146 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4147 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4148 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4149 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4150 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4151 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4153 return automata_list_el_1
== automata_list_el_2
;
4156 /* Initialization of the abstract data. */
4158 initiate_automata_lists ()
4160 first_free_automata_list_el
= NULL
;
4161 automata_list_table
= htab_create (1500, automata_list_hash
,
4162 automata_list_eq_p
, (htab_del
) 0);
4165 /* The following function starts new automata list and makes it the
4168 automata_list_start ()
4170 current_automata_list
= NULL
;
4173 /* The following function adds AUTOMATON to the current list. */
4175 automata_list_add (automaton
)
4176 automaton_t automaton
;
4178 automata_list_el_t el
;
4180 el
= get_free_automata_list_el ();
4181 el
->automaton
= automaton
;
4182 el
->next_automata_list_el
= current_automata_list
;
4183 current_automata_list
= el
;
4186 /* The following function finishes forming the current list, inserts
4187 it into the table and returns it. */
4188 static automata_list_el_t
4189 automata_list_finish ()
4193 if (current_automata_list
== NULL
)
4195 entry_ptr
= htab_find_slot (automata_list_table
,
4196 (void *) current_automata_list
, 1);
4197 if (*entry_ptr
== NULL
)
4198 *entry_ptr
= (void *) current_automata_list
;
4200 free_automata_list (current_automata_list
);
4201 current_automata_list
= NULL
;
4202 return (automata_list_el_t
) *entry_ptr
;
4205 /* Finishing work with the abstract data. */
4207 finish_automata_lists ()
4209 htab_delete (automata_list_table
);
4214 /* The page contains abstract data for work with exclusion sets (see
4215 exclusion_set in file rtl.def). */
4217 /* The following variable refers to an exclusion set returned by
4218 get_excl_set. This is bit string of length equal to cpu units
4219 number. If exclusion set for given unit contains 1 for a unit,
4220 then simultaneous reservation of the units is prohibited. */
4221 static reserv_sets_t excl_set
;
4223 /* The array contains exclusion sets for each unit. */
4224 static reserv_sets_t
*unit_excl_set_table
;
4226 /* The following function forms the array containing exclusion sets
4229 initiate_excl_sets ()
4232 reserv_sets_t unit_excl_set
;
4236 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4237 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4238 obstack_finish (&irp
);
4239 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4240 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4241 obstack_finish (&irp
);
4242 /* Evaluate unit exclusion sets. */
4243 for (i
= 0; i
< description
->decls_num
; i
++)
4245 decl
= description
->decls
[i
];
4246 if (decl
->mode
== dm_unit
)
4248 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4249 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4250 obstack_finish (&irp
);
4251 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4252 for (el
= decl
->decl
.unit
.excl_list
;
4254 el
= el
->next_unit_set_el
)
4255 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4256 unit_excl_set_table
[decl
->decl
.unit
.unit_num
] = unit_excl_set
;
4261 /* The function sets up and return EXCL_SET which is union of
4262 exclusion sets for each unit in IN_SET. */
4263 static reserv_sets_t
4264 get_excl_set (in_set
)
4265 reserv_sets_t in_set
;
4273 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4274 memset (excl_set
, 0, chars_num
);
4275 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4276 if (((unsigned char *) in_set
) [excl_char_num
])
4277 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4278 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4280 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4281 if (start_unit_num
>= description
->units_num
)
4283 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4286 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4294 /* The page contains abstract data for work with presence/absence sets
4295 (see presence_set/absence_set in file rtl.def). */
4297 /* The following variables refer to correspondingly an presence and an
4298 absence set returned by get_presence_absence_set. This is bit
4299 string of length equal to cpu units number. */
4300 static reserv_sets_t presence_set
, absence_set
;
4302 /* The following arrays contain correspondingly presence and absence
4303 sets for each unit. */
4304 static reserv_sets_t
*unit_presence_set_table
, *unit_absence_set_table
;
4306 /* The following function forms the array containing presence and
4307 absence sets for each unit */
4309 initiate_presence_absence_sets ()
4312 reserv_sets_t unit_set
;
4316 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4317 presence_set
= (reserv_sets_t
) obstack_base (&irp
);
4318 obstack_finish (&irp
);
4319 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4320 unit_presence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4321 obstack_finish (&irp
);
4322 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4323 absence_set
= (reserv_sets_t
) obstack_base (&irp
);
4324 obstack_finish (&irp
);
4325 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4326 unit_absence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4327 obstack_finish (&irp
);
4328 /* Evaluate unit presence/absence sets. */
4329 for (i
= 0; i
< description
->decls_num
; i
++)
4331 decl
= description
->decls
[i
];
4332 if (decl
->mode
== dm_unit
)
4334 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4335 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4336 obstack_finish (&irp
);
4337 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4338 for (el
= decl
->decl
.unit
.presence_list
;
4340 el
= el
->next_unit_set_el
)
4341 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4342 unit_presence_set_table
[decl
->decl
.unit
.unit_num
] = unit_set
;
4344 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4345 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4346 obstack_finish (&irp
);
4347 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4348 for (el
= decl
->decl
.unit
.absence_list
;
4350 el
= el
->next_unit_set_el
)
4351 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4352 unit_absence_set_table
[decl
->decl
.unit
.unit_num
] = unit_set
;
4357 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4358 ABSENCE_SET which is union of corresponding sets for each unit in
4360 static reserv_sets_t
4361 get_presence_absence_set (in_set
, presence_p
)
4362 reserv_sets_t in_set
;
4371 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4373 memset (presence_set
, 0, chars_num
);
4375 memset (absence_set
, 0, chars_num
);
4376 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4377 if (((unsigned char *) in_set
) [char_num
])
4378 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4379 if ((((unsigned char *) in_set
) [char_num
] >> i
) & 1)
4381 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4382 if (start_unit_num
>= description
->units_num
)
4383 return (presence_p
? presence_set
: absence_set
);
4384 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4386 presence_set
[unit_num
]
4387 |= unit_presence_set_table
[start_unit_num
] [unit_num
];
4389 absence_set
[unit_num
]
4390 |= unit_absence_set_table
[start_unit_num
] [unit_num
];
4392 return (presence_p
? presence_set
: absence_set
);
4397 /* This page contains code for transformation of original reservations
4398 described in .md file. The main goal of transformations is
4399 simplifying reservation and lifting up all `|' on the top of IR
4400 reservation representation. */
4403 /* The following function makes copy of IR representation of
4404 reservation. The function also substitutes all reservations
4405 defined by define_reservation by corresponding value during making
4408 copy_insn_regexp (regexp
)
4414 if (regexp
->mode
== rm_reserv
)
4415 result
= copy_insn_regexp (regexp
->regexp
.reserv
.reserv_decl
->regexp
);
4416 else if (regexp
->mode
== rm_unit
)
4417 result
= copy_node (regexp
, sizeof (struct regexp
));
4418 else if (regexp
->mode
== rm_repeat
)
4420 result
= copy_node (regexp
, sizeof (struct regexp
));
4421 result
->regexp
.repeat
.regexp
4422 = copy_insn_regexp (regexp
->regexp
.repeat
.regexp
);
4424 else if (regexp
->mode
== rm_sequence
)
4426 result
= copy_node (regexp
,
4427 sizeof (struct regexp
) + sizeof (regexp_t
)
4428 * (regexp
->regexp
.sequence
.regexps_num
- 1));
4429 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4430 result
->regexp
.sequence
.regexps
[i
]
4431 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4433 else if (regexp
->mode
== rm_allof
)
4435 result
= copy_node (regexp
,
4436 sizeof (struct regexp
) + sizeof (regexp_t
)
4437 * (regexp
->regexp
.allof
.regexps_num
- 1));
4438 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4439 result
->regexp
.allof
.regexps
[i
]
4440 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4442 else if (regexp
->mode
== rm_oneof
)
4444 result
= copy_node (regexp
,
4445 sizeof (struct regexp
) + sizeof (regexp_t
)
4446 * (regexp
->regexp
.oneof
.regexps_num
- 1));
4447 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4448 result
->regexp
.oneof
.regexps
[i
]
4449 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4453 if (regexp
->mode
!= rm_nothing
)
4455 result
= copy_node (regexp
, sizeof (struct regexp
));
4460 /* The following variable is set up 1 if a transformation has been
4462 static int regexp_transformed_p
;
4464 /* The function makes transformation
4467 transform_1 (regexp
)
4475 if (regexp
->mode
== rm_repeat
)
4477 repeat_num
= regexp
->regexp
.repeat
.repeat_num
;
4478 if (repeat_num
<= 1)
4480 operand
= regexp
->regexp
.repeat
.regexp
;
4482 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4483 * (repeat_num
- 1));
4484 regexp
->mode
= rm_sequence
;
4486 regexp
->regexp
.sequence
.regexps_num
= repeat_num
;
4487 for (i
= 0; i
< repeat_num
; i
++)
4488 regexp
->regexp
.sequence
.regexps
[i
] = copy_insn_regexp (operand
);
4489 regexp_transformed_p
= 1;
4494 /* The function makes transformations
4495 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4496 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4497 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4499 transform_2 (regexp
)
4502 if (regexp
->mode
== rm_sequence
)
4509 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4510 if (regexp
->regexp
.sequence
.regexps
[i
]->mode
== rm_sequence
)
4513 sequence
= regexp
->regexp
.sequence
.regexps
[i
];
4516 if (i
< regexp
->regexp
.sequence
.regexps_num
)
4518 if (sequence
->regexp
.sequence
.regexps_num
<= 1
4519 || regexp
->regexp
.sequence
.regexps_num
<= 1)
4521 result
= create_node (sizeof (struct regexp
)
4523 * (regexp
->regexp
.sequence
.regexps_num
4524 + sequence
->regexp
.sequence
.regexps_num
4526 result
->mode
= rm_sequence
;
4527 result
->pos
= regexp
->pos
;
4528 result
->regexp
.sequence
.regexps_num
4529 = (regexp
->regexp
.sequence
.regexps_num
4530 + sequence
->regexp
.sequence
.regexps_num
- 1);
4531 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4532 if (i
< sequence_index
)
4533 result
->regexp
.sequence
.regexps
[i
]
4534 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4535 else if (i
> sequence_index
)
4536 result
->regexp
.sequence
.regexps
4537 [i
+ sequence
->regexp
.sequence
.regexps_num
- 1]
4538 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
4540 for (j
= 0; j
< sequence
->regexp
.sequence
.regexps_num
; j
++)
4541 result
->regexp
.sequence
.regexps
[i
+ j
]
4542 = copy_insn_regexp (sequence
->regexp
.sequence
.regexps
[j
]);
4543 regexp_transformed_p
= 1;
4547 else if (regexp
->mode
== rm_allof
)
4554 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4555 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_allof
)
4558 allof
= regexp
->regexp
.allof
.regexps
[i
];
4561 if (i
< regexp
->regexp
.allof
.regexps_num
)
4563 if (allof
->regexp
.allof
.regexps_num
<= 1
4564 || regexp
->regexp
.allof
.regexps_num
<= 1)
4566 result
= create_node (sizeof (struct regexp
)
4568 * (regexp
->regexp
.allof
.regexps_num
4569 + allof
->regexp
.allof
.regexps_num
- 2));
4570 result
->mode
= rm_allof
;
4571 result
->pos
= regexp
->pos
;
4572 result
->regexp
.allof
.regexps_num
4573 = (regexp
->regexp
.allof
.regexps_num
4574 + allof
->regexp
.allof
.regexps_num
- 1);
4575 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4576 if (i
< allof_index
)
4577 result
->regexp
.allof
.regexps
[i
]
4578 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4579 else if (i
> allof_index
)
4580 result
->regexp
.allof
.regexps
4581 [i
+ allof
->regexp
.allof
.regexps_num
- 1]
4582 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[i
]);
4584 for (j
= 0; j
< allof
->regexp
.allof
.regexps_num
; j
++)
4585 result
->regexp
.allof
.regexps
[i
+ j
]
4586 = copy_insn_regexp (allof
->regexp
.allof
.regexps
[j
]);
4587 regexp_transformed_p
= 1;
4591 else if (regexp
->mode
== rm_oneof
)
4598 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4599 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
4602 oneof
= regexp
->regexp
.oneof
.regexps
[i
];
4605 if (i
< regexp
->regexp
.oneof
.regexps_num
)
4607 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4608 || regexp
->regexp
.oneof
.regexps_num
<= 1)
4610 result
= create_node (sizeof (struct regexp
)
4612 * (regexp
->regexp
.oneof
.regexps_num
4613 + oneof
->regexp
.oneof
.regexps_num
- 2));
4614 result
->mode
= rm_oneof
;
4615 result
->pos
= regexp
->pos
;
4616 result
->regexp
.oneof
.regexps_num
4617 = (regexp
->regexp
.oneof
.regexps_num
4618 + oneof
->regexp
.oneof
.regexps_num
- 1);
4619 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4620 if (i
< oneof_index
)
4621 result
->regexp
.oneof
.regexps
[i
]
4622 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4623 else if (i
> oneof_index
)
4624 result
->regexp
.oneof
.regexps
4625 [i
+ oneof
->regexp
.oneof
.regexps_num
- 1]
4626 = copy_insn_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
4628 for (j
= 0; j
< oneof
->regexp
.oneof
.regexps_num
; j
++)
4629 result
->regexp
.oneof
.regexps
[i
+ j
]
4630 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[j
]);
4631 regexp_transformed_p
= 1;
4638 /* The function makes transformations
4639 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4640 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|... */
4642 transform_3 (regexp
)
4645 if (regexp
->mode
== rm_sequence
)
4653 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4654 if (regexp
->regexp
.sequence
.regexps
[i
]->mode
== rm_oneof
)
4657 oneof
= regexp
->regexp
.sequence
.regexps
[i
];
4660 if (i
< regexp
->regexp
.sequence
.regexps_num
)
4662 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4663 || regexp
->regexp
.sequence
.regexps_num
<= 1)
4665 result
= create_node (sizeof (struct regexp
)
4667 * (oneof
->regexp
.oneof
.regexps_num
- 1));
4668 result
->mode
= rm_oneof
;
4669 result
->pos
= regexp
->pos
;
4670 result
->regexp
.oneof
.regexps_num
= oneof
->regexp
.oneof
.regexps_num
;
4671 for (i
= 0; i
< result
->regexp
.oneof
.regexps_num
; i
++)
4674 = create_node (sizeof (struct regexp
)
4676 * (regexp
->regexp
.sequence
.regexps_num
- 1));
4677 sequence
->mode
= rm_sequence
;
4678 sequence
->pos
= regexp
->pos
;
4679 sequence
->regexp
.sequence
.regexps_num
4680 = regexp
->regexp
.sequence
.regexps_num
;
4681 result
->regexp
.oneof
.regexps
[i
] = sequence
;
4682 for (j
= 0; j
< sequence
->regexp
.sequence
.regexps_num
; j
++)
4683 if (j
!= oneof_index
)
4684 sequence
->regexp
.sequence
.regexps
[j
]
4685 = copy_insn_regexp (regexp
->regexp
.sequence
.regexps
[j
]);
4687 sequence
->regexp
.sequence
.regexps
[j
]
4688 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[i
]);
4690 regexp_transformed_p
= 1;
4694 else if (regexp
->mode
== rm_allof
)
4702 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4703 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_oneof
)
4706 oneof
= regexp
->regexp
.allof
.regexps
[i
];
4709 if (i
< regexp
->regexp
.allof
.regexps_num
)
4711 if (oneof
->regexp
.oneof
.regexps_num
<= 1
4712 || regexp
->regexp
.allof
.regexps_num
<= 1)
4714 result
= create_node (sizeof (struct regexp
)
4716 * (oneof
->regexp
.oneof
.regexps_num
- 1));
4717 result
->mode
= rm_oneof
;
4718 result
->pos
= regexp
->pos
;
4719 result
->regexp
.oneof
.regexps_num
= oneof
->regexp
.oneof
.regexps_num
;
4720 for (i
= 0; i
< result
->regexp
.oneof
.regexps_num
; i
++)
4723 = create_node (sizeof (struct regexp
)
4725 * (regexp
->regexp
.allof
.regexps_num
- 1));
4726 allof
->mode
= rm_allof
;
4727 allof
->pos
= regexp
->pos
;
4728 allof
->regexp
.allof
.regexps_num
4729 = regexp
->regexp
.allof
.regexps_num
;
4730 result
->regexp
.oneof
.regexps
[i
] = allof
;
4731 for (j
= 0; j
< allof
->regexp
.allof
.regexps_num
; j
++)
4732 if (j
!= oneof_index
)
4733 allof
->regexp
.allof
.regexps
[j
]
4734 = copy_insn_regexp (regexp
->regexp
.allof
.regexps
[j
]);
4736 allof
->regexp
.allof
.regexps
[j
]
4737 = copy_insn_regexp (oneof
->regexp
.oneof
.regexps
[i
]);
4739 regexp_transformed_p
= 1;
4746 /* The function traverses IR of reservation and applies transformations
4747 implemented by FUNC. */
4749 regexp_transform_func (regexp
, func
)
4751 regexp_t (*func
) PARAMS ((regexp_t regexp
));
4755 if (regexp
->mode
== rm_sequence
)
4756 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
4757 regexp
->regexp
.sequence
.regexps
[i
]
4758 = regexp_transform_func (regexp
->regexp
.sequence
.regexps
[i
], func
);
4759 else if (regexp
->mode
== rm_allof
)
4760 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
4761 regexp
->regexp
.allof
.regexps
[i
]
4762 = regexp_transform_func (regexp
->regexp
.allof
.regexps
[i
], func
);
4763 else if (regexp
->mode
== rm_oneof
)
4764 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
4765 regexp
->regexp
.oneof
.regexps
[i
]
4766 = regexp_transform_func (regexp
->regexp
.oneof
.regexps
[i
], func
);
4767 else if (regexp
->mode
== rm_repeat
)
4768 regexp
->regexp
.repeat
.regexp
4769 = regexp_transform_func (regexp
->regexp
.repeat
.regexp
, func
);
4770 else if (regexp
->mode
!= rm_nothing
&& regexp
->mode
!= rm_unit
)
4772 return (*func
) (regexp
);
4775 /* The function applies all transformations for IR representation of
4776 reservation REGEXP. */
4778 transform_regexp (regexp
)
4781 regexp
= regexp_transform_func (regexp
, transform_1
);
4784 regexp_transformed_p
= 0;
4785 regexp
= regexp_transform_func (regexp
, transform_2
);
4786 regexp
= regexp_transform_func (regexp
, transform_3
);
4788 while (regexp_transformed_p
);
4792 /* The function applys all transformations for reservations of all
4793 insn declarations. */
4795 transform_insn_regexps ()
4800 transform_time
= create_ticker ();
4801 add_advance_cycle_insn_decl ();
4802 fprintf (stderr
, "Reservation transformation...");
4804 for (i
= 0; i
< description
->decls_num
; i
++)
4806 decl
= description
->decls
[i
];
4807 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
4808 decl
->decl
.insn_reserv
.transformed_regexp
4809 = transform_regexp (copy_insn_regexp
4810 (decl
->decl
.insn_reserv
.regexp
));
4812 fprintf (stderr
, "done\n");
4813 ticker_off (&transform_time
);
4819 /* The following variable is an array indexed by cycle. Each element
4820 contains cyclic list of units which should be in the same cycle. */
4821 static unit_decl_t
*the_same_automaton_lists
;
4823 /* The function processes all alternative reservations on CYCLE in
4824 given REGEXP to check the UNIT is not reserved on the all
4825 alternatives. If it is true, the unit should be in the same
4826 automaton with other analogous units reserved on CYCLE in given
4829 process_unit_to_form_the_same_automaton_unit_lists (unit
, regexp
, cycle
)
4835 regexp_t seq
, allof
;
4836 unit_decl_t unit_decl
, last
;
4838 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
4840 unit_decl
= unit
->regexp
.unit
.unit_decl
;
4841 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
4843 seq
= regexp
->regexp
.oneof
.regexps
[i
];
4844 if (seq
->mode
== rm_sequence
)
4846 if (cycle
>= seq
->regexp
.sequence
.regexps_num
)
4848 allof
= seq
->regexp
.sequence
.regexps
[cycle
];
4849 if (allof
->mode
== rm_allof
)
4851 for (k
= 0; k
< allof
->regexp
.allof
.regexps_num
; k
++)
4852 if (allof
->regexp
.allof
.regexps
[k
]->mode
== rm_unit
4853 && (allof
->regexp
.allof
.regexps
[k
]->regexp
.unit
.unit_decl
4856 if (k
>= allof
->regexp
.allof
.regexps_num
)
4859 else if (allof
->mode
== rm_unit
4860 && allof
->regexp
.unit
.unit_decl
!= unit_decl
)
4863 else if (cycle
!= 0)
4865 else if (seq
->mode
== rm_allof
)
4867 for (k
= 0; k
< seq
->regexp
.allof
.regexps_num
; k
++)
4868 if (seq
->regexp
.allof
.regexps
[k
]->mode
== rm_unit
4869 && (seq
->regexp
.allof
.regexps
[k
]->regexp
.unit
.unit_decl
4872 if (k
>= seq
->regexp
.allof
.regexps_num
)
4875 else if (seq
->mode
== rm_unit
&& seq
->regexp
.unit
.unit_decl
!= unit_decl
)
4880 if (the_same_automaton_lists
[cycle
] == NULL
)
4881 the_same_automaton_lists
[cycle
] = unit_decl
;
4884 for (last
= the_same_automaton_lists
[cycle
];;)
4886 if (last
== unit_decl
)
4888 if (last
->the_same_automaton_unit
4889 == the_same_automaton_lists
[cycle
])
4891 last
= last
->the_same_automaton_unit
;
4893 last
->the_same_automaton_unit
= unit_decl
->the_same_automaton_unit
;
4894 unit_decl
->the_same_automaton_unit
4895 = the_same_automaton_lists
[cycle
];
4900 /* The function processes given REGEXP to find units which should be
4901 in the same automaton. */
4903 form_the_same_automaton_unit_lists_from_regexp (regexp
)
4907 regexp_t seq
, allof
, unit
;
4909 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
4911 for (i
= 0; i
< description
->max_insn_reserv_cycles
; i
++)
4912 the_same_automaton_lists
[i
] = NULL
;
4913 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
4915 seq
= regexp
->regexp
.oneof
.regexps
[i
];
4916 if (seq
->mode
== rm_sequence
)
4917 for (j
= 0; j
< seq
->regexp
.sequence
.regexps_num
; j
++)
4919 allof
= seq
->regexp
.sequence
.regexps
[j
];
4920 if (allof
->mode
== rm_allof
)
4921 for (k
= 0; k
< allof
->regexp
.allof
.regexps_num
; k
++)
4923 unit
= allof
->regexp
.allof
.regexps
[k
];
4924 if (unit
->mode
== rm_unit
)
4925 process_unit_to_form_the_same_automaton_unit_lists
4927 else if (unit
->mode
!= rm_nothing
)
4930 else if (allof
->mode
== rm_unit
)
4931 process_unit_to_form_the_same_automaton_unit_lists
4933 else if (allof
->mode
!= rm_nothing
)
4936 else if (seq
->mode
== rm_allof
)
4937 for (k
= 0; k
< seq
->regexp
.allof
.regexps_num
; k
++)
4939 unit
= seq
->regexp
.allof
.regexps
[k
];
4940 if (unit
->mode
== rm_unit
)
4941 process_unit_to_form_the_same_automaton_unit_lists
4943 else if (unit
->mode
!= rm_nothing
)
4946 else if (seq
->mode
== rm_unit
)
4947 process_unit_to_form_the_same_automaton_unit_lists (seq
, regexp
, 0);
4948 else if (seq
->mode
!= rm_nothing
)
4953 /* The function initializes data to search for units which should be
4954 in the same automaton and call function
4955 `form_the_same_automaton_unit_lists_from_regexp' for each insn
4956 reservation regexp. */
4958 form_the_same_automaton_unit_lists ()
4963 the_same_automaton_lists
4964 = (unit_decl_t
*) xmalloc (description
->max_insn_reserv_cycles
4965 * sizeof (unit_decl_t
));
4966 for (i
= 0; i
< description
->decls_num
; i
++)
4968 decl
= description
->decls
[i
];
4969 if (decl
->mode
== dm_unit
)
4971 decl
->decl
.unit
.the_same_automaton_message_reported_p
= FALSE
;
4972 decl
->decl
.unit
.the_same_automaton_unit
= &decl
->decl
.unit
;
4975 for (i
= 0; i
< description
->decls_num
; i
++)
4977 decl
= description
->decls
[i
];
4978 if (decl
->mode
== dm_insn_reserv
)
4979 form_the_same_automaton_unit_lists_from_regexp
4980 (decl
->decl
.insn_reserv
.transformed_regexp
);
4982 free (the_same_automaton_lists
);
4985 /* The function finds units which should be in the same automaton and,
4986 if they are not, reports about it. */
4988 check_unit_distributions_to_automata ()
4991 unit_decl_t start_unit_decl
, unit_decl
;
4994 form_the_same_automaton_unit_lists ();
4995 for (i
= 0; i
< description
->decls_num
; i
++)
4997 decl
= description
->decls
[i
];
4998 if (decl
->mode
== dm_unit
)
5000 start_unit_decl
= &decl
->decl
.unit
;
5001 if (!start_unit_decl
->the_same_automaton_message_reported_p
)
5002 for (unit_decl
= start_unit_decl
->the_same_automaton_unit
;
5003 unit_decl
!= start_unit_decl
;
5004 unit_decl
= unit_decl
->the_same_automaton_unit
)
5005 if (start_unit_decl
->automaton_decl
!= unit_decl
->automaton_decl
)
5007 error ("Units `%s' and `%s' should be in the same automaton",
5008 start_unit_decl
->name
, unit_decl
->name
);
5009 unit_decl
->the_same_automaton_message_reported_p
= TRUE
;
5017 /* The page contains code for building alt_states (see comments for
5018 IR) describing all possible insns reservations of an automaton. */
5020 /* Current state being formed for which the current alt_state
5022 static state_t state_being_formed
;
5024 /* Current alt_state being formed. */
5025 static alt_state_t alt_state_being_formed
;
5027 /* This recursive function processes `,' and units in reservation
5028 REGEXP for forming alt_states of AUTOMATON. It is believed that
5029 CURR_CYCLE is start cycle of all reservation REGEXP. */
5031 process_seq_for_forming_states (regexp
, automaton
, curr_cycle
)
5033 automaton_t automaton
;
5040 else if (regexp
->mode
== rm_unit
)
5042 if (regexp
->regexp
.unit
.unit_decl
->corresponding_automaton_num
5043 == automaton
->automaton_order_num
)
5044 set_state_reserv (state_being_formed
, curr_cycle
,
5045 regexp
->regexp
.unit
.unit_decl
->unit_num
);
5048 else if (regexp
->mode
== rm_sequence
)
5050 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
5052 = process_seq_for_forming_states
5053 (regexp
->regexp
.sequence
.regexps
[i
], automaton
, curr_cycle
) + 1;
5056 else if (regexp
->mode
== rm_allof
)
5058 int finish_cycle
= 0;
5061 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
5064 = process_seq_for_forming_states (regexp
->regexp
.allof
.regexps
[i
],
5065 automaton
, curr_cycle
);
5066 if (finish_cycle
< cycle
)
5067 finish_cycle
= cycle
;
5069 return finish_cycle
;
5073 if (regexp
->mode
!= rm_nothing
)
5079 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5080 inserts alt_state into the table. */
5082 finish_forming_alt_state (alt_state
, automaton
)
5083 alt_state_t alt_state
;
5084 automaton_t automaton ATTRIBUTE_UNUSED
;
5086 state_t state_in_table
;
5087 state_t corresponding_state
;
5089 corresponding_state
= alt_state
->state
;
5090 state_in_table
= insert_state (corresponding_state
);
5091 if (state_in_table
!= corresponding_state
)
5093 free_state (corresponding_state
);
5094 alt_state
->state
= state_in_table
;
5098 /* The following variable value is current automaton insn for whose
5099 reservation the alt states are created. */
5100 static ainsn_t curr_ainsn
;
5102 /* This recursive function processes `|' in reservation REGEXP for
5103 forming alt_states of AUTOMATON. List of the alt states should
5104 have the same order as in the description. */
5106 process_alts_for_forming_states (regexp
, automaton
, inside_oneof_p
)
5108 automaton_t automaton
;
5113 if (regexp
->mode
!= rm_oneof
)
5115 alt_state_being_formed
= get_free_alt_state ();
5116 state_being_formed
= get_free_state (1, automaton
);
5117 alt_state_being_formed
->state
= state_being_formed
;
5118 /* We inserts in reverse order but we process alternatives also
5119 in reverse order. So we have the same order of alternative
5120 as in the description. */
5121 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5122 curr_ainsn
->alt_states
= alt_state_being_formed
;
5123 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5124 finish_forming_alt_state (alt_state_being_formed
, automaton
);
5130 /* We processes it in reverse order to get list with the same
5131 order as in the description. See also the previous
5133 for (i
= regexp
->regexp
.oneof
.regexps_num
- 1; i
>= 0; i
--)
5134 process_alts_for_forming_states (regexp
->regexp
.oneof
.regexps
[i
],
5139 /* Create nodes alt_state for all AUTOMATON insns. */
5141 create_alt_states (automaton
)
5142 automaton_t automaton
;
5144 struct insn_reserv_decl
*reserv_decl
;
5146 for (curr_ainsn
= automaton
->ainsn_list
;
5148 curr_ainsn
= curr_ainsn
->next_ainsn
)
5150 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5151 if (reserv_decl
!= &advance_cycle_insn_decl
->decl
.insn_reserv
)
5153 curr_ainsn
->alt_states
= NULL
;
5154 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5156 curr_ainsn
->sorted_alt_states
5157 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5164 /* The page contains major code for building DFA(s) for fast pipeline
5165 hazards recognition. */
5167 /* The function forms list of ainsns of AUTOMATON with the same
5170 form_ainsn_with_same_reservs (automaton
)
5171 automaton_t automaton
;
5175 vla_ptr_t first_insns
;
5176 vla_ptr_t last_insns
;
5178 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5179 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5180 for (curr_ainsn
= automaton
->ainsn_list
;
5182 curr_ainsn
= curr_ainsn
->next_ainsn
)
5183 if (curr_ainsn
->insn_reserv_decl
5184 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
5186 curr_ainsn
->next_same_reservs_insn
= NULL
;
5187 curr_ainsn
->first_insn_with_same_reservs
= 1;
5191 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5193 (curr_ainsn
->sorted_alt_states
,
5194 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5196 curr_ainsn
->next_same_reservs_insn
= NULL
;
5197 if (i
< VLA_PTR_LENGTH (first_insns
))
5199 curr_ainsn
->first_insn_with_same_reservs
= 0;
5200 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5202 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5206 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5207 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5208 curr_ainsn
->first_insn_with_same_reservs
= 1;
5211 VLA_PTR_DELETE (first_insns
);
5212 VLA_PTR_DELETE (last_insns
);
5215 /* The following function creates all states of nondeterministic (if
5216 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5218 make_automaton (automaton
)
5219 automaton_t automaton
;
5222 struct insn_reserv_decl
*insn_reserv_decl
;
5223 alt_state_t alt_state
;
5225 state_t start_state
;
5227 ainsn_t advance_cycle_ainsn
;
5229 vla_ptr_t state_stack
;
5231 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5232 /* Create the start state (empty state). */
5233 start_state
= insert_state (get_free_state (1, automaton
));
5234 automaton
->start_state
= start_state
;
5235 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5236 VLA_PTR_ADD (state_stack
, start_state
);
5237 while (VLA_PTR_LENGTH (state_stack
) != 0)
5239 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5240 VLA_PTR_SHORTEN (state_stack
, 1);
5241 advance_cycle_ainsn
= NULL
;
5242 for (ainsn
= automaton
->ainsn_list
;
5244 ainsn
= ainsn
->next_ainsn
)
5245 if (ainsn
->first_insn_with_same_reservs
)
5247 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5248 if (insn_reserv_decl
!= &advance_cycle_insn_decl
->decl
.insn_reserv
)
5250 /* We process alt_states in the same order as they are
5251 present in the description. */
5253 for (alt_state
= ainsn
->alt_states
;
5255 alt_state
= alt_state
->next_alt_state
)
5257 state2
= alt_state
->state
;
5258 if (!intersected_state_reservs_p (state
, state2
))
5260 state2
= states_union (state
, state2
);
5261 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5263 state2
->it_was_placed_in_stack_for_NDFA_forming
5265 VLA_PTR_ADD (state_stack
, state2
);
5267 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5272 if (!ndfa_flag
&& added_arc
!= NULL
)
5274 added_arc
->state_alts
= 0;
5275 for (alt_state
= ainsn
->alt_states
;
5277 alt_state
= alt_state
->next_alt_state
)
5279 state2
= alt_state
->state
;
5280 if (!intersected_state_reservs_p (state
, state2
))
5281 added_arc
->state_alts
++;
5286 advance_cycle_ainsn
= ainsn
;
5288 /* Add transition to advance cycle. */
5289 state2
= state_shift (state
);
5290 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5292 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5293 VLA_PTR_ADD (state_stack
, state2
);
5295 if (advance_cycle_ainsn
== NULL
)
5297 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5299 VLA_PTR_DELETE (state_stack
);
5302 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5304 form_arcs_marked_by_insn (state
)
5311 for (i
= 0; i
< description
->decls_num
; i
++)
5313 decl
= description
->decls
[i
];
5314 if (decl
->mode
== dm_insn_reserv
)
5315 decl
->decl
.insn_reserv
.arcs_marked_by_insn
= NULL
;
5317 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5319 if (arc
->insn
== NULL
)
5321 arc
->next_arc_marked_by_insn
5322 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5323 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5327 /* The function creates composed state (see comments for IR) from
5328 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5329 same insn. If the composed state is not in STATE_STACK yet, it is
5330 popped to STATE_STACK. */
5332 create_composed_state (original_state
, arcs_marked_by_insn
, state_stack
)
5333 state_t original_state
;
5334 arc_t arcs_marked_by_insn
;
5335 vla_ptr_t
*state_stack
;
5338 alt_state_t curr_alt_state
;
5339 alt_state_t new_alt_state
;
5342 state_t state_in_table
;
5344 alt_state_t canonical_alt_states_list
;
5347 if (arcs_marked_by_insn
== NULL
)
5349 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5350 state
= arcs_marked_by_insn
->to_state
;
5355 /* Create composed state. */
5356 state
= get_free_state (0, arcs_marked_by_insn
->to_state
->automaton
);
5357 curr_alt_state
= NULL
;
5358 for (curr_arc
= arcs_marked_by_insn
;
5360 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5362 new_alt_state
= get_free_alt_state ();
5363 new_alt_state
->next_alt_state
= curr_alt_state
;
5364 new_alt_state
->state
= curr_arc
->to_state
;
5365 if (curr_arc
->to_state
->component_states
!= NULL
)
5367 curr_alt_state
= new_alt_state
;
5369 /* There are not identical sets in the alt state list. */
5370 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5371 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5374 state
= canonical_alt_states_list
->state
;
5375 free_state (temp_state
);
5379 state
->component_states
= canonical_alt_states_list
;
5380 state_in_table
= insert_state (state
);
5381 if (state_in_table
!= state
)
5383 if (!state_in_table
->it_was_placed_in_stack_for_DFA_forming
)
5386 state
= state_in_table
;
5390 if (state
->it_was_placed_in_stack_for_DFA_forming
)
5392 for (curr_alt_state
= state
->component_states
;
5393 curr_alt_state
!= NULL
;
5394 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
5395 for (curr_arc
= first_out_arc (curr_alt_state
->state
);
5397 curr_arc
= next_out_arc (curr_arc
))
5398 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5400 arcs_marked_by_insn
->to_state
= state
;
5401 for (alts_number
= 0,
5402 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5404 curr_arc
= next_arc
)
5406 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5407 remove_arc (original_state
, curr_arc
);
5410 arcs_marked_by_insn
->state_alts
= alts_number
;
5413 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5415 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5416 VLA_PTR_ADD (*state_stack
, state
);
5420 /* The function transformes nondeterminstic AUTOMATON into
5423 NDFA_to_DFA (automaton
)
5424 automaton_t automaton
;
5426 state_t start_state
;
5429 vla_ptr_t state_stack
;
5432 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5433 /* Create the start state (empty state). */
5434 start_state
= automaton
->start_state
;
5435 start_state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5436 VLA_PTR_ADD (state_stack
, start_state
);
5437 while (VLA_PTR_LENGTH (state_stack
) != 0)
5439 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5440 VLA_PTR_SHORTEN (state_stack
, 1);
5441 form_arcs_marked_by_insn (state
);
5442 for (i
= 0; i
< description
->decls_num
; i
++)
5444 decl
= description
->decls
[i
];
5445 if (decl
->mode
== dm_insn_reserv
)
5446 create_composed_state
5447 (state
, decl
->decl
.insn_reserv
.arcs_marked_by_insn
,
5451 VLA_PTR_DELETE (state_stack
);
5454 /* The following variable value is current number (1, 2, ...) of passing
5456 static int curr_state_graph_pass_num
;
5458 /* This recursive function passes all states achieved from START_STATE
5459 and applies APPLIED_FUNC to them. */
5461 pass_state_graph (start_state
, applied_func
)
5462 state_t start_state
;
5463 void (*applied_func
) PARAMS ((state_t state
));
5467 if (start_state
->pass_num
== curr_state_graph_pass_num
)
5469 start_state
->pass_num
= curr_state_graph_pass_num
;
5470 (*applied_func
) (start_state
);
5471 for (arc
= first_out_arc (start_state
);
5473 arc
= next_out_arc (arc
))
5474 pass_state_graph (arc
->to_state
, applied_func
);
5477 /* This recursive function passes all states of AUTOMATON and applies
5478 APPLIED_FUNC to them. */
5480 pass_states (automaton
, applied_func
)
5481 automaton_t automaton
;
5482 void (*applied_func
) PARAMS ((state_t state
));
5484 curr_state_graph_pass_num
++;
5485 pass_state_graph (automaton
->start_state
, applied_func
);
5488 /* The function initializes code for passing of all states. */
5490 initiate_pass_states ()
5492 curr_state_graph_pass_num
= 0;
5495 /* The following vla is used for storing pointers to all achieved
5497 static vla_ptr_t all_achieved_states
;
5499 /* This function is called by function pass_states to add an achieved
5502 add_achieved_state (state
)
5505 VLA_PTR_ADD (all_achieved_states
, state
);
5508 /* The function sets up equivalence numbers of insns which mark all
5509 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5510 nonzero value) or by equiv_class_num_2 of the destination state.
5511 The function returns number of out arcs of STATE. */
5513 set_out_arc_insns_equiv_num (state
, odd_iteration_flag
)
5515 int odd_iteration_flag
;
5517 int state_out_arcs_num
;
5520 state_out_arcs_num
= 0;
5521 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5523 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
!= 0
5524 || arc
->insn
->insn_reserv_decl
->state_alts
!= 0)
5526 state_out_arcs_num
++;
5527 arc
->insn
->insn_reserv_decl
->equiv_class_num
5528 = (odd_iteration_flag
5529 ? arc
->to_state
->equiv_class_num_1
5530 : arc
->to_state
->equiv_class_num_2
);
5531 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
5532 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
== 0
5533 || arc
->insn
->insn_reserv_decl
->state_alts
<= 0)
5536 return state_out_arcs_num
;
5539 /* The function clears equivalence numbers and alt_states in all insns
5540 which mark all out arcs of STATE. */
5542 clear_arc_insns_equiv_num (state
)
5547 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5549 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
5550 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
5554 /* The function copies pointers to equivalent states from vla FROM
5557 copy_equiv_class (to
, from
)
5559 const vla_ptr_t
*from
;
5563 VLA_PTR_NULLIFY (*to
);
5564 for (class_ptr
= VLA_PTR_BEGIN (*from
);
5565 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
5567 VLA_PTR_ADD (*to
, *class_ptr
);
5570 /* The function returns nonzero value if STATE is not equivalent to
5571 another state from the same current partition on equivalence
5572 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5573 output arcs. Iteration of making equivalence partition is defined
5574 by ODD_ITERATION_FLAG. */
5576 state_is_differed (state
, original_state_out_arcs_num
, odd_iteration_flag
)
5578 int original_state_out_arcs_num
;
5579 int odd_iteration_flag
;
5582 int state_out_arcs_num
;
5584 state_out_arcs_num
= 0;
5585 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5587 state_out_arcs_num
++;
5588 if ((odd_iteration_flag
5589 ? arc
->to_state
->equiv_class_num_1
5590 : arc
->to_state
->equiv_class_num_2
)
5591 != arc
->insn
->insn_reserv_decl
->equiv_class_num
5592 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
5595 return state_out_arcs_num
!= original_state_out_arcs_num
;
5598 /* The function makes initial partition of STATES on equivalent
5601 init_equiv_class (states
, states_num
)
5606 state_t result_equiv_class
;
5608 result_equiv_class
= NULL
;
5609 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
5611 (*state_ptr
)->equiv_class_num_1
= 1;
5612 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
5613 result_equiv_class
= *state_ptr
;
5615 return result_equiv_class
;
5618 /* The function processes equivalence class given by its pointer
5619 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5620 are not equvalent states, the function partitions the class
5621 removing nonequivalent states and placing them in
5622 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5623 assigns it to the state equivalence number. If the class has been
5624 partitioned, the function returns nonzero value. */
5626 partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5627 next_iteration_classes
, new_equiv_class_num_ptr
)
5628 state_t
*equiv_class_ptr
;
5629 int odd_iteration_flag
;
5630 vla_ptr_t
*next_iteration_classes
;
5631 int *new_equiv_class_num_ptr
;
5633 state_t new_equiv_class
;
5635 state_t first_state
;
5642 if (*equiv_class_ptr
== NULL
)
5644 for (first_state
= *equiv_class_ptr
;
5645 first_state
!= NULL
;
5646 first_state
= new_equiv_class
)
5648 new_equiv_class
= NULL
;
5649 if (first_state
->next_equiv_class_state
!= NULL
)
5651 /* There are more one states in the class equivalence. */
5652 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
5653 odd_iteration_flag
);
5654 for (prev_state
= first_state
,
5655 curr_state
= first_state
->next_equiv_class_state
;
5657 curr_state
= next_state
)
5659 next_state
= curr_state
->next_equiv_class_state
;
5660 if (state_is_differed (curr_state
, out_arcs_num
,
5661 odd_iteration_flag
))
5663 /* Remove curr state from the class equivalence. */
5664 prev_state
->next_equiv_class_state
= next_state
;
5665 /* Add curr state to the new class equivalence. */
5666 curr_state
->next_equiv_class_state
= new_equiv_class
;
5667 if (new_equiv_class
== NULL
)
5668 (*new_equiv_class_num_ptr
)++;
5669 if (odd_iteration_flag
)
5670 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
5672 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
5673 new_equiv_class
= curr_state
;
5677 prev_state
= curr_state
;
5679 clear_arc_insns_equiv_num (first_state
);
5681 if (new_equiv_class
!= NULL
)
5682 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
5687 /* The function finds equivalent states of AUTOMATON. */
5689 evaluate_equiv_classes (automaton
, equiv_classes
)
5690 automaton_t automaton
;
5691 vla_ptr_t
*equiv_classes
;
5693 state_t new_equiv_class
;
5694 int new_equiv_class_num
;
5695 int odd_iteration_flag
;
5697 vla_ptr_t next_iteration_classes
;
5698 state_t
*equiv_class_ptr
;
5701 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
5702 pass_states (automaton
, add_achieved_state
);
5703 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
5704 VLA_PTR_LENGTH (all_achieved_states
));
5705 odd_iteration_flag
= 0;
5706 new_equiv_class_num
= 1;
5707 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
5708 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
5711 odd_iteration_flag
= !odd_iteration_flag
;
5713 copy_equiv_class (equiv_classes
, &next_iteration_classes
);
5714 /* Transfer equiv numbers for the next iteration. */
5715 for (state_ptr
= VLA_PTR_BEGIN (all_achieved_states
);
5716 state_ptr
<= (state_t
*) VLA_PTR_LAST (all_achieved_states
);
5718 if (odd_iteration_flag
)
5719 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
5721 (*state_ptr
)->equiv_class_num_1
= (*state_ptr
)->equiv_class_num_2
;
5722 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5723 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5725 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5726 &next_iteration_classes
,
5727 &new_equiv_class_num
))
5730 while (!finish_flag
);
5731 VLA_PTR_DELETE (next_iteration_classes
);
5732 VLA_PTR_DELETE (all_achieved_states
);
5735 /* The function merges equivalent states of AUTOMATON. */
5737 merge_states (automaton
, equiv_classes
)
5738 automaton_t automaton
;
5739 vla_ptr_t
*equiv_classes
;
5741 state_t
*equiv_class_ptr
;
5744 state_t first_class_state
;
5745 alt_state_t alt_states
;
5746 alt_state_t new_alt_state
;
5750 /* Create states corresponding to equivalence classes containing two
5752 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5753 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5755 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
5757 /* There are more one states in the class equivalence. */
5758 /* Create new compound state. */
5759 new_state
= get_free_state (0, automaton
);
5761 first_class_state
= *equiv_class_ptr
;
5762 for (curr_state
= first_class_state
;
5764 curr_state
= curr_state
->next_equiv_class_state
)
5766 curr_state
->equiv_class_state
= new_state
;
5767 new_alt_state
= get_free_alt_state ();
5768 new_alt_state
->state
= curr_state
;
5769 new_alt_state
->next_sorted_alt_state
= alt_states
;
5770 alt_states
= new_alt_state
;
5772 new_state
->component_states
= alt_states
;
5775 (*equiv_class_ptr
)->equiv_class_state
= *equiv_class_ptr
;
5776 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
5777 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
5779 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
5781 first_class_state
= *equiv_class_ptr
;
5782 /* Create new arcs output from the state corresponding to
5784 for (curr_arc
= first_out_arc (first_class_state
);
5786 curr_arc
= next_out_arc (curr_arc
))
5787 add_arc (first_class_state
->equiv_class_state
,
5788 curr_arc
->to_state
->equiv_class_state
,
5789 curr_arc
->insn
, curr_arc
->state_alts
);
5790 /* Delete output arcs from states of given class equivalence. */
5791 for (curr_state
= first_class_state
;
5793 curr_state
= curr_state
->next_equiv_class_state
)
5795 if (automaton
->start_state
== curr_state
)
5796 automaton
->start_state
= curr_state
->equiv_class_state
;
5797 /* Delete the state and its output arcs. */
5798 for (curr_arc
= first_out_arc (curr_state
);
5800 curr_arc
= next_arc
)
5802 next_arc
= next_out_arc (curr_arc
);
5803 free_arc (curr_arc
);
5809 /* Change `to_state' of arcs output from the state of given
5810 equivalence class. */
5811 for (curr_arc
= first_out_arc (*equiv_class_ptr
);
5813 curr_arc
= next_out_arc (curr_arc
))
5814 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
5818 /* The function sets up new_cycle_p for states if there is arc to the
5819 state marked by advance_cycle_insn_decl. */
5821 set_new_cycle_flags (state
)
5826 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5827 if (arc
->insn
->insn_reserv_decl
5828 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
5829 arc
->to_state
->new_cycle_p
= 1;
5832 /* The top level function for minimization of deterministic
5835 minimize_DFA (automaton
)
5836 automaton_t automaton
;
5838 vla_ptr_t equiv_classes
;
5840 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
5841 evaluate_equiv_classes (automaton
, &equiv_classes
);
5842 merge_states (automaton
, &equiv_classes
);
5843 pass_states (automaton
, set_new_cycle_flags
);
5844 VLA_PTR_DELETE (equiv_classes
);
5847 /* Values of two variables are counted number of states and arcs in an
5849 static int curr_counted_states_num
;
5850 static int curr_counted_arcs_num
;
5852 /* The function is called by function `pass_states' to count states
5853 and arcs of an automaton. */
5855 incr_states_and_arcs_nums (state
)
5860 curr_counted_states_num
++;
5861 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5862 curr_counted_arcs_num
++;
5865 /* The function counts states and arcs of AUTOMATON. */
5867 count_states_and_arcs (automaton
, states_num
, arcs_num
)
5868 automaton_t automaton
;
5872 curr_counted_states_num
= 0;
5873 curr_counted_arcs_num
= 0;
5874 pass_states (automaton
, incr_states_and_arcs_nums
);
5875 *states_num
= curr_counted_states_num
;
5876 *arcs_num
= curr_counted_arcs_num
;
5879 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5880 recognition after checking and simplifying IR of the
5883 build_automaton (automaton
)
5884 automaton_t automaton
;
5889 ticker_on (&NDFA_time
);
5890 make_automaton (automaton
);
5891 ticker_off (&NDFA_time
);
5892 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5893 automaton
->NDFA_states_num
= states_num
;
5894 automaton
->NDFA_arcs_num
= arcs_num
;
5895 ticker_on (&NDFA_to_DFA_time
);
5896 NDFA_to_DFA (automaton
);
5897 ticker_off (&NDFA_to_DFA_time
);
5898 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5899 automaton
->DFA_states_num
= states_num
;
5900 automaton
->DFA_arcs_num
= arcs_num
;
5901 if (!no_minimization_flag
)
5903 ticker_on (&minimize_time
);
5904 minimize_DFA (automaton
);
5905 ticker_off (&minimize_time
);
5906 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
5907 automaton
->minimal_DFA_states_num
= states_num
;
5908 automaton
->minimal_DFA_arcs_num
= arcs_num
;
5914 /* The page contains code for enumeration of all states of an automaton. */
5916 /* Variable used for enumeration of all states of an automaton. Its
5917 value is current number of automaton states. */
5918 static int curr_state_order_num
;
5920 /* The function is called by function `pass_states' for enumerating
5923 set_order_state_num (state
)
5926 state
->order_state_num
= curr_state_order_num
;
5927 curr_state_order_num
++;
5930 /* The function enumerates all states of AUTOMATON. */
5932 enumerate_states (automaton
)
5933 automaton_t automaton
;
5935 curr_state_order_num
= 0;
5936 pass_states (automaton
, set_order_state_num
);
5937 automaton
->achieved_states_num
= curr_state_order_num
;
5942 /* The page contains code for finding equivalent automaton insns
5945 /* The function inserts AINSN into cyclic list
5946 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
5948 insert_ainsn_into_equiv_class (ainsn
, cyclic_equiv_class_insn_list
)
5950 ainsn_t cyclic_equiv_class_insn_list
;
5952 if (cyclic_equiv_class_insn_list
== NULL
)
5953 ainsn
->next_equiv_class_insn
= ainsn
;
5956 ainsn
->next_equiv_class_insn
5957 = cyclic_equiv_class_insn_list
->next_equiv_class_insn
;
5958 cyclic_equiv_class_insn_list
->next_equiv_class_insn
= ainsn
;
5963 /* The function deletes equiv_class_insn into cyclic list of
5964 equivalent ainsns. */
5966 delete_ainsn_from_equiv_class (equiv_class_insn
)
5967 ainsn_t equiv_class_insn
;
5969 ainsn_t curr_equiv_class_insn
;
5970 ainsn_t prev_equiv_class_insn
;
5972 prev_equiv_class_insn
= equiv_class_insn
;
5973 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
5974 curr_equiv_class_insn
!= equiv_class_insn
;
5975 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
5976 prev_equiv_class_insn
= curr_equiv_class_insn
;
5977 if (prev_equiv_class_insn
!= equiv_class_insn
)
5978 prev_equiv_class_insn
->next_equiv_class_insn
5979 = equiv_class_insn
->next_equiv_class_insn
;
5982 /* The function processes AINSN of a state in order to find equivalent
5983 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
5986 process_insn_equiv_class (ainsn
, insn_arcs_array
)
5988 arc_t
*insn_arcs_array
;
5992 ainsn_t cyclic_insn_list
;
5995 if (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
] == NULL
)
5998 /* New class of ainsns which are not equivalent to given ainsn. */
5999 cyclic_insn_list
= NULL
;
6002 next_insn
= curr_insn
->next_equiv_class_insn
;
6003 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6005 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6008 delete_ainsn_from_equiv_class (curr_insn
);
6009 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6012 curr_insn
= next_insn
;
6014 while (curr_insn
!= ainsn
);
6017 /* The function processes STATE in order to find equivalent ainsns. */
6019 process_state_for_insn_equiv_partition (state
)
6023 arc_t
*insn_arcs_array
;
6025 vla_ptr_t insn_arcs_vect
;
6027 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6028 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6029 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6030 /* Process insns of the arcs. */
6031 for (i
= 0; i
< description
->insns_num
; i
++)
6032 insn_arcs_array
[i
] = NULL
;
6033 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6034 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6035 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6036 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6037 VLA_PTR_DELETE (insn_arcs_vect
);
6040 /* The function searches for equivalent ainsns of AUTOMATON. */
6042 set_insn_equiv_classes (automaton
)
6043 automaton_t automaton
;
6048 ainsn_t cyclic_insn_list
;
6049 ainsn_t insn_with_same_reservs
;
6050 int equiv_classes_num
;
6052 /* All insns are included in one equivalence class. */
6053 cyclic_insn_list
= NULL
;
6054 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6055 if (ainsn
->first_insn_with_same_reservs
)
6056 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
6058 /* Process insns in order to make equivalence partition. */
6059 pass_states (automaton
, process_state_for_insn_equiv_partition
);
6060 /* Enumerate equiv classes. */
6061 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6062 /* Set undefined value. */
6063 ainsn
->insn_equiv_class_num
= -1;
6064 equiv_classes_num
= 0;
6065 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6066 if (ainsn
->insn_equiv_class_num
< 0)
6069 if (!first_insn
->first_insn_with_same_reservs
)
6071 first_insn
->first_ainsn_with_given_equialence_num
= 1;
6072 curr_insn
= first_insn
;
6075 for (insn_with_same_reservs
= curr_insn
;
6076 insn_with_same_reservs
!= NULL
;
6077 insn_with_same_reservs
6078 = insn_with_same_reservs
->next_same_reservs_insn
)
6079 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6080 curr_insn
= curr_insn
->next_equiv_class_insn
;
6082 while (curr_insn
!= first_insn
);
6083 equiv_classes_num
++;
6085 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6090 /* This page contains code for creating DFA(s) and calls functions
6094 /* The following value is used to prevent floating point overflow for
6095 estimating an automaton bound. The value should be less DBL_MAX on
6096 the host machine. We use here approximate minimum of maximal
6097 double floating point value required by ANSI C standard. It
6098 will work for non ANSI sun compiler too. */
6100 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6102 /* The function estimate size of the single DFA used by PHR (pipeline
6103 hazards recognizer). */
6105 estimate_one_automaton_bound ()
6108 double one_automaton_estimation_bound
;
6112 one_automaton_estimation_bound
= 1.0;
6113 for (i
= 0; i
< description
->decls_num
; i
++)
6115 decl
= description
->decls
[i
];
6116 if (decl
->mode
== dm_unit
)
6118 root_value
= exp (log (decl
->decl
.unit
.max_occ_cycle_num
+ 1.0)
6120 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6121 > one_automaton_estimation_bound
)
6122 one_automaton_estimation_bound
*= root_value
;
6125 return one_automaton_estimation_bound
;
6128 /* The function compares unit declarations acoording to their maximal
6129 cycle in reservations. */
6131 compare_max_occ_cycle_nums (unit_decl_1
, unit_decl_2
)
6132 const void *unit_decl_1
;
6133 const void *unit_decl_2
;
6135 if (((*(decl_t
*) unit_decl_1
)->decl
.unit
.max_occ_cycle_num
)
6136 < ((*(decl_t
*) unit_decl_2
)->decl
.unit
.max_occ_cycle_num
))
6138 else if (((*(decl_t
*) unit_decl_1
)->decl
.unit
.max_occ_cycle_num
)
6139 == ((*(decl_t
*) unit_decl_2
)->decl
.unit
.max_occ_cycle_num
))
6145 /* The function makes heuristic assigning automata to units. Actually
6146 efficacy of the algorithm has been checked yet??? */
6148 units_to_automata_heuristic_distr ()
6150 double estimation_bound
;
6152 decl_t
*unit_decl_ptr
;
6156 vla_ptr_t unit_decls
;
6159 if (description
->units_num
== 0)
6161 estimation_bound
= estimate_one_automaton_bound ();
6162 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6163 for (i
= 0; i
< description
->decls_num
; i
++)
6165 decl
= description
->decls
[i
];
6166 if (decl
->mode
== dm_unit
)
6167 VLA_PTR_ADD (unit_decls
, decl
);
6169 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6170 sizeof (decl_t
), compare_max_occ_cycle_nums
);
6172 unit_decl_ptr
= VLA_PTR_BEGIN (unit_decls
);
6173 bound_value
= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6174 (*unit_decl_ptr
)->decl
.unit
.corresponding_automaton_num
= automaton_num
;
6175 for (unit_decl_ptr
++;
6176 unit_decl_ptr
<= (decl_t
*) VLA_PTR_LAST (unit_decls
);
6180 = ((decl_t
*) VLA_PTR_LAST (unit_decls
) - unit_decl_ptr
+ 1);
6181 if (automata_num
- automaton_num
- 1 > rest_units_num
)
6183 if (automaton_num
< automata_num
- 1
6184 && ((automata_num
- automaton_num
- 1 == rest_units_num
)
6187 / ((*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
)))))
6189 bound_value
= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6193 bound_value
*= (*unit_decl_ptr
)->decl
.unit
.max_occ_cycle_num
;
6194 (*unit_decl_ptr
)->decl
.unit
.corresponding_automaton_num
= automaton_num
;
6196 if (automaton_num
!= automata_num
- 1)
6198 VLA_PTR_DELETE (unit_decls
);
6201 /* The functions creates automaton insns for each automata. Automaton
6202 insn is simply insn for given automaton which makes reservation
6203 only of units of the automaton. */
6208 ainsn_t first_ainsn
;
6215 for (i
= 0; i
< description
->decls_num
; i
++)
6217 decl
= description
->decls
[i
];
6218 if (decl
->mode
== dm_insn_reserv
)
6220 curr_ainsn
= create_node (sizeof (struct ainsn
));
6221 curr_ainsn
->insn_reserv_decl
= &decl
->decl
.insn_reserv
;
6222 curr_ainsn
->important_p
= FALSE
;
6223 curr_ainsn
->next_ainsn
= NULL
;
6224 if (prev_ainsn
== NULL
)
6225 first_ainsn
= curr_ainsn
;
6227 prev_ainsn
->next_ainsn
= curr_ainsn
;
6228 prev_ainsn
= curr_ainsn
;
6234 /* The function assigns automata to units according to constructions
6235 `define_automaton' in the description. */
6237 units_to_automata_distr ()
6242 for (i
= 0; i
< description
->decls_num
; i
++)
6244 decl
= description
->decls
[i
];
6245 if (decl
->mode
== dm_unit
)
6247 if (decl
->decl
.unit
.automaton_decl
== NULL
6248 || (decl
->decl
.unit
.automaton_decl
->corresponding_automaton
6250 /* Distribute to the first automaton. */
6251 decl
->decl
.unit
.corresponding_automaton_num
= 0;
6253 decl
->decl
.unit
.corresponding_automaton_num
6254 = (decl
->decl
.unit
.automaton_decl
6255 ->corresponding_automaton
->automaton_order_num
);
6260 /* The function creates DFA(s) for fast pipeline hazards recognition
6261 after checking and simplifying IR of the description. */
6265 automaton_t curr_automaton
;
6266 automaton_t prev_automaton
;
6268 int curr_automaton_num
;
6271 if (automata_num
!= 0)
6273 units_to_automata_heuristic_distr ();
6274 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6275 curr_automaton_num
< automata_num
;
6276 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6278 curr_automaton
= create_node (sizeof (struct automaton
));
6279 curr_automaton
->ainsn_list
= create_ainsns ();
6280 curr_automaton
->corresponding_automaton_decl
= NULL
;
6281 curr_automaton
->next_automaton
= NULL
;
6282 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6283 if (prev_automaton
== NULL
)
6284 description
->first_automaton
= curr_automaton
;
6286 prev_automaton
->next_automaton
= curr_automaton
;
6291 curr_automaton_num
= 0;
6292 prev_automaton
= NULL
;
6293 for (i
= 0; i
< description
->decls_num
; i
++)
6295 decl
= description
->decls
[i
];
6296 if (decl
->mode
== dm_automaton
6297 && decl
->decl
.automaton
.automaton_is_used
)
6299 curr_automaton
= create_node (sizeof (struct automaton
));
6300 curr_automaton
->ainsn_list
= create_ainsns ();
6301 curr_automaton
->corresponding_automaton_decl
6302 = &decl
->decl
.automaton
;
6303 curr_automaton
->next_automaton
= NULL
;
6304 decl
->decl
.automaton
.corresponding_automaton
= curr_automaton
;
6305 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6306 if (prev_automaton
== NULL
)
6307 description
->first_automaton
= curr_automaton
;
6309 prev_automaton
->next_automaton
= curr_automaton
;
6310 curr_automaton_num
++;
6311 prev_automaton
= curr_automaton
;
6314 if (curr_automaton_num
== 0)
6316 curr_automaton
= create_node (sizeof (struct automaton
));
6317 curr_automaton
->ainsn_list
= create_ainsns ();
6318 curr_automaton
->corresponding_automaton_decl
= NULL
;
6319 curr_automaton
->next_automaton
= NULL
;
6320 description
->first_automaton
= curr_automaton
;
6322 units_to_automata_distr ();
6324 NDFA_time
= create_ticker ();
6325 ticker_off (&NDFA_time
);
6326 NDFA_to_DFA_time
= create_ticker ();
6327 ticker_off (&NDFA_to_DFA_time
);
6328 minimize_time
= create_ticker ();
6329 ticker_off (&minimize_time
);
6330 equiv_time
= create_ticker ();
6331 ticker_off (&equiv_time
);
6332 for (curr_automaton
= description
->first_automaton
;
6333 curr_automaton
!= NULL
;
6334 curr_automaton
= curr_automaton
->next_automaton
)
6336 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6337 fprintf (stderr
, "Create anonymous automaton ...");
6339 fprintf (stderr
, "Create automaton `%s'...",
6340 curr_automaton
->corresponding_automaton_decl
->name
);
6341 create_alt_states (curr_automaton
);
6342 form_ainsn_with_same_reservs (curr_automaton
);
6343 build_automaton (curr_automaton
);
6344 enumerate_states (curr_automaton
);
6345 ticker_on (&equiv_time
);
6346 set_insn_equiv_classes (curr_automaton
);
6347 ticker_off (&equiv_time
);
6348 fprintf (stderr
, "done\n");
6354 /* This page contains code for forming string representation of
6355 regexp. The representation is formed on IR obstack. So you should
6356 not work with IR obstack between regexp_representation and
6357 finish_regexp_representation calls. */
6359 /* This recursive function forms string representation of regexp
6360 (without tailing '\0'). */
6362 form_regexp (regexp
)
6367 if (regexp
->mode
== rm_unit
|| regexp
->mode
== rm_reserv
)
6369 const char *name
= (regexp
->mode
== rm_unit
6370 ? regexp
->regexp
.unit
.name
6371 : regexp
->regexp
.reserv
.name
);
6373 obstack_grow (&irp
, name
, strlen (name
));
6375 else if (regexp
->mode
== rm_sequence
)
6376 for (i
= 0; i
< regexp
->regexp
.sequence
.regexps_num
; i
++)
6379 obstack_1grow (&irp
, ',');
6380 form_regexp (regexp
->regexp
.sequence
.regexps
[i
]);
6382 else if (regexp
->mode
== rm_allof
)
6384 obstack_1grow (&irp
, '(');
6385 for (i
= 0; i
< regexp
->regexp
.allof
.regexps_num
; i
++)
6388 obstack_1grow (&irp
, '+');
6389 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_sequence
6390 || regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
6391 obstack_1grow (&irp
, '(');
6392 form_regexp (regexp
->regexp
.allof
.regexps
[i
]);
6393 if (regexp
->regexp
.allof
.regexps
[i
]->mode
== rm_sequence
6394 || regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_oneof
)
6395 obstack_1grow (&irp
, ')');
6397 obstack_1grow (&irp
, ')');
6399 else if (regexp
->mode
== rm_oneof
)
6400 for (i
= 0; i
< regexp
->regexp
.oneof
.regexps_num
; i
++)
6403 obstack_1grow (&irp
, '|');
6404 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_sequence
)
6405 obstack_1grow (&irp
, '(');
6406 form_regexp (regexp
->regexp
.oneof
.regexps
[i
]);
6407 if (regexp
->regexp
.oneof
.regexps
[i
]->mode
== rm_sequence
)
6408 obstack_1grow (&irp
, ')');
6410 else if (regexp
->mode
== rm_repeat
)
6414 if (regexp
->regexp
.repeat
.regexp
->mode
== rm_sequence
6415 || regexp
->regexp
.repeat
.regexp
->mode
== rm_allof
6416 || regexp
->regexp
.repeat
.regexp
->mode
== rm_oneof
)
6417 obstack_1grow (&irp
, '(');
6418 form_regexp (regexp
->regexp
.repeat
.regexp
);
6419 if (regexp
->regexp
.repeat
.regexp
->mode
== rm_sequence
6420 || regexp
->regexp
.repeat
.regexp
->mode
== rm_allof
6421 || regexp
->regexp
.repeat
.regexp
->mode
== rm_oneof
)
6422 obstack_1grow (&irp
, ')');
6423 sprintf (digits
, "*%d", regexp
->regexp
.repeat
.repeat_num
);
6424 obstack_grow (&irp
, digits
, strlen (digits
));
6426 else if (regexp
->mode
== rm_nothing
)
6427 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
6432 /* The function returns string representation of REGEXP on IR
6435 regexp_representation (regexp
)
6438 form_regexp (regexp
);
6439 obstack_1grow (&irp
, '\0');
6440 return obstack_base (&irp
);
6443 /* The function frees memory allocated for last formed string
6444 representation of regexp. */
6446 finish_regexp_representation ()
6448 int length
= obstack_object_size (&irp
);
6450 obstack_blank_fast (&irp
, -length
);
6455 /* This page contains code for output PHR (pipeline hazards recognizer). */
6457 /* The function outputs minimal C type which is sufficient for
6458 representation numbers in range min_range_value and
6459 max_range_value. Because host machine and build machine may be
6460 different, we use here minimal values required by ANSI C standard
6461 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6465 output_range_type (f
, min_range_value
, max_range_value
)
6467 long int min_range_value
;
6468 long int max_range_value
;
6470 if (min_range_value
>= 0 && max_range_value
<= 255)
6471 fprintf (f
, "unsigned char");
6472 else if (min_range_value
>= -127 && max_range_value
<= 127)
6473 fprintf (f
, "signed char");
6474 else if (min_range_value
>= 0 && max_range_value
<= 65535)
6475 fprintf (f
, "unsigned short");
6476 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
6477 fprintf (f
, "short");
6482 /* The following macro value is used as value of member
6483 `longest_path_length' of state when we are processing path and the
6484 state on the path. */
6486 #define ON_THE_PATH -2
6488 /* The following recursive function searches for the length of the
6489 longest path starting from STATE which does not contain cycles and
6490 `cycle advance' arcs. */
6493 longest_path_length (state
)
6499 if (state
->longest_path_length
== ON_THE_PATH
)
6500 /* We don't expect the path cycle here. Our graph may contain
6501 only cycles with one state on the path not containing `cycle
6502 advance' arcs -- see comment below. */
6504 else if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
6505 /* We alreday visited the state. */
6506 return state
->longest_path_length
;
6509 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6510 /* Ignore cycles containing one state and `cycle advance' arcs. */
6511 if (arc
->to_state
!= state
6512 && (arc
->insn
->insn_reserv_decl
6513 != &advance_cycle_insn_decl
->decl
.insn_reserv
))
6515 length
= longest_path_length (arc
->to_state
);
6516 if (length
> result
)
6519 state
->longest_path_length
= result
+ 1;
6523 /* The following variable value is value of the corresponding global
6524 variable in the automaton based pipeline interface. */
6526 static int max_dfa_issue_rate
;
6528 /* The following function processes the longest path length staring
6529 from STATE to find MAX_DFA_ISSUE_RATE. */
6532 process_state_longest_path_length (state
)
6537 value
= longest_path_length (state
);
6538 if (value
> max_dfa_issue_rate
)
6539 max_dfa_issue_rate
= value
;
6542 /* The following nacro value is name of the corresponding global
6543 variable in the automaton based pipeline interface. */
6545 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6547 /* The following function calculates value of the the corresponding
6548 global variable and outputs its declaration. */
6551 output_dfa_max_issue_rate ()
6553 automaton_t automaton
;
6555 if (UNDEFINED_LONGEST_PATH_LENGTH
== ON_THE_PATH
|| ON_THE_PATH
>= 0)
6557 max_dfa_issue_rate
= 0;
6558 for (automaton
= description
->first_automaton
;
6560 automaton
= automaton
->next_automaton
)
6561 pass_states (automaton
, process_state_longest_path_length
);
6562 fprintf (output_file
, "\nint %s = %d;\n",
6563 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
6566 /* The function outputs all initialization values of VECT with length
6569 output_vect (vect
, vect_length
)
6576 if (vect_length
== 0)
6577 fprintf (output_file
,
6578 "0 /* This is dummy el because the vect is empty */");
6583 fprintf (output_file
, "%5ld", (long) *vect
);
6585 if (els_on_line
== 10)
6588 fprintf (output_file
, ",\n");
6590 else if (vect_length
!= 0)
6591 fprintf (output_file
, ", ");
6595 while (vect_length
!= 0);
6599 /* The following is name of the structure which represents DFA(s) for
6601 #define CHIP_NAME "DFA_chip"
6603 /* The following is name of member which represents state of a DFA for
6606 output_chip_member_name (f
, automaton
)
6608 automaton_t automaton
;
6610 if (automaton
->corresponding_automaton_decl
== NULL
)
6611 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
6613 fprintf (f
, "%s_automaton_state",
6614 automaton
->corresponding_automaton_decl
->name
);
6617 /* The following is name of temporary variable which stores state of a
6620 output_temp_chip_member_name (f
, automaton
)
6622 automaton_t automaton
;
6625 output_chip_member_name (f
, automaton
);
6628 /* This is name of macro value which is code of pseudo_insn
6629 representing advancing cpu cycle. Its value is used as internal
6630 code unknown insn. */
6631 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6633 /* Output name of translate vector for given automaton. */
6635 output_translate_vect_name (f
, automaton
)
6637 automaton_t automaton
;
6639 if (automaton
->corresponding_automaton_decl
== NULL
)
6640 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
6642 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
6645 /* Output name for simple transition table representation. */
6647 output_trans_full_vect_name (f
, automaton
)
6649 automaton_t automaton
;
6651 if (automaton
->corresponding_automaton_decl
== NULL
)
6652 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6654 fprintf (f
, "%s_transitions",
6655 automaton
->corresponding_automaton_decl
->name
);
6658 /* Output name of comb vector of the transition table for given
6661 output_trans_comb_vect_name (f
, automaton
)
6663 automaton_t automaton
;
6665 if (automaton
->corresponding_automaton_decl
== NULL
)
6666 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6668 fprintf (f
, "%s_transitions",
6669 automaton
->corresponding_automaton_decl
->name
);
6672 /* Output name of check vector of the transition table for given
6675 output_trans_check_vect_name (f
, automaton
)
6677 automaton_t automaton
;
6679 if (automaton
->corresponding_automaton_decl
== NULL
)
6680 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
6682 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
6685 /* Output name of base vector of the transition table for given
6688 output_trans_base_vect_name (f
, automaton
)
6690 automaton_t automaton
;
6692 if (automaton
->corresponding_automaton_decl
== NULL
)
6693 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
6695 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
6698 /* Output name for simple alternatives number representation. */
6700 output_state_alts_full_vect_name (f
, automaton
)
6702 automaton_t automaton
;
6704 if (automaton
->corresponding_automaton_decl
== NULL
)
6705 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
6707 fprintf (f
, "%s_state_alts",
6708 automaton
->corresponding_automaton_decl
->name
);
6711 /* Output name of comb vector of the alternatives number table for given
6714 output_state_alts_comb_vect_name (f
, automaton
)
6716 automaton_t automaton
;
6718 if (automaton
->corresponding_automaton_decl
== NULL
)
6719 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
6721 fprintf (f
, "%s_state_alts",
6722 automaton
->corresponding_automaton_decl
->name
);
6725 /* Output name of check vector of the alternatives number table for given
6728 output_state_alts_check_vect_name (f
, automaton
)
6730 automaton_t automaton
;
6732 if (automaton
->corresponding_automaton_decl
== NULL
)
6733 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
6735 fprintf (f
, "%s_check_state_alts",
6736 automaton
->corresponding_automaton_decl
->name
);
6739 /* Output name of base vector of the alternatives number table for given
6742 output_state_alts_base_vect_name (f
, automaton
)
6744 automaton_t automaton
;
6746 if (automaton
->corresponding_automaton_decl
== NULL
)
6747 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
6749 fprintf (f
, "%s_base_state_alts",
6750 automaton
->corresponding_automaton_decl
->name
);
6753 /* Output name of simple min issue delay table representation. */
6755 output_min_issue_delay_vect_name (f
, automaton
)
6757 automaton_t automaton
;
6759 if (automaton
->corresponding_automaton_decl
== NULL
)
6760 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
6762 fprintf (f
, "%s_min_issue_delay",
6763 automaton
->corresponding_automaton_decl
->name
);
6766 /* Output name of deadlock vector for given automaton. */
6768 output_dead_lock_vect_name (f
, automaton
)
6770 automaton_t automaton
;
6772 if (automaton
->corresponding_automaton_decl
== NULL
)
6773 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
6775 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
6778 /* Output name of reserved units table for AUTOMATON into file F. */
6780 output_reserved_units_table_name (f
, automaton
)
6782 automaton_t automaton
;
6784 if (automaton
->corresponding_automaton_decl
== NULL
)
6785 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
6787 fprintf (f
, "%s_reserved_units",
6788 automaton
->corresponding_automaton_decl
->name
);
6791 /* Name of the PHR interface macro. */
6792 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6794 /* Name of the PHR interface macro. */
6795 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6797 /* Names of an internal functions: */
6798 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6800 /* This is external type of DFA(s) state. */
6801 #define STATE_TYPE_NAME "state_t"
6803 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6805 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6807 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6809 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6811 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6813 /* Name of cache of insn dfa codes. */
6814 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6816 /* Name of length of cache of insn dfa codes. */
6817 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6819 /* Names of the PHR interface functions: */
6820 #define SIZE_FUNC_NAME "state_size"
6822 #define TRANSITION_FUNC_NAME "state_transition"
6824 #define STATE_ALTS_FUNC_NAME "state_alts"
6826 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6828 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6830 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6832 #define RESET_FUNC_NAME "state_reset"
6834 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6836 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6838 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6840 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6842 #define DFA_START_FUNC_NAME "dfa_start"
6844 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6846 /* Names of parameters of the PHR interface functions. */
6847 #define STATE_NAME "state"
6849 #define INSN_PARAMETER_NAME "insn"
6851 #define INSN2_PARAMETER_NAME "insn2"
6853 #define CHIP_PARAMETER_NAME "chip"
6855 #define FILE_PARAMETER_NAME "f"
6857 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6859 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6861 /* Names of the variables whose values are internal insn code of rtx
6863 #define INTERNAL_INSN_CODE_NAME "insn_code"
6865 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6867 /* Names of temporary variables in some functions. */
6868 #define TEMPORARY_VARIABLE_NAME "temp"
6870 #define I_VARIABLE_NAME "i"
6872 /* Name of result variable in some functions. */
6873 #define RESULT_VARIABLE_NAME "res"
6875 /* Name of function (attribute) to translate insn into number of insn
6876 alternatives reservation. */
6877 #define INSN_ALTS_FUNC_NAME "insn_alts"
6879 /* Name of function (attribute) to translate insn into internal insn
6881 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6883 /* Name of function (attribute) to translate insn into internal insn
6884 code with caching. */
6885 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6887 /* Name of function (attribute) to translate insn into internal insn
6889 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6891 /* Name of function (attribute) to translate insn into internal insn
6893 #define BYPASS_P_FUNC_NAME "bypass_p"
6895 /* Output C type which is used for representation of codes of states
6898 output_state_member_type (f
, automaton
)
6900 automaton_t automaton
;
6902 output_range_type (f
, 0, automaton
->achieved_states_num
);
6905 /* Output definition of the structure representing current DFA(s)
6908 output_chip_definitions ()
6910 automaton_t automaton
;
6912 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
6913 for (automaton
= description
->first_automaton
;
6915 automaton
= automaton
->next_automaton
)
6917 fprintf (output_file
, " ");
6918 output_state_member_type (output_file
, automaton
);
6919 fprintf (output_file
, " ");
6920 output_chip_member_name (output_file
, automaton
);
6921 fprintf (output_file
, ";\n");
6923 fprintf (output_file
, "};\n\n");
6925 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
6930 /* The function outputs translate vector of internal insn code into
6931 insn equivalence class number. The equivalence class number is
6932 used to access to table and vectors reprewsenting DFA(s). */
6934 output_translate_vect (automaton
)
6935 automaton_t automaton
;
6939 vla_hwint_t translate_vect
;
6941 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
6942 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
6943 for (insn_value
= 0; insn_value
<= description
->insns_num
; insn_value
++)
6944 /* Undefined value */
6945 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
6946 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6947 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
6948 = ainsn
->insn_equiv_class_num
;
6949 fprintf (output_file
,
6950 "/* Vector translating external insn codes to internal ones.*/\n");
6951 fprintf (output_file
, "static const ");
6952 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
6953 fprintf (output_file
, " ");
6954 output_translate_vect_name (output_file
, automaton
);
6955 fprintf (output_file
, "[] = {\n");
6956 output_vect (VLA_HWINT_BEGIN (translate_vect
),
6957 VLA_HWINT_LENGTH (translate_vect
));
6958 fprintf (output_file
, "};\n\n");
6959 VLA_HWINT_DELETE (translate_vect
);
6962 /* The value in a table state x ainsn -> something which represents
6964 static int undefined_vect_el_value
;
6966 /* The following function returns nonzero value if the best
6967 representation of the table is comb vector. */
6970 state_ainsn_table_t tab
;
6972 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
6973 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
6976 /* The following function creates new table for AUTOMATON. */
6977 static state_ainsn_table_t
6978 create_state_ainsn_table (automaton
)
6979 automaton_t automaton
;
6981 state_ainsn_table_t tab
;
6982 int full_vect_length
;
6985 tab
= create_node (sizeof (struct state_ainsn_table
));
6986 tab
->automaton
= automaton
;
6987 VLA_HWINT_CREATE (tab
->comb_vect
, 10000, "comb vector");
6988 VLA_HWINT_CREATE (tab
->check_vect
, 10000, "check vector");
6989 VLA_HWINT_CREATE (tab
->base_vect
, 1000, "base vector");
6990 VLA_HWINT_EXPAND (tab
->base_vect
, automaton
->achieved_states_num
);
6991 VLA_HWINT_CREATE (tab
->full_vect
, 10000, "full vector");
6992 full_vect_length
= (automaton
->insn_equiv_classes_num
6993 * automaton
->achieved_states_num
);
6994 VLA_HWINT_EXPAND (tab
->full_vect
, full_vect_length
);
6995 for (i
= 0; i
< full_vect_length
; i
++)
6996 VLA_HWINT (tab
->full_vect
, i
) = undefined_vect_el_value
;
6997 tab
->min_base_vect_el_value
= 0;
6998 tab
->max_base_vect_el_value
= 0;
6999 tab
->min_comb_vect_el_value
= 0;
7000 tab
->max_comb_vect_el_value
= 0;
7004 /* The following function outputs the best C representation of the
7005 table TAB of given TABLE_NAME. */
7007 output_state_ainsn_table (tab
, table_name
, output_full_vect_name_func
,
7008 output_comb_vect_name_func
,
7009 output_check_vect_name_func
,
7010 output_base_vect_name_func
)
7011 state_ainsn_table_t tab
;
7013 void (*output_full_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7014 void (*output_comb_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7015 void (*output_check_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7016 void (*output_base_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7018 if (!comb_vect_p (tab
))
7020 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7021 fprintf (output_file
, "static const ");
7022 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7023 tab
->max_comb_vect_el_value
);
7024 fprintf (output_file
, " ");
7025 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7026 fprintf (output_file
, "[] = {\n");
7027 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7028 VLA_HWINT_LENGTH (tab
->full_vect
));
7029 fprintf (output_file
, "};\n\n");
7033 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7034 fprintf (output_file
, "static const ");
7035 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7036 tab
->max_comb_vect_el_value
);
7037 fprintf (output_file
, " ");
7038 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7039 fprintf (output_file
, "[] = {\n");
7040 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7041 VLA_HWINT_LENGTH (tab
->comb_vect
));
7042 fprintf (output_file
, "};\n\n");
7043 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7044 fprintf (output_file
, "static const ");
7045 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7046 fprintf (output_file
, " ");
7047 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7048 fprintf (output_file
, "[] = {\n");
7049 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7050 VLA_HWINT_LENGTH (tab
->check_vect
));
7051 fprintf (output_file
, "};\n\n");
7052 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7053 fprintf (output_file
, "static const ");
7054 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7055 tab
->max_base_vect_el_value
);
7056 fprintf (output_file
, " ");
7057 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7058 fprintf (output_file
, "[] = {\n");
7059 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7060 VLA_HWINT_LENGTH (tab
->base_vect
));
7061 fprintf (output_file
, "};\n\n");
7065 /* The following function adds vector with length VECT_LENGTH and
7066 elements pointed by VECT to table TAB as its line with number
7069 add_vect (tab
, vect_num
, vect
, vect_length
)
7070 state_ainsn_table_t tab
;
7075 int real_vect_length
;
7076 vect_el_t
*comb_vect_start
;
7077 vect_el_t
*check_vect_start
;
7078 int comb_vect_index
;
7079 int comb_vect_els_num
;
7081 int first_unempty_vect_index
;
7082 int additional_els_num
;
7087 if (vect_length
== 0)
7089 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7090 if (vect
[vect_length
- 1] == undefined_vect_el_value
)
7092 /* Form full vector in the table: */
7093 for (i
= 0; i
< vect_length
; i
++)
7094 VLA_HWINT (tab
->full_vect
,
7095 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
7097 /* Form comb vector in the table: */
7098 if (VLA_HWINT_LENGTH (tab
->comb_vect
) != VLA_HWINT_LENGTH (tab
->check_vect
))
7100 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7101 comb_vect_els_num
= VLA_HWINT_LENGTH (tab
->comb_vect
);
7102 for (first_unempty_vect_index
= 0;
7103 first_unempty_vect_index
< vect_length
;
7104 first_unempty_vect_index
++)
7105 if (vect
[first_unempty_vect_index
] != undefined_vect_el_value
)
7107 /* Search for the place in comb vect for the inserted vect. */
7108 for (comb_vect_index
= 0;
7109 comb_vect_index
< comb_vect_els_num
;
7112 for (vect_index
= first_unempty_vect_index
;
7113 vect_index
< vect_length
7114 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7116 if (vect
[vect_index
] != undefined_vect_el_value
7117 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7118 != undefined_vect_el_value
))
7120 if (vect_index
>= vect_length
7121 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7124 /* Slot was found. */
7125 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7126 if (additional_els_num
< 0)
7127 additional_els_num
= 0;
7128 /* Expand comb and check vectors. */
7129 vect_el
= undefined_vect_el_value
;
7130 no_state_value
= tab
->automaton
->achieved_states_num
;
7131 while (additional_els_num
> 0)
7133 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7134 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7135 additional_els_num
--;
7137 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7138 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7139 if (VLA_HWINT_LENGTH (tab
->comb_vect
)
7140 < (size_t) (comb_vect_index
+ real_vect_length
))
7142 /* Fill comb and check vectors. */
7143 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7144 if (vect
[vect_index
] != undefined_vect_el_value
)
7146 if (comb_vect_start
[comb_vect_index
+ vect_index
]
7147 != undefined_vect_el_value
)
7149 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7150 if (vect
[vect_index
] < 0)
7152 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7153 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7154 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7155 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7156 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7158 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7159 tab
->max_base_vect_el_value
= comb_vect_index
;
7160 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7161 tab
->min_base_vect_el_value
= comb_vect_index
;
7162 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7165 /* Return number of out arcs of STATE. */
7167 out_state_arcs_num (state
)
7174 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7176 if (arc
->insn
== NULL
)
7178 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7184 /* Compare number of possible transitions from the states. */
7186 compare_transition_els_num (state_ptr_1
, state_ptr_2
)
7187 const void *state_ptr_1
;
7188 const void *state_ptr_2
;
7190 int transition_els_num_1
;
7191 int transition_els_num_2
;
7193 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7194 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7195 if (transition_els_num_1
< transition_els_num_2
)
7197 else if (transition_els_num_1
== transition_els_num_2
)
7203 /* The function adds element EL_VALUE to vector VECT for a table state
7206 add_vect_el (vect
, ainsn
, el_value
)
7211 int equiv_class_num
;
7216 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7217 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7218 vect_index
<= equiv_class_num
;
7220 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7221 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7224 /* This is for forming vector of states of an automaton. */
7225 static vla_ptr_t output_states_vect
;
7227 /* The function is called by function pass_states. The function adds
7228 STATE to `output_states_vect'. */
7230 add_states_vect_el (state
)
7233 VLA_PTR_ADD (output_states_vect
, state
);
7236 /* Form and output vectors (comb, check, base or full vector)
7237 representing transition table of AUTOMATON. */
7239 output_trans_table (automaton
)
7240 automaton_t automaton
;
7244 vla_hwint_t transition_vect
;
7246 undefined_vect_el_value
= automaton
->achieved_states_num
;
7247 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7248 /* Create vect of pointers to states ordered by num of transitions
7249 from the state (state with the maximum num is the first). */
7250 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7251 pass_states (automaton
, add_states_vect_el
);
7252 qsort (VLA_PTR_BEGIN (output_states_vect
),
7253 VLA_PTR_LENGTH (output_states_vect
),
7254 sizeof (state_t
), compare_transition_els_num
);
7255 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7256 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7257 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7260 VLA_HWINT_NULLIFY (transition_vect
);
7261 for (arc
= first_out_arc (*state_ptr
);
7263 arc
= next_out_arc (arc
))
7265 if (arc
->insn
== NULL
)
7267 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7268 add_vect_el (&transition_vect
, arc
->insn
,
7269 arc
->to_state
->order_state_num
);
7271 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7272 VLA_HWINT_BEGIN (transition_vect
),
7273 VLA_HWINT_LENGTH (transition_vect
));
7275 output_state_ainsn_table
7276 (automaton
->trans_table
, (char *) "state transitions",
7277 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7278 output_trans_check_vect_name
, output_trans_base_vect_name
);
7279 VLA_PTR_DELETE (output_states_vect
);
7280 VLA_HWINT_DELETE (transition_vect
);
7283 /* Form and output vectors (comb, check, base or simple vect)
7284 representing alts number table of AUTOMATON. The table is state x
7285 ainsn -> number of possible alternative reservations by the
7288 output_state_alts_table (automaton
)
7289 automaton_t automaton
;
7293 vla_hwint_t state_alts_vect
;
7295 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7296 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7297 /* Create vect of pointers to states ordered by num of transitions
7298 from the state (state with the maximum num is the first). */
7299 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7300 pass_states (automaton
, add_states_vect_el
);
7301 qsort (VLA_PTR_BEGIN (output_states_vect
),
7302 VLA_PTR_LENGTH (output_states_vect
),
7303 sizeof (state_t
), compare_transition_els_num
);
7304 /* Create base, comb, and check vectors. */
7305 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7306 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7307 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7310 VLA_HWINT_NULLIFY (state_alts_vect
);
7311 for (arc
= first_out_arc (*state_ptr
);
7313 arc
= next_out_arc (arc
))
7315 if (arc
->insn
== NULL
)
7317 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7318 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7320 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7321 VLA_HWINT_BEGIN (state_alts_vect
),
7322 VLA_HWINT_LENGTH (state_alts_vect
));
7324 output_state_ainsn_table
7325 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7326 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7327 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7328 VLA_PTR_DELETE (output_states_vect
);
7329 VLA_HWINT_DELETE (state_alts_vect
);
7332 /* The current number of passing states to find minimal issue delay
7333 value for an ainsn and state. */
7334 static int curr_state_pass_num
;
7337 /* This recursive function passes states to find minimal issue delay
7338 value for AINSN. The state being visited is STATE. The function
7339 returns minimal issue delay value for AINSN in STATE or -1 if we
7340 enter into a loop. */
7342 min_issue_delay_pass_states (state
, ainsn
)
7347 int min_insn_issue_delay
, insn_issue_delay
;
7349 if (state
->state_pass_num
== curr_state_pass_num
7350 || state
->min_insn_issue_delay
!= -1)
7351 /* We've entered into a loop or already have the correct value for
7352 given state and ainsn. */
7353 return state
->min_insn_issue_delay
;
7354 state
->state_pass_num
= curr_state_pass_num
;
7355 min_insn_issue_delay
= -1;
7356 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7357 if (arc
->insn
== ainsn
)
7359 min_insn_issue_delay
= 0;
7364 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7365 if (insn_issue_delay
!= -1)
7367 if (arc
->insn
->insn_reserv_decl
7368 == &advance_cycle_insn_decl
->decl
.insn_reserv
)
7370 if (min_insn_issue_delay
== -1
7371 || min_insn_issue_delay
> insn_issue_delay
)
7373 min_insn_issue_delay
= insn_issue_delay
;
7374 if (insn_issue_delay
== 0)
7379 return min_insn_issue_delay
;
7382 /* The function searches minimal issue delay value for AINSN in STATE.
7383 The function can return negative value if we can not issue AINSN. We
7384 will report about it later. */
7386 min_issue_delay (state
, ainsn
)
7390 curr_state_pass_num
++;
7391 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7392 return state
->min_insn_issue_delay
;
7395 /* The function initiates code for finding minimal issue delay values.
7396 It should be called only once. */
7398 initiate_min_issue_delay_pass_states ()
7400 curr_state_pass_num
= 0;
7403 /* Form and output vectors representing minimal issue delay table of
7404 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7407 output_min_issue_delay_table (automaton
)
7408 automaton_t automaton
;
7410 vla_hwint_t min_issue_delay_vect
;
7411 vla_hwint_t compressed_min_issue_delay_vect
;
7412 vect_el_t min_delay
;
7417 /* Create vect of pointers to states ordered by num of transitions
7418 from the state (state with the maximum num is the first). */
7419 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7420 pass_states (automaton
, add_states_vect_el
);
7421 VLA_HWINT_CREATE (min_issue_delay_vect
, 1500, "min issue delay vector");
7422 VLA_HWINT_EXPAND (min_issue_delay_vect
,
7423 VLA_HWINT_LENGTH (output_states_vect
)
7424 * automaton
->insn_equiv_classes_num
);
7426 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
7427 * automaton
->insn_equiv_classes_num
);
7429 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
7430 automaton
->max_min_delay
= 0;
7431 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7432 if (ainsn
->first_ainsn_with_given_equialence_num
)
7434 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7435 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7437 (*state_ptr
)->min_insn_issue_delay
= -1;
7438 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7439 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7442 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
7443 if (automaton
->max_min_delay
< min_delay
)
7444 automaton
->max_min_delay
= min_delay
;
7445 VLA_HWINT (min_issue_delay_vect
,
7446 (*state_ptr
)->order_state_num
7447 * automaton
->insn_equiv_classes_num
7448 + ainsn
->insn_equiv_class_num
) = min_delay
;
7451 fprintf (output_file
, "/* Vector of min issue delay of insns.*/\n");
7452 fprintf (output_file
, "static const ");
7453 output_range_type (output_file
, 0, automaton
->max_min_delay
);
7454 fprintf (output_file
, " ");
7455 output_min_issue_delay_vect_name (output_file
, automaton
);
7456 fprintf (output_file
, "[] = {\n");
7457 /* Compress the vector */
7458 if (automaton
->max_min_delay
< 2)
7459 automaton
->min_issue_delay_table_compression_factor
= 8;
7460 else if (automaton
->max_min_delay
< 4)
7461 automaton
->min_issue_delay_table_compression_factor
= 4;
7462 else if (automaton
->max_min_delay
< 16)
7463 automaton
->min_issue_delay_table_compression_factor
= 2;
7465 automaton
->min_issue_delay_table_compression_factor
= 1;
7466 VLA_HWINT_CREATE (compressed_min_issue_delay_vect
, 1500,
7467 "compressed min issue delay vector");
7468 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect
,
7469 (VLA_HWINT_LENGTH (min_issue_delay_vect
)
7470 + automaton
->min_issue_delay_table_compression_factor
7472 / automaton
->min_issue_delay_table_compression_factor
);
7474 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
7476 VLA_HWINT (compressed_min_issue_delay_vect
, i
) = 0;
7477 for (i
= 0; i
< (int) VLA_HWINT_LENGTH (min_issue_delay_vect
); i
++)
7478 VLA_HWINT (compressed_min_issue_delay_vect
,
7479 i
/ automaton
->min_issue_delay_table_compression_factor
)
7480 |= (VLA_HWINT (min_issue_delay_vect
, i
)
7481 << (8 - (i
% automaton
->min_issue_delay_table_compression_factor
7483 * (8 / automaton
->min_issue_delay_table_compression_factor
)));
7484 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect
),
7485 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
));
7486 fprintf (output_file
, "};\n\n");
7487 VLA_PTR_DELETE (output_states_vect
);
7488 VLA_HWINT_DELETE (min_issue_delay_vect
);
7489 VLA_HWINT_DELETE (compressed_min_issue_delay_vect
);
7493 /* Number of states which contains transition only by advancing cpu
7495 static int locked_states_num
;
7498 /* Form and output vector representing the locked states of
7501 output_dead_lock_vect (automaton
)
7502 automaton_t automaton
;
7506 vla_hwint_t dead_lock_vect
;
7508 /* Create vect of pointers to states ordered by num of
7509 transitions from the state (state with the maximum num is the
7511 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7512 pass_states (automaton
, add_states_vect_el
);
7513 VLA_HWINT_CREATE (dead_lock_vect
, 1500, "is dead locked vector");
7514 VLA_HWINT_EXPAND (dead_lock_vect
, VLA_HWINT_LENGTH (output_states_vect
));
7515 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7516 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7519 arc
= first_out_arc (*state_ptr
);
7522 VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
)
7523 = (next_out_arc (arc
) == NULL
7524 && (arc
->insn
->insn_reserv_decl
7525 == &advance_cycle_insn_decl
->decl
.insn_reserv
) ? 1 : 0);
7527 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
7528 locked_states_num
++;
7531 fprintf (output_file
, "/* Vector for locked state flags. */\n");
7532 fprintf (output_file
, "static const ");
7533 output_range_type (output_file
, 0, 1);
7534 fprintf (output_file
, " ");
7535 output_dead_lock_vect_name (output_file
, automaton
);
7536 fprintf (output_file
, "[] = {\n");
7537 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
7538 VLA_HWINT_LENGTH (dead_lock_vect
));
7539 fprintf (output_file
, "};\n\n");
7540 VLA_HWINT_DELETE (dead_lock_vect
);
7541 VLA_PTR_DELETE (output_states_vect
);
7544 /* Form and output vector representing reserved units of the states of
7547 output_reserved_units_table (automaton
)
7548 automaton_t automaton
;
7550 state_t
*curr_state_ptr
;
7551 vla_hwint_t reserved_units_table
;
7552 size_t state_byte_size
;
7555 /* Create vect of pointers to states. */
7556 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7557 pass_states (automaton
, add_states_vect_el
);
7558 /* Create vector. */
7559 VLA_HWINT_CREATE (reserved_units_table
, 1500, "reserved units vector");
7560 state_byte_size
= (description
->query_units_num
+ 7) / 8;
7561 VLA_HWINT_EXPAND (reserved_units_table
,
7562 VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7564 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7566 VLA_HWINT (reserved_units_table
, i
) = 0;
7567 for (curr_state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7568 curr_state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7571 for (i
= 0; i
< description
->units_num
; i
++)
7572 if (units_array
[i
]->query_p
)
7574 if (test_unit_reserv ((*curr_state_ptr
)->reservs
, 0, i
))
7575 VLA_HWINT (reserved_units_table
,
7576 (*curr_state_ptr
)->order_state_num
* state_byte_size
7577 + units_array
[i
]->query_num
/ 8)
7578 += (1 << (units_array
[i
]->query_num
% 8));
7581 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
7582 fprintf (output_file
, "static const ");
7583 output_range_type (output_file
, 0, 255);
7584 fprintf (output_file
, " ");
7585 output_reserved_units_table_name (output_file
, automaton
);
7586 fprintf (output_file
, "[] = {\n");
7587 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
7588 VLA_HWINT_LENGTH (reserved_units_table
));
7589 fprintf (output_file
, "};\n\n");
7590 VLA_HWINT_DELETE (reserved_units_table
);
7591 VLA_PTR_DELETE (output_states_vect
);
7594 /* The function outputs all tables representing DFA(s) used for fast
7595 pipeline hazards recognition. */
7599 automaton_t automaton
;
7602 locked_states_num
= 0;
7604 initiate_min_issue_delay_pass_states ();
7605 for (automaton
= description
->first_automaton
;
7607 automaton
= automaton
->next_automaton
)
7609 output_translate_vect (automaton
);
7610 output_trans_table (automaton
);
7611 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
7612 output_state_alts_table (automaton
);
7613 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7614 AUTOMATON_STATE_ALTS_MACRO_NAME
);
7615 output_min_issue_delay_table (automaton
);
7616 output_dead_lock_vect (automaton
);
7617 if (no_minimization_flag
)
7619 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
7620 output_reserved_units_table (automaton
);
7621 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7622 CPU_UNITS_QUERY_MACRO_NAME
);
7625 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
7626 advance_cycle_insn_decl
->decl
.insn_reserv
.insn_num
);
7629 /* The function outputs definition and value of PHR interface variable
7630 `max_insn_queue_index' */
7632 output_max_insn_queue_index_def ()
7636 for (i
= 0; (1 << i
) <= description
->max_insn_reserv_cycles
; i
++)
7640 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
7644 /* The function outputs switch cases for insn reseravtions using
7645 function *output_automata_list_code. */
7647 output_insn_code_cases (output_automata_list_code
)
7648 void (*output_automata_list_code
) (automata_list_el_t
);
7650 decl_t decl
, decl_2
;
7653 for (i
= 0; i
< description
->decls_num
; i
++)
7655 decl
= description
->decls
[i
];
7656 if (decl
->mode
== dm_insn_reserv
)
7657 decl
->decl
.insn_reserv
.processed_p
= FALSE
;
7659 for (i
= 0; i
< description
->decls_num
; i
++)
7661 decl
= description
->decls
[i
];
7662 if (decl
->mode
== dm_insn_reserv
&& !decl
->decl
.insn_reserv
.processed_p
)
7664 for (j
= i
; j
< description
->decls_num
; j
++)
7666 decl_2
= description
->decls
[j
];
7667 if (decl_2
->mode
== dm_insn_reserv
7668 && (decl_2
->decl
.insn_reserv
.important_automata_list
7669 == decl
->decl
.insn_reserv
.important_automata_list
))
7671 decl_2
->decl
.insn_reserv
.processed_p
= TRUE
;
7672 fprintf (output_file
, " case %d: /* %s */\n",
7673 decl_2
->decl
.insn_reserv
.insn_num
,
7674 decl_2
->decl
.insn_reserv
.name
);
7677 (*output_automata_list_code
)
7678 (decl
->decl
.insn_reserv
.important_automata_list
);
7684 /* The function outputs a code for evaluation of a minimal delay of
7685 issue of insns which have reservations in given AUTOMATA_LIST. */
7687 output_automata_list_min_issue_delay_code (automata_list
)
7688 automata_list_el_t automata_list
;
7690 automata_list_el_t el
;
7691 automaton_t automaton
;
7693 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7695 automaton
= el
->automaton
;
7696 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7697 output_min_issue_delay_vect_name (output_file
, automaton
);
7698 fprintf (output_file
,
7699 (automaton
->min_issue_delay_table_compression_factor
!= 1
7701 output_translate_vect_name (output_file
, automaton
);
7702 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
7703 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7704 output_chip_member_name (output_file
, automaton
);
7705 fprintf (output_file
, " * %d", automaton
->insn_equiv_classes_num
);
7706 if (automaton
->min_issue_delay_table_compression_factor
== 1)
7707 fprintf (output_file
, "];\n");
7710 fprintf (output_file
, ") / %d];\n",
7711 automaton
->min_issue_delay_table_compression_factor
);
7712 fprintf (output_file
, " %s = (%s >> (8 - (",
7713 TEMPORARY_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7714 output_translate_vect_name (output_file
, automaton
);
7716 (output_file
, " [%s] %% %d + 1) * %d)) & %d;\n",
7717 INTERNAL_INSN_CODE_NAME
,
7718 automaton
->min_issue_delay_table_compression_factor
,
7719 8 / automaton
->min_issue_delay_table_compression_factor
,
7720 (1 << (8 / automaton
->min_issue_delay_table_compression_factor
))
7723 if (el
== automata_list
)
7724 fprintf (output_file
, " %s = %s;\n",
7725 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7728 fprintf (output_file
, " if (%s > %s)\n",
7729 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
7730 fprintf (output_file
, " %s = %s;\n",
7731 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
7734 fprintf (output_file
, " break;\n\n");
7737 /* Output function `internal_min_issue_delay'. */
7739 output_internal_min_issue_delay_func ()
7741 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
7742 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, CHIP_NAME
);
7743 fprintf (output_file
,
7744 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7745 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7746 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
7747 CHIP_PARAMETER_NAME
);
7748 fprintf (output_file
, "{\n int %s;\n int %s;\n",
7749 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
7750 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
7751 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
7752 fprintf (output_file
,
7753 "\n default:\n %s = -1;\n break;\n }\n",
7754 RESULT_VARIABLE_NAME
);
7755 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
7756 fprintf (output_file
, "}\n\n");
7759 /* The function outputs a code changing state after issue of insns
7760 which have reservations in given AUTOMATA_LIST. */
7762 output_automata_list_transition_code (automata_list
)
7763 automata_list_el_t automata_list
;
7765 automata_list_el_t el
, next_el
;
7767 fprintf (output_file
, " {\n");
7768 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
7769 for (el
= automata_list
;; el
= next_el
)
7771 next_el
= el
->next_automata_list_el
;
7772 if (next_el
== NULL
)
7774 fprintf (output_file
, " ");
7775 output_state_member_type (output_file
, el
->automaton
);
7776 fprintf (output_file
, " ");
7777 output_temp_chip_member_name (output_file
, el
->automaton
);
7778 fprintf (output_file
, ";\n");
7780 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7781 if (comb_vect_p (el
->automaton
->trans_table
))
7783 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7784 output_trans_base_vect_name (output_file
, el
->automaton
);
7785 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
7786 output_chip_member_name (output_file
, el
->automaton
);
7787 fprintf (output_file
, "] + ");
7788 output_translate_vect_name (output_file
, el
->automaton
);
7789 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
7790 fprintf (output_file
, " if (");
7791 output_trans_check_vect_name (output_file
, el
->automaton
);
7792 fprintf (output_file
, " [%s] != %s->",
7793 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
7794 output_chip_member_name (output_file
, el
->automaton
);
7795 fprintf (output_file
, ")\n");
7796 fprintf (output_file
, " return %s (%s, %s);\n",
7797 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7798 CHIP_PARAMETER_NAME
);
7799 fprintf (output_file
, " else\n");
7800 fprintf (output_file
, " ");
7801 if (el
->next_automata_list_el
!= NULL
)
7802 output_temp_chip_member_name (output_file
, el
->automaton
);
7805 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7806 output_chip_member_name (output_file
, el
->automaton
);
7808 fprintf (output_file
, " = ");
7809 output_trans_comb_vect_name (output_file
, el
->automaton
);
7810 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
7814 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7815 output_trans_full_vect_name (output_file
, el
->automaton
);
7816 fprintf (output_file
, " [");
7817 output_translate_vect_name (output_file
, el
->automaton
);
7818 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
7819 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7820 output_chip_member_name (output_file
, el
->automaton
);
7821 fprintf (output_file
, " * %d];\n",
7822 el
->automaton
->insn_equiv_classes_num
);
7823 fprintf (output_file
, " if (%s >= %d)\n",
7824 TEMPORARY_VARIABLE_NAME
, el
->automaton
->achieved_states_num
);
7825 fprintf (output_file
, " return %s (%s, %s);\n",
7826 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7827 CHIP_PARAMETER_NAME
);
7828 fprintf (output_file
, " else\n ");
7829 if (el
->next_automata_list_el
!= NULL
)
7830 output_temp_chip_member_name (output_file
, el
->automaton
);
7833 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
7834 output_chip_member_name (output_file
, el
->automaton
);
7836 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
7838 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
7839 for (el
= automata_list
;; el
= next_el
)
7841 next_el
= el
->next_automata_list_el
;
7842 if (next_el
== NULL
)
7844 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
7845 output_chip_member_name (output_file
, el
->automaton
);
7846 fprintf (output_file
, " = ");
7847 output_temp_chip_member_name (output_file
, el
->automaton
);
7848 fprintf (output_file
, ";\n");
7850 fprintf (output_file
, " return -1;\n");
7851 fprintf (output_file
, " }\n");
7854 /* Output function `internal_state_transition'. */
7856 output_internal_trans_func ()
7858 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
7859 INTERNAL_TRANSITION_FUNC_NAME
, CHIP_NAME
);
7860 fprintf (output_file
,
7861 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
7862 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
7863 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
,
7864 CHIP_NAME
, CHIP_PARAMETER_NAME
);
7865 fprintf (output_file
, "{\n int %s;\n", TEMPORARY_VARIABLE_NAME
);
7866 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
7867 output_insn_code_cases (output_automata_list_transition_code
);
7868 fprintf (output_file
, "\n default:\n return -1;\n }\n");
7869 fprintf (output_file
, "}\n\n");
7876 insn_code = dfa_insn_code (insn);
7877 if (insn_code > DFA__ADVANCE_CYCLE)
7881 insn_code = DFA__ADVANCE_CYCLE;
7883 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7884 code denotes CODE. */
7886 output_internal_insn_code_evaluation (insn_name
, insn_code_name
, code
)
7887 const char *insn_name
;
7888 const char *insn_code_name
;
7891 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
7892 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
7893 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
7894 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
7895 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
7896 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
7897 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
7901 /* The function outputs function `dfa_insn_code'. */
7903 output_dfa_insn_code_func ()
7905 fprintf (output_file
, "#ifdef __GNUC__\n__inline__\n#endif\n");
7906 fprintf (output_file
, "static int %s PARAMS ((rtx));\n",
7907 DFA_INSN_CODE_FUNC_NAME
);
7908 fprintf (output_file
, "static int\n%s (%s)\n\trtx %s;\n",
7909 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN_PARAMETER_NAME
);
7910 fprintf (output_file
, "{\n int %s;\n int %s;\n\n",
7911 INTERNAL_INSN_CODE_NAME
, TEMPORARY_VARIABLE_NAME
);
7912 fprintf (output_file
, " if (INSN_UID (%s) >= %s)\n {\n",
7913 INSN_PARAMETER_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
7914 fprintf (output_file
, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
7915 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
7916 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, INSN_PARAMETER_NAME
);
7917 fprintf (output_file
, " %s = xrealloc (%s, %s * sizeof (int));\n",
7918 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
7919 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
7920 fprintf (output_file
,
7921 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
7922 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
7923 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
7924 TEMPORARY_VARIABLE_NAME
);
7925 fprintf (output_file
, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
7926 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
7927 INSN_PARAMETER_NAME
);
7928 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
7929 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
7930 fprintf (output_file
, " %s [INSN_UID (%s)] = %s;\n",
7931 DFA_INSN_CODES_VARIABLE_NAME
, INSN_PARAMETER_NAME
,
7932 INTERNAL_INSN_CODE_NAME
);
7933 fprintf (output_file
, " }\n return %s;\n}\n\n",
7934 INTERNAL_INSN_CODE_NAME
);
7937 /* The function outputs PHR interface function `state_transition'. */
7939 output_trans_func ()
7941 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
7942 TRANSITION_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
7943 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
7944 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
7945 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
7946 INTERNAL_INSN_CODE_NAME
, -1);
7947 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
7948 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
7951 /* The function outputs a code for evaluation of alternative states
7952 number for insns which have reservations in given AUTOMATA_LIST. */
7954 output_automata_list_state_alts_code (automata_list
)
7955 automata_list_el_t automata_list
;
7957 automata_list_el_t el
;
7958 automaton_t automaton
;
7960 fprintf (output_file
, " {\n");
7961 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7962 if (comb_vect_p (el
->automaton
->state_alts_table
))
7964 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
7967 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
7969 automaton
= el
->automaton
;
7970 if (comb_vect_p (automaton
->state_alts_table
))
7972 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
7973 output_state_alts_base_vect_name (output_file
, automaton
);
7974 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
7975 output_chip_member_name (output_file
, automaton
);
7976 fprintf (output_file
, "] + ");
7977 output_translate_vect_name (output_file
, automaton
);
7978 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
7979 fprintf (output_file
, " if (");
7980 output_state_alts_check_vect_name (output_file
, automaton
);
7981 fprintf (output_file
, " [%s] != %s->",
7982 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
7983 output_chip_member_name (output_file
, automaton
);
7984 fprintf (output_file
, ")\n");
7985 fprintf (output_file
, " return 0;\n");
7986 fprintf (output_file
, " else\n");
7987 fprintf (output_file
,
7988 (el
== automata_list
7989 ? " %s = " : " %s += "),
7990 RESULT_VARIABLE_NAME
);
7991 output_state_alts_comb_vect_name (output_file
, automaton
);
7992 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
7996 fprintf (output_file
,
7997 (el
== automata_list
7998 ? "\n %s = " : " %s += "),
7999 RESULT_VARIABLE_NAME
);
8000 output_state_alts_full_vect_name (output_file
, automaton
);
8001 fprintf (output_file
, " [");
8002 output_translate_vect_name (output_file
, automaton
);
8003 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8004 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8005 output_chip_member_name (output_file
, automaton
);
8006 fprintf (output_file
, " * %d];\n",
8007 automaton
->insn_equiv_classes_num
);
8010 fprintf (output_file
, " break;\n }\n\n");
8013 /* Output function `internal_state_alts'. */
8015 output_internal_state_alts_func ()
8017 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8018 INTERNAL_STATE_ALTS_FUNC_NAME
, CHIP_NAME
);
8019 fprintf (output_file
,
8020 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8021 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8022 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8023 CHIP_PARAMETER_NAME
);
8024 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8025 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8026 output_insn_code_cases (output_automata_list_state_alts_code
);
8027 fprintf (output_file
,
8028 "\n default:\n %s = 0;\n break;\n }\n",
8029 RESULT_VARIABLE_NAME
);
8030 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8031 fprintf (output_file
, "}\n\n");
8034 /* The function outputs PHR interface function `state_alts'. */
8036 output_state_alts_func ()
8038 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8039 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8040 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8041 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8042 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8043 INTERNAL_INSN_CODE_NAME
, 0);
8044 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8045 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8048 /* Output function `min_issue_delay'. */
8050 output_min_issue_delay_func ()
8052 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8053 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8054 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8055 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8056 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8057 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8058 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8059 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8060 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8061 fprintf (output_file
, " }\n else\n %s = %s;\n",
8062 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8063 fprintf (output_file
, "\n return %s (%s, %s);\n",
8064 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8066 fprintf (output_file
, "}\n\n");
8069 /* Output function `internal_dead_lock'. */
8071 output_internal_dead_lock_func ()
8073 automaton_t automaton
;
8075 fprintf (output_file
, "static int %s PARAMS ((struct %s *));\n",
8076 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
);
8077 fprintf (output_file
, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8078 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_PARAMETER_NAME
, CHIP_NAME
,
8079 CHIP_PARAMETER_NAME
);
8080 fprintf (output_file
, "{\n");
8081 for (automaton
= description
->first_automaton
;
8083 automaton
= automaton
->next_automaton
)
8085 fprintf (output_file
, " if (");
8086 output_dead_lock_vect_name (output_file
, automaton
);
8087 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8088 output_chip_member_name (output_file
, automaton
);
8089 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8091 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8094 /* The function outputs PHR interface function `state_dead_lock_p'. */
8096 output_dead_lock_func ()
8098 fprintf (output_file
, "int\n%s (%s)\n\t%s %s;\n",
8099 DEAD_LOCK_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8100 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8101 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8104 /* Output function `internal_reset'. */
8106 output_internal_reset_func ()
8108 fprintf (output_file
, "static void %s PARAMS ((struct %s *));\n",
8109 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8110 fprintf (output_file
, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8111 INTERNAL_RESET_FUNC_NAME
, CHIP_PARAMETER_NAME
,
8112 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8113 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8114 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8117 /* The function outputs PHR interface function `state_size'. */
8121 fprintf (output_file
, "int\n%s ()\n", SIZE_FUNC_NAME
);
8122 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8125 /* The function outputs PHR interface function `state_reset'. */
8127 output_reset_func ()
8129 fprintf (output_file
, "void\n%s (%s)\n\t %s %s;\n",
8130 RESET_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8131 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8135 /* Output function `min_insn_conflict_delay'. */
8137 output_min_insn_conflict_delay_func ()
8139 fprintf (output_file
,
8140 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8141 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
,
8142 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8143 STATE_TYPE_NAME
, STATE_NAME
,
8144 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8145 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s;\n",
8146 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8147 INTERNAL_INSN2_CODE_NAME
);
8148 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8149 INTERNAL_INSN_CODE_NAME
, 0);
8150 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8151 INTERNAL_INSN2_CODE_NAME
, 0);
8152 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8153 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8154 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8155 fprintf (output_file
, " if (%s (%s, &%s) > 0)\n abort ();\n",
8156 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8157 fprintf (output_file
, " return %s (%s, &%s);\n",
8158 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8160 fprintf (output_file
, "}\n\n");
8163 /* Output function `internal_insn_latency'. */
8165 output_internal_insn_latency_func ()
8168 struct bypass_decl
*bypass
;
8171 fprintf (output_file
, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8172 INTERNAL_INSN_LATENCY_FUNC_NAME
);
8173 fprintf (output_file
, "static int\n%s (%s, %s, %s, %s)",
8174 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8175 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8176 INSN2_PARAMETER_NAME
);
8177 fprintf (output_file
, "\n\tint %s;\n\tint %s;\n",
8178 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8179 fprintf (output_file
,
8180 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8181 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8182 fprintf (output_file
, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8183 for (i
= 0; i
< description
->decls_num
; i
++)
8185 decl
= description
->decls
[i
];
8186 if (decl
->mode
== dm_insn_reserv
)
8188 fprintf (output_file
, " case %d:\n",
8189 decl
->decl
.insn_reserv
.insn_num
);
8190 if (decl
->decl
.insn_reserv
.bypass_list
== NULL
)
8191 fprintf (output_file
, " return (%s != %s ? %d : 0);\n",
8192 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8193 decl
->decl
.insn_reserv
.default_latency
);
8196 fprintf (output_file
, " switch (%s)\n {\n",
8197 INTERNAL_INSN2_CODE_NAME
);
8198 for (bypass
= decl
->decl
.insn_reserv
.bypass_list
;
8200 bypass
= bypass
->next
)
8202 fprintf (output_file
, " case %d:\n",
8203 bypass
->in_insn_reserv
->insn_num
);
8204 if (bypass
->bypass_guard_name
== NULL
)
8205 fprintf (output_file
, " return %d;\n",
8208 fprintf (output_file
,
8209 " return (%s (%s, %s) ? %d : %d);\n",
8210 bypass
->bypass_guard_name
, INSN_PARAMETER_NAME
,
8211 INSN2_PARAMETER_NAME
, bypass
->latency
,
8212 decl
->decl
.insn_reserv
.default_latency
);
8214 fprintf (output_file
, " default:\n");
8215 fprintf (output_file
,
8216 " return (%s != %s ? %d : 0);\n }\n",
8217 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8218 decl
->decl
.insn_reserv
.default_latency
);
8223 fprintf (output_file
, " default:\n return 0;\n }\n}\n\n");
8226 /* The function outputs PHR interface function `insn_latency'. */
8228 output_insn_latency_func ()
8230 fprintf (output_file
, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8231 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8232 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8233 fprintf (output_file
, "{\n int %s, %s;\n",
8234 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8235 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8236 INTERNAL_INSN_CODE_NAME
, 0);
8237 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8238 INTERNAL_INSN2_CODE_NAME
, 0);
8239 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8240 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8241 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8242 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8245 /* The function outputs PHR interface function `print_reservation'. */
8247 output_print_reservation_func ()
8252 fprintf (output_file
, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8253 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8254 INSN_PARAMETER_NAME
, FILE_PARAMETER_NAME
,
8255 INSN_PARAMETER_NAME
);
8256 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8257 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8258 fprintf (output_file
, " %s = %s (%s);\n",
8259 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8260 INSN_PARAMETER_NAME
);
8261 fprintf (output_file
, " if (%s > %s)\n",
8262 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8263 fprintf (output_file
, " {\n fprintf (%s, \"%s\");\n",
8264 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8265 fprintf (output_file
, " return;\n }\n");
8266 fprintf (output_file
, " }\n else\n");
8267 fprintf (output_file
,
8268 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8269 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8270 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8271 for (i
= 0; i
< description
->decls_num
; i
++)
8273 decl
= description
->decls
[i
];
8274 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8276 fprintf (output_file
,
8277 " case %d:\n", decl
->decl
.insn_reserv
.insn_num
);
8278 fprintf (output_file
,
8279 " fprintf (%s, \"%s\");\n break;\n",
8280 FILE_PARAMETER_NAME
,
8281 regexp_representation (decl
->decl
.insn_reserv
.regexp
));
8282 finish_regexp_representation ();
8285 fprintf (output_file
, " default:\n fprintf (%s, \"%s\");\n }\n",
8286 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8287 fprintf (output_file
, "}\n\n");
8290 /* The following function is used to sort unit declaration by their
8293 units_cmp (unit1
, unit2
)
8294 const void *unit1
, *unit2
;
8296 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8297 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8299 return strcmp (u1
->name
, u2
->name
);
8302 /* The following macro value is name of struct containing unit name
8304 #define NAME_CODE_STRUCT_NAME "name_code"
8306 /* The following macro value is name of table of struct name_code. */
8307 #define NAME_CODE_TABLE_NAME "name_code_table"
8309 /* The following macro values are member names for struct name_code. */
8310 #define NAME_MEMBER_NAME "name"
8311 #define CODE_MEMBER_NAME "code"
8313 /* The following macro values are local variable names for function
8314 `get_cpu_unit_code'. */
8315 #define CMP_VARIABLE_NAME "cmp"
8316 #define LOW_VARIABLE_NAME "l"
8317 #define MIDDLE_VARIABLE_NAME "m"
8318 #define HIGH_VARIABLE_NAME "h"
8320 /* The following function outputs function to obtain internal cpu unit
8321 code by the cpu unit name. */
8323 output_get_cpu_unit_code_func ()
8328 fprintf (output_file
, "int\n%s (%s)\n\tconst char *%s;\n",
8329 GET_CPU_UNIT_CODE_FUNC_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8330 CPU_UNIT_NAME_PARAMETER_NAME
);
8331 fprintf (output_file
, "{\n struct %s {const char *%s; int %s;};\n",
8332 NAME_CODE_STRUCT_NAME
, NAME_MEMBER_NAME
, CODE_MEMBER_NAME
);
8333 fprintf (output_file
, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME
,
8334 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8335 fprintf (output_file
, " static struct %s %s [] =\n {\n",
8336 NAME_CODE_STRUCT_NAME
, NAME_CODE_TABLE_NAME
);
8337 units
= (unit_decl_t
*) xmalloc (sizeof (unit_decl_t
)
8338 * description
->units_num
);
8339 memcpy (units
, units_array
, sizeof (unit_decl_t
) * description
->units_num
);
8340 qsort (units
, description
->units_num
, sizeof (unit_decl_t
), units_cmp
);
8341 for (i
= 0; i
< description
->units_num
; i
++)
8342 if (units
[i
]->query_p
)
8343 fprintf (output_file
, " {\"%s\", %d},\n",
8344 units
[i
]->name
, units
[i
]->query_num
);
8345 fprintf (output_file
, " };\n\n");
8346 fprintf (output_file
, " /* The following is binary search: */\n");
8347 fprintf (output_file
, " %s = 0;\n", LOW_VARIABLE_NAME
);
8348 fprintf (output_file
, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8349 HIGH_VARIABLE_NAME
, NAME_CODE_TABLE_NAME
, NAME_CODE_STRUCT_NAME
);
8350 fprintf (output_file
, " while (%s <= %s)\n {\n",
8351 LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8352 fprintf (output_file
, " %s = (%s + %s) / 2;\n",
8353 MIDDLE_VARIABLE_NAME
, LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8354 fprintf (output_file
, " %s = strcmp (%s, %s [%s].%s);\n",
8355 CMP_VARIABLE_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8356 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, NAME_MEMBER_NAME
);
8357 fprintf (output_file
, " if (%s < 0)\n", CMP_VARIABLE_NAME
);
8358 fprintf (output_file
, " %s = %s - 1;\n",
8359 HIGH_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8360 fprintf (output_file
, " else if (%s > 0)\n", CMP_VARIABLE_NAME
);
8361 fprintf (output_file
, " %s = %s + 1;\n",
8362 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8363 fprintf (output_file
, " else\n");
8364 fprintf (output_file
, " return %s [%s].%s;\n }\n",
8365 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, CODE_MEMBER_NAME
);
8366 fprintf (output_file
, " return -1;\n}\n\n");
8370 /* The following function outputs function to check reservation of cpu
8371 unit (its internal code will be passed as the function argument) in
8374 output_cpu_unit_reservation_p ()
8376 automaton_t automaton
;
8378 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8379 CPU_UNIT_RESERVATION_P_FUNC_NAME
, STATE_NAME
,
8380 CPU_CODE_PARAMETER_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8381 CPU_CODE_PARAMETER_NAME
);
8382 fprintf (output_file
, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8383 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
8384 description
->query_units_num
);
8385 for (automaton
= description
->first_automaton
;
8387 automaton
= automaton
->next_automaton
)
8389 fprintf (output_file
, " if ((");
8390 output_reserved_units_table_name (output_file
, automaton
);
8391 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
8392 output_chip_member_name (output_file
, automaton
);
8393 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8394 (description
->query_units_num
+ 7) / 8,
8395 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
8396 fprintf (output_file
, " return 1;\n");
8398 fprintf (output_file
, " return 0;\n}\n\n");
8401 /* The function outputs PHR interface function `dfa_start'. */
8403 output_dfa_start_func ()
8405 fprintf (output_file
,
8406 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8407 DFA_START_FUNC_NAME
, I_VARIABLE_NAME
,
8408 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8409 fprintf (output_file
, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8410 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8411 fprintf (output_file
,
8412 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8413 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
8414 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
8415 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
8418 /* The function outputs PHR interface function `dfa_finish'. */
8420 output_dfa_finish_func ()
8422 fprintf (output_file
, "void\n%s ()\n{\n free (%s);\n}\n\n",
8423 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8428 /* The page contains code for output description file (readable
8429 representation of original description and generated DFA(s). */
8431 /* The function outputs string representation of IR reservation. */
8433 output_regexp (regexp
)
8436 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
8437 finish_regexp_representation ();
8440 /* Output names of units in LIST separated by comma. */
8442 output_unit_set_el_list (list
)
8447 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
8450 fprintf (output_description_file
, ",");
8451 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
8455 /* The function outputs string representation of IR define_reservation
8456 and define_insn_reservation. */
8458 output_description ()
8463 for (i
= 0; i
< description
->decls_num
; i
++)
8465 decl
= description
->decls
[i
];
8466 if (decl
->mode
== dm_unit
)
8468 if (decl
->decl
.unit
.excl_list
!= NULL
)
8470 fprintf (output_description_file
, "unit %s exlusion_set: ",
8471 decl
->decl
.unit
.name
);
8472 output_unit_set_el_list (decl
->decl
.unit
.excl_list
);
8473 fprintf (output_description_file
, "\n");
8475 if (decl
->decl
.unit
.presence_list
!= NULL
)
8477 fprintf (output_description_file
, "unit %s presence_set: ",
8478 decl
->decl
.unit
.name
);
8479 output_unit_set_el_list (decl
->decl
.unit
.presence_list
);
8480 fprintf (output_description_file
, "\n");
8482 if (decl
->decl
.unit
.absence_list
!= NULL
)
8484 fprintf (output_description_file
, "unit %s absence_set: ",
8485 decl
->decl
.unit
.name
);
8486 output_unit_set_el_list (decl
->decl
.unit
.absence_list
);
8487 fprintf (output_description_file
, "\n");
8491 fprintf (output_description_file
, "\n");
8492 for (i
= 0; i
< description
->decls_num
; i
++)
8494 decl
= description
->decls
[i
];
8495 if (decl
->mode
== dm_reserv
)
8497 fprintf (output_description_file
, "reservation ");
8498 fprintf (output_description_file
, decl
->decl
.reserv
.name
);
8499 fprintf (output_description_file
, ": ");
8500 output_regexp (decl
->decl
.reserv
.regexp
);
8501 fprintf (output_description_file
, "\n");
8503 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8505 fprintf (output_description_file
, "insn reservation %s ",
8506 decl
->decl
.insn_reserv
.name
);
8507 print_rtl (output_description_file
, decl
->decl
.insn_reserv
.condexp
);
8508 fprintf (output_description_file
, ": ");
8509 output_regexp (decl
->decl
.insn_reserv
.regexp
);
8510 fprintf (output_description_file
, "\n");
8512 else if (decl
->mode
== dm_bypass
)
8513 fprintf (output_description_file
, "bypass %d %s %s\n",
8514 decl
->decl
.bypass
.latency
, decl
->decl
.bypass
.out_insn_name
,
8515 decl
->decl
.bypass
.in_insn_name
);
8517 fprintf (output_description_file
, "\n\f\n");
8520 /* The function outputs name of AUTOMATON. */
8522 output_automaton_name (f
, automaton
)
8524 automaton_t automaton
;
8526 if (automaton
->corresponding_automaton_decl
== NULL
)
8527 fprintf (f
, "#%d", automaton
->automaton_order_num
);
8529 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
8532 /* Maximal length of line for pretty printing into description
8534 #define MAX_LINE_LENGTH 70
8536 /* The function outputs units name belonging to AUTOMATON. */
8538 output_automaton_units (automaton
)
8539 automaton_t automaton
;
8543 int curr_line_length
;
8544 int there_is_an_automaton_unit
;
8547 fprintf (output_description_file
, "\n Coresponding units:\n");
8548 fprintf (output_description_file
, " ");
8549 curr_line_length
= 4;
8550 there_is_an_automaton_unit
= 0;
8551 for (i
= 0; i
< description
->decls_num
; i
++)
8553 decl
= description
->decls
[i
];
8554 if (decl
->mode
== dm_unit
8555 && (decl
->decl
.unit
.corresponding_automaton_num
8556 == automaton
->automaton_order_num
))
8558 there_is_an_automaton_unit
= 1;
8559 name
= decl
->decl
.unit
.name
;
8560 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
8562 curr_line_length
= strlen (name
) + 4;
8563 fprintf (output_description_file
, "\n ");
8567 curr_line_length
+= strlen (name
) + 1;
8568 fprintf (output_description_file
, " ");
8570 fprintf (output_description_file
, name
);
8573 if (!there_is_an_automaton_unit
)
8574 fprintf (output_description_file
, "<None>");
8575 fprintf (output_description_file
, "\n\n");
8578 /* The following variable is used for forming array of all possible cpu unit
8579 reservations described by the current DFA state. */
8580 static vla_ptr_t state_reservs
;
8582 /* The function forms `state_reservs' for STATE. */
8584 add_state_reservs (state
)
8587 alt_state_t curr_alt_state
;
8588 reserv_sets_t reservs
;
8590 if (state
->component_states
!= NULL
)
8591 for (curr_alt_state
= state
->component_states
;
8592 curr_alt_state
!= NULL
;
8593 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
8594 add_state_reservs (curr_alt_state
->state
);
8597 reservs
= state
->reservs
;
8598 VLA_PTR_ADD (state_reservs
, reservs
);
8602 /* The function outputs readable represenatation of all out arcs of
8605 output_state_arcs (state
)
8611 int curr_line_length
;
8613 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
8616 if (!ainsn
->first_insn_with_same_reservs
)
8618 fprintf (output_description_file
, " ");
8619 curr_line_length
= 7;
8620 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
8623 insn_name
= ainsn
->insn_reserv_decl
->name
;
8624 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
8626 if (ainsn
!= arc
->insn
)
8628 fprintf (output_description_file
, ",\n ");
8629 curr_line_length
= strlen (insn_name
) + 6;
8632 curr_line_length
+= strlen (insn_name
);
8636 curr_line_length
+= strlen (insn_name
);
8637 if (ainsn
!= arc
->insn
)
8639 curr_line_length
+= 2;
8640 fprintf (output_description_file
, ", ");
8643 fprintf (output_description_file
, insn_name
);
8644 ainsn
= ainsn
->next_same_reservs_insn
;
8646 while (ainsn
!= NULL
);
8647 fprintf (output_description_file
, " %d (%d)\n",
8648 arc
->to_state
->order_state_num
, arc
->state_alts
);
8650 fprintf (output_description_file
, "\n");
8653 /* The following function is used for sorting possible cpu unit
8654 reservation of a DFA state. */
8656 state_reservs_cmp (reservs_ptr_1
, reservs_ptr_2
)
8657 const void *reservs_ptr_1
;
8658 const void *reservs_ptr_2
;
8660 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
8661 *(reserv_sets_t
*) reservs_ptr_2
);
8664 /* The following function is used for sorting possible cpu unit
8665 reservation of a DFA state. */
8667 remove_state_duplicate_reservs ()
8669 reserv_sets_t
*reservs_ptr
;
8670 reserv_sets_t
*last_formed_reservs_ptr
;
8672 last_formed_reservs_ptr
= NULL
;
8673 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
8674 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
8676 if (last_formed_reservs_ptr
== NULL
)
8677 last_formed_reservs_ptr
= reservs_ptr
;
8678 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
8680 ++last_formed_reservs_ptr
;
8681 *last_formed_reservs_ptr
= *reservs_ptr
;
8683 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
8686 /* The following function output readable representation of DFA(s)
8687 state used for fast recognition of pipeline hazards. State is
8688 described by possible (current and scehduled) cpu unit
8691 output_state (state
)
8694 reserv_sets_t
*reservs_ptr
;
8696 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
8697 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
8698 fprintf (output_description_file
,
8699 state
->new_cycle_p
? " (new cycle)\n" : "\n");
8700 add_state_reservs (state
);
8701 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
8702 sizeof (reserv_sets_t
), state_reservs_cmp
);
8703 remove_state_duplicate_reservs ();
8704 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
8705 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
8708 fprintf (output_description_file
, " ");
8709 output_reserv_sets (output_description_file
, *reservs_ptr
);
8710 fprintf (output_description_file
, "\n");
8712 fprintf (output_description_file
, "\n");
8713 output_state_arcs (state
);
8714 VLA_PTR_DELETE (state_reservs
);
8717 /* The following function output readable representation of
8718 DFAs used for fast recognition of pipeline hazards. */
8720 output_automaton_descriptions ()
8722 automaton_t automaton
;
8724 for (automaton
= description
->first_automaton
;
8726 automaton
= automaton
->next_automaton
)
8728 fprintf (output_description_file
, "\nAutomaton ");
8729 output_automaton_name (output_description_file
, automaton
);
8730 fprintf (output_description_file
, "\n");
8731 output_automaton_units (automaton
);
8732 pass_states (automaton
, output_state
);
8738 /* The page contains top level function for generation DFA(s) used for
8741 /* The function outputs statistics about work of different phases of
8744 output_statistics (f
)
8747 automaton_t automaton
;
8749 int transition_comb_vect_els
= 0;
8750 int transition_full_vect_els
= 0;
8751 int state_alts_comb_vect_els
= 0;
8752 int state_alts_full_vect_els
= 0;
8753 int min_issue_delay_vect_els
= 0;
8756 for (automaton
= description
->first_automaton
;
8758 automaton
= automaton
->next_automaton
)
8760 fprintf (f
, "\nAutomaton ");
8761 output_automaton_name (f
, automaton
);
8762 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
8763 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
8764 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
8765 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
8766 if (!no_minimization_flag
)
8767 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8768 automaton
->minimal_DFA_states_num
,
8769 automaton
->minimal_DFA_arcs_num
);
8770 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
8771 description
->insns_num
, automaton
->insn_equiv_classes_num
);
8774 (f
, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8775 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
),
8776 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
),
8777 (comb_vect_p (automaton
->trans_table
)
8778 ? "use comb vect" : "use simple vect"));
8780 (f
, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8781 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
),
8782 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
),
8783 (comb_vect_p (automaton
->state_alts_table
)
8784 ? "use comb vect" : "use simple vect"));
8786 (f
, "%5ld min delay table els, compression factor %d\n",
8787 (long) automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
,
8788 automaton
->min_issue_delay_table_compression_factor
);
8789 transition_comb_vect_els
8790 += VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
);
8791 transition_full_vect_els
8792 += VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
);
8793 state_alts_comb_vect_els
8794 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
);
8795 state_alts_full_vect_els
8796 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
);
8797 min_issue_delay_vect_els
8798 += automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
;
8802 fprintf (f
, "\n%5d all allocated states, %5d all allocated arcs\n",
8803 allocated_states_num
, allocated_arcs_num
);
8804 fprintf (f
, "%5d all allocated alternative states\n",
8805 allocated_alt_states_num
);
8806 fprintf (f
, "%5d all transition comb vector els, %5d all trans table els\n",
8807 transition_comb_vect_els
, transition_full_vect_els
);
8809 (f
, "%5d all state alts comb vector els, %5d all state alts table els\n",
8810 state_alts_comb_vect_els
, state_alts_full_vect_els
);
8811 fprintf (f
, "%5d all min delay table els\n", min_issue_delay_vect_els
);
8812 fprintf (f
, "%5d locked states num\n", locked_states_num
);
8816 /* The function output times of work of different phases of DFA
8819 output_time_statistics (f
)
8822 fprintf (f
, "\n transformation: ");
8823 print_active_time (f
, transform_time
);
8824 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
8825 print_active_time (f
, NDFA_time
);
8828 fprintf (f
, ", NDFA -> DFA: ");
8829 print_active_time (f
, NDFA_to_DFA_time
);
8831 fprintf (f
, "\n DFA minimization: ");
8832 print_active_time (f
, minimize_time
);
8833 fprintf (f
, ", making insn equivalence: ");
8834 print_active_time (f
, equiv_time
);
8835 fprintf (f
, "\n all automaton generation: ");
8836 print_active_time (f
, automaton_generation_time
);
8837 fprintf (f
, ", output: ");
8838 print_active_time (f
, output_time
);
8842 /* The function generates DFA (deterministic finate state automaton)
8843 for fast recognition of pipeline hazards. No errors during
8844 checking must be fixed before this function call. */
8848 automata_num
= split_argument
;
8849 if (description
->units_num
< automata_num
)
8850 automata_num
= description
->units_num
;
8853 initiate_automata_lists ();
8854 initiate_pass_states ();
8855 initiate_excl_sets ();
8856 initiate_presence_absence_sets ();
8857 automaton_generation_time
= create_ticker ();
8859 ticker_off (&automaton_generation_time
);
8864 /* The following function creates attribute which order number of insn
8865 in pipeline hazard description translator. */
8867 make_insn_alts_attr ()
8873 condexp
= rtx_alloc (COND
);
8874 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
8875 XEXP (condexp
, 1) = make_numeric_value (0);
8876 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
8878 decl
= description
->decls
[i
];
8879 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8881 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
8882 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
8883 = make_numeric_value (decl
->decl
.insn_reserv
.transformed_regexp
8884 ->regexp
.oneof
.regexps_num
);
8888 if (description
->insns_num
!= insn_num
+ 1)
8890 make_internal_attr (attr_printf (sizeof ("*")
8891 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
8892 "*%s", INSN_ALTS_FUNC_NAME
),
8898 /* The following function creates attribute which is order number of
8899 insn in pipeline hazard description translator. */
8901 make_internal_dfa_insn_code_attr ()
8907 condexp
= rtx_alloc (COND
);
8908 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
8909 XEXP (condexp
, 1) = make_numeric_value (advance_cycle_insn_decl
8910 ->decl
.insn_reserv
.insn_num
+ 1);
8911 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
8913 decl
= description
->decls
[i
];
8914 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8916 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
8917 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
8918 = make_numeric_value (decl
->decl
.insn_reserv
.insn_num
);
8922 if (description
->insns_num
!= insn_num
+ 1)
8925 (attr_printf (sizeof ("*")
8926 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
8927 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
8933 /* The following function creates attribute which order number of insn
8934 in pipeline hazard description translator. */
8936 make_default_insn_latency_attr ()
8942 condexp
= rtx_alloc (COND
);
8943 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
8944 XEXP (condexp
, 1) = make_numeric_value (0);
8945 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
8947 decl
= description
->decls
[i
];
8948 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8950 XVECEXP (condexp
, 0, 2 * insn_num
) = decl
->decl
.insn_reserv
.condexp
;
8951 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
8952 = make_numeric_value (decl
->decl
.insn_reserv
.default_latency
);
8956 if (description
->insns_num
!= insn_num
+ 1)
8958 make_internal_attr (attr_printf (sizeof ("*")
8959 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
8960 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
8966 /* The following function creates attribute which returns 1 if given
8967 output insn has bypassing and 0 otherwise. */
8972 int bypass_insns_num
= 0;
8976 for (i
= 0; i
< description
->decls_num
; i
++)
8978 decl
= description
->decls
[i
];
8979 if (decl
->mode
== dm_insn_reserv
8980 && decl
->decl
.insn_reserv
.condexp
!= NULL
8981 && decl
->decl
.insn_reserv
.bypass_list
!= NULL
)
8984 if (bypass_insns_num
== 0)
8985 result_rtx
= make_numeric_value (0);
8988 result_rtx
= rtx_alloc (COND
);
8989 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
8990 XEXP (result_rtx
, 1) = make_numeric_value (0);
8992 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
8994 decl
= description
->decls
[i
];
8995 if (decl
->mode
== dm_insn_reserv
8996 && decl
->decl
.insn_reserv
.condexp
!= NULL
8997 && decl
->decl
.insn_reserv
.bypass_list
!= NULL
)
8999 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9000 = decl
->decl
.insn_reserv
.condexp
;
9001 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9002 = make_numeric_value (1);
9007 make_internal_attr (attr_printf (sizeof ("*")
9008 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9009 "*%s", BYPASS_P_FUNC_NAME
),
9015 /* This page mainly contains top level functions of pipeline hazards
9016 description translator. */
9018 /* The following macro value is suffix of name of description file of
9019 pipeline hazards description translator. */
9020 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9022 /* The function returns suffix of given file name. The returned
9023 string can not be changed. */
9025 file_name_suffix (file_name
)
9026 const char *file_name
;
9028 const char *last_period
;
9030 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9031 if (*file_name
== '.')
9032 last_period
= file_name
;
9033 return (last_period
== NULL
? file_name
: last_period
);
9036 /* The function returns base name of given file name, i.e. pointer to
9037 first char after last `/' (or `\' for WIN32) in given file name,
9038 given file name itself if the directory name is absent. The
9039 returned string can not be changed. */
9041 base_file_name (file_name
)
9042 const char *file_name
;
9044 int directory_name_length
;
9046 directory_name_length
= strlen (file_name
);
9048 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9049 && file_name
[directory_name_length
] != '\\')
9051 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9053 directory_name_length
--;
9054 return file_name
+ directory_name_length
+ 1;
9057 /* The following is top level function to initialize the work of
9058 pipeline hazards description translator. */
9060 initiate_automaton_gen (argc
, argv
)
9064 const char *base_name
;
9068 split_argument
= 0; /* default value */
9069 no_minimization_flag
= 0;
9073 for (i
= 2; i
< argc
; i
++)
9074 if (strcmp (argv
[i
], NO_MINIMIZATION_OPTION
) == 0)
9075 no_minimization_flag
= 1;
9076 else if (strcmp (argv
[i
], "-time") == 0)
9078 else if (strcmp (argv
[i
], "-v") == 0)
9080 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9082 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9084 else if (strcmp (argv
[i
], "-split") == 0)
9087 fatal ("-split has no argument.");
9088 fatal ("option `-split' has not been implemented yet\n");
9089 /* split_argument = atoi (argument_vect [i + 1]); */
9091 VLA_PTR_CREATE (decls
, 150, "decls");
9092 /* Initialize IR storage. */
9093 obstack_init (&irp
);
9094 initiate_automaton_decl_table ();
9095 initiate_insn_decl_table ();
9096 initiate_decl_table ();
9097 output_file
= stdout
;
9098 output_description_file
= NULL
;
9099 base_name
= base_file_name (argv
[1]);
9100 obstack_grow (&irp
, base_name
,
9101 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9102 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9103 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9104 obstack_1grow (&irp
, '\0');
9105 output_description_file_name
= obstack_base (&irp
);
9106 obstack_finish (&irp
);
9109 /* The following function checks existence at least one arc marked by
9112 check_automata_insn_issues ()
9114 automaton_t automaton
;
9115 ainsn_t ainsn
, reserv_ainsn
;
9117 for (automaton
= description
->first_automaton
;
9119 automaton
= automaton
->next_automaton
)
9121 for (ainsn
= automaton
->ainsn_list
;
9123 ainsn
= ainsn
->next_ainsn
)
9124 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9126 for (reserv_ainsn
= ainsn
;
9127 reserv_ainsn
!= NULL
;
9128 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9129 if (automaton
->corresponding_automaton_decl
!= NULL
)
9132 error ("Automaton `%s': Insn `%s' will never be issued",
9133 automaton
->corresponding_automaton_decl
->name
,
9134 reserv_ainsn
->insn_reserv_decl
->name
);
9137 ("Automaton `%s': Insn `%s' will never be issued",
9138 automaton
->corresponding_automaton_decl
->name
,
9139 reserv_ainsn
->insn_reserv_decl
->name
);
9144 error ("Insn `%s' will never be issued",
9145 reserv_ainsn
->insn_reserv_decl
->name
);
9147 warning ("Insn `%s' will never be issued",
9148 reserv_ainsn
->insn_reserv_decl
->name
);
9154 /* The following vla is used for storing pointers to all achieved
9156 static vla_ptr_t automaton_states
;
9158 /* This function is called by function pass_states to add an achieved
9161 add_automaton_state (state
)
9164 VLA_PTR_ADD (automaton_states
, state
);
9167 /* The following function forms list of important automata (whose
9168 states may be changed after the insn issue) for each insn. */
9170 form_important_insn_automata_lists ()
9172 automaton_t automaton
;
9179 VLA_PTR_CREATE (automaton_states
, 1500,
9180 "automaton states for forming important insn automata sets");
9181 /* Mark important ainsns. */
9182 for (automaton
= description
->first_automaton
;
9184 automaton
= automaton
->next_automaton
)
9186 VLA_PTR_NULLIFY (automaton_states
);
9187 pass_states (automaton
, add_automaton_state
);
9188 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9189 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9192 for (arc
= first_out_arc (*state_ptr
);
9194 arc
= next_out_arc (arc
))
9195 if (arc
->to_state
!= *state_ptr
)
9197 if (!arc
->insn
->first_insn_with_same_reservs
)
9199 for (ainsn
= arc
->insn
;
9201 ainsn
= ainsn
->next_same_reservs_insn
)
9202 ainsn
->important_p
= TRUE
;
9206 VLA_PTR_DELETE (automaton_states
);
9207 /* Create automata sets for the insns. */
9208 for (i
= 0; i
< description
->decls_num
; i
++)
9210 decl
= description
->decls
[i
];
9211 if (decl
->mode
== dm_insn_reserv
)
9213 automata_list_start ();
9214 for (automaton
= description
->first_automaton
;
9216 automaton
= automaton
->next_automaton
)
9217 for (ainsn
= automaton
->ainsn_list
;
9219 ainsn
= ainsn
->next_ainsn
)
9220 if (ainsn
->important_p
9221 && ainsn
->insn_reserv_decl
== &decl
->decl
.insn_reserv
)
9223 automata_list_add (automaton
);
9226 decl
->decl
.insn_reserv
.important_automata_list
9227 = automata_list_finish ();
9233 /* The following is top level function to generate automat(a,on) for
9234 fast recognition of pipeline hazards. */
9240 description
= create_node (sizeof (struct description
)
9241 /* One entry for cycle advancing insn. */
9242 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9243 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9244 description
->query_units_num
= 0;
9245 for (i
= 0; i
< description
->decls_num
; i
++)
9247 description
->decls
[i
] = VLA_PTR (decls
, i
);
9248 if (description
->decls
[i
]->mode
== dm_unit
9249 && description
->decls
[i
]->decl
.unit
.query_p
)
9250 description
->decls
[i
]->decl
.unit
.query_num
9251 = description
->query_units_num
++;
9253 all_time
= create_ticker ();
9254 check_time
= create_ticker ();
9255 fprintf (stderr
, "Check description...");
9257 check_all_description ();
9258 fprintf (stderr
, "done\n");
9259 ticker_off (&check_time
);
9260 generation_time
= create_ticker ();
9263 transform_insn_regexps ();
9264 check_unit_distributions_to_automata ();
9269 check_automata_insn_issues ();
9273 form_important_insn_automata_lists ();
9274 fprintf (stderr
, "Generation of attributes...");
9276 make_internal_dfa_insn_code_attr ();
9277 make_insn_alts_attr ();
9278 make_default_insn_latency_attr ();
9279 make_bypass_attr ();
9280 fprintf (stderr
, "done\n");
9282 ticker_off (&generation_time
);
9283 ticker_off (&all_time
);
9284 fprintf (stderr
, "All other genattrtab stuff...");
9288 /* The following is top level function to output PHR and to finish
9289 work with pipeline description translator. */
9293 fprintf (stderr
, "done\n");
9295 fatal ("Errors in DFA description");
9296 ticker_on (&all_time
);
9297 output_time
= create_ticker ();
9298 fprintf (stderr
, "Forming and outputing automata tables...");
9300 output_dfa_max_issue_rate ();
9302 fprintf (stderr
, "done\n");
9303 fprintf (stderr
, "Output functions to work with automata...");
9305 output_chip_definitions ();
9306 output_max_insn_queue_index_def ();
9307 output_internal_min_issue_delay_func ();
9308 output_internal_trans_func ();
9309 /* Cache of insn dfa codes: */
9310 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9311 fprintf (output_file
, "\nstatic int %s;\n\n",
9312 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9313 output_dfa_insn_code_func ();
9314 output_trans_func ();
9315 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
9316 output_internal_state_alts_func ();
9317 output_state_alts_func ();
9318 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9319 AUTOMATON_STATE_ALTS_MACRO_NAME
);
9320 output_min_issue_delay_func ();
9321 output_internal_dead_lock_func ();
9322 output_dead_lock_func ();
9323 output_size_func ();
9324 output_internal_reset_func ();
9325 output_reset_func ();
9326 output_min_insn_conflict_delay_func ();
9327 output_internal_insn_latency_func ();
9328 output_insn_latency_func ();
9329 output_print_reservation_func ();
9330 if (no_minimization_flag
)
9332 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
9333 output_get_cpu_unit_code_func ();
9334 output_cpu_unit_reservation_p ();
9335 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9336 CPU_UNITS_QUERY_MACRO_NAME
);
9338 output_dfa_start_func ();
9339 output_dfa_finish_func ();
9340 fprintf (stderr
, "done\n");
9343 output_description_file
= fopen (output_description_file_name
, "w");
9344 if (output_description_file
== NULL
)
9346 perror (output_description_file_name
);
9347 exit (FATAL_EXIT_CODE
);
9349 fprintf (stderr
, "Output automata description...");
9351 output_description ();
9352 output_automaton_descriptions ();
9353 fprintf (stderr
, "done\n");
9354 output_statistics (output_description_file
);
9356 output_statistics (stderr
);
9357 ticker_off (&output_time
);
9358 output_time_statistics (stderr
);
9361 finish_automata_lists ();
9364 fprintf (stderr
, "Summary:\n");
9365 fprintf (stderr
, " check time ");
9366 print_active_time (stderr
, check_time
);
9367 fprintf (stderr
, ", generation time ");
9368 print_active_time (stderr
, generation_time
);
9369 fprintf (stderr
, ", all time ");
9370 print_active_time (stderr
, all_time
);
9371 fprintf (stderr
, "\n");
9373 /* Finish all work. */
9374 if (output_description_file
!= NULL
)
9376 fflush (output_description_file
);
9377 if (ferror (stdout
) != 0)
9378 fatal ("Error in writing DFA description file %s",
9379 output_description_file_name
);
9380 fclose (output_description_file
);
9382 finish_automaton_decl_table ();
9383 finish_insn_decl_table ();
9384 finish_decl_table ();
9385 obstack_free (&irp
, NULL
);
9386 if (have_error
&& output_description_file
!= NULL
)
9387 remove (output_description_file_name
);