]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genautomata.c
re PR rtl-optimization/31500 (FAIL: gcc.dg/Warray-bounds.c (internal compiler error))
[thirdparty/gcc.git] / gcc / genautomata.c
CommitLineData
fae15c93 1/* Pipeline hazard description translator.
df1133a6 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
a4de48bc 3 Free Software Foundation, Inc.
fae15c93
VM
4
5 Written by Vladimir Makarov <vmakarov@redhat.com>
3d7aafde 6
54a7b573 7This file is part of GCC.
fae15c93 8
54a7b573 9GCC is free software; you can redistribute it and/or modify it
fae15c93
VM
10under the terms of the GNU General Public License as published by the
11Free Software Foundation; either version 2, or (at your option) any
12later version.
13
54a7b573 14GCC is distributed in the hope that it will be useful, but WITHOUT
fae15c93
VM
15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
54a7b573 20along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
21Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2202110-1301, USA. */
fae15c93
VM
23
24/* References:
3d7aafde 25
fae15c93
VM
26 1. Detecting pipeline structural hazards quickly. T. Proebsting,
27 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
28 Principles of Programming Languages, pages 280--286, 1994.
29
30 This article is a good start point to understand usage of finite
31 state automata for pipeline hazard recognizers. But I'd
32 recommend the 2nd article for more deep understanding.
33
34 2. Efficient Instruction Scheduling Using Finite State Automata:
35 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
36 article about usage of finite state automata for pipeline hazard
37 recognizers.
38
39 The current implementation is different from the 2nd article in the
40 following:
41
42 1. New operator `|' (alternative) is permitted in functional unit
fbe5a4a6
KH
43 reservation which can be treated deterministically and
44 non-deterministically.
fae15c93
VM
45
46 2. Possibility of usage of nondeterministic automata too.
47
48 3. Possibility to query functional unit reservations for given
49 automaton state.
50
51 4. Several constructions to describe impossible reservations
30028c85
VM
52 (`exclusion_set', `presence_set', `final_presence_set',
53 `absence_set', and `final_absence_set').
fae15c93
VM
54
55 5. No reverse automata are generated. Trace instruction scheduling
56 requires this. It can be easily added in the future if we
57 really need this.
58
59 6. Union of automaton states are not generated yet. It is planned
60 to be implemented. Such feature is needed to make more accurate
61 interlock insn scheduling to get state describing functional
30028c85 62 unit reservation in a joint CFG point. */
fae15c93
VM
63
64/* This file code processes constructions of machine description file
65 which describes automaton used for recognition of processor pipeline
66 hazards by insn scheduler and can be used for other tasks (such as
67 VLIW insn packing.
68
69 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
70 `gen_bypass', `gen_excl_set', `gen_presence_set',
30028c85
VM
71 `gen_final_presence_set', `gen_absence_set',
72 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
fae15c93
VM
73 `gen_reserv', `gen_insn_reserv' are called from file
74 `genattrtab.c'. They transform RTL constructions describing
75 automata in .md file into internal representation convenient for
76 further processing.
3d7aafde 77
fae15c93
VM
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
80 It can be divided on:
81
82 o checking correctness of the automaton pipeline description
83 (major function is `check_all_description').
84
85 o generating automaton (automata) from the description (major
86 function is `make_automaton').
87
88 o optional transformation of nondeterministic finite state
89 automata into deterministic ones if the alternative operator
96e13905 90 `|' is treated nondeterministically in the description (major
fae15c93
VM
91 function is NDFA_to_DFA).
92
93 o optional minimization of the finite state automata by merging
94 equivalent automaton states (major function is `minimize_DFA').
95
96 o forming tables (some as comb vectors) and attributes
97 representing the automata (functions output_..._table).
98
99 Function `write_automata' outputs the created finite state
100 automaton as different tables and functions which works with the
101 automata to inquire automaton state and to change its state. These
102 function are used by gcc instruction scheduler and may be some
103 other gcc code. */
104
4977bab6 105#include "bconfig.h"
fae15c93 106#include "system.h"
4977bab6
ZW
107#include "coretypes.h"
108#include "tm.h"
fae15c93
VM
109#include "rtl.h"
110#include "obstack.h"
111#include "errors.h"
8c94f366 112#include "gensupport.h"
fae15c93 113
fae15c93
VM
114#include <math.h>
115#include "hashtab.h"
1fb49ce7 116#include "vec.h"
fae15c93 117
fae15c93
VM
118#ifndef CHAR_BIT
119#define CHAR_BIT 8
120#endif
fae15c93 121
fae15c93
VM
122/* Positions in machine description file. Now they are not used. But
123 they could be used in the future for better diagnostic messages. */
124typedef int pos_t;
125
126/* The following is element of vector of current (and planned in the
127 future) functional unit reservations. */
128typedef unsigned HOST_WIDE_INT set_el_t;
129
130/* Reservations of function units are represented by value of the following
131 type. */
132typedef set_el_t *reserv_sets_t;
133
fae15c93
VM
134/* The following structure describes a ticker. */
135struct ticker
136{
137 /* The following member value is time of the ticker creation with
138 taking into account time when the ticker is off. Active time of
139 the ticker is current time minus the value. */
140 int modified_creation_time;
141 /* The following member value is time (incremented by one) when the
142 ticker was off. Zero value means that now the ticker is on. */
143 int incremented_off_time;
144};
145
146/* The ticker is represented by the following type. */
147typedef struct ticker ticker_t;
148
149/* The following type describes elements of output vectors. */
150typedef HOST_WIDE_INT vect_el_t;
151
152/* Forward declaration of structures of internal representation of
153 pipeline description based on NDFA. */
154
155struct unit_decl;
156struct bypass_decl;
157struct result_decl;
158struct automaton_decl;
30028c85 159struct unit_pattern_rel_decl;
fae15c93
VM
160struct reserv_decl;
161struct insn_reserv_decl;
162struct decl;
163struct unit_regexp;
164struct result_regexp;
165struct reserv_regexp;
166struct nothing_regexp;
167struct sequence_regexp;
168struct repeat_regexp;
169struct allof_regexp;
170struct oneof_regexp;
171struct regexp;
172struct description;
173struct unit_set_el;
30028c85
VM
174struct pattern_set_el;
175struct pattern_reserv;
fae15c93
VM
176struct state;
177struct alt_state;
178struct arc;
179struct ainsn;
180struct automaton;
181struct state_ainsn_table;
182
183/* The following typedefs are for brevity. */
deb09eff 184typedef struct unit_decl *unit_decl_t;
fae15c93
VM
185typedef struct decl *decl_t;
186typedef struct regexp *regexp_t;
187typedef struct unit_set_el *unit_set_el_t;
30028c85
VM
188typedef struct pattern_set_el *pattern_set_el_t;
189typedef struct pattern_reserv *pattern_reserv_t;
fae15c93
VM
190typedef struct alt_state *alt_state_t;
191typedef struct state *state_t;
192typedef struct arc *arc_t;
193typedef struct ainsn *ainsn_t;
194typedef struct automaton *automaton_t;
195typedef struct automata_list_el *automata_list_el_t;
196typedef struct state_ainsn_table *state_ainsn_table_t;
197
fae15c93
VM
198/* Undefined position. */
199static pos_t no_pos = 0;
200
201/* All IR is stored in the following obstack. */
202static struct obstack irp;
203
204\f
1fb49ce7
ZW
205/* Declare vector types for various data structures: */
206
207DEF_VEC_P(alt_state_t);
208DEF_VEC_ALLOC_P(alt_state_t,heap);
209DEF_VEC_P(ainsn_t);
210DEF_VEC_ALLOC_P(ainsn_t,heap);
211DEF_VEC_P(state_t);
212DEF_VEC_ALLOC_P(state_t,heap);
213DEF_VEC_P(decl_t);
214DEF_VEC_ALLOC_P(decl_t,heap);
215DEF_VEC_P(reserv_sets_t);
216DEF_VEC_ALLOC_P(reserv_sets_t,heap);
217
218DEF_VEC_I(vect_el_t);
219DEF_VEC_ALLOC_I(vect_el_t, heap);
220typedef VEC(vect_el_t,heap) *vla_hwint_t;
8c94f366
ZW
221\f
222/* Forward declarations of functions used before their definitions, only. */
223static regexp_t gen_regexp_sequence (const char *);
224static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
225 reserv_sets_t);
226static reserv_sets_t get_excl_set (reserv_sets_t);
227static int check_presence_pattern_sets (reserv_sets_t,
228 reserv_sets_t, int);
229static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
230 int);
231static arc_t first_out_arc (state_t);
232static arc_t next_out_arc (arc_t);
233
fae15c93
VM
234\f
235
236/* Options with the following names can be set up in automata_option
237 construction. Because the strings occur more one time we use the
238 macros. */
239
240#define NO_MINIMIZATION_OPTION "-no-minimization"
e3c8eb86 241#define TIME_OPTION "-time"
df1133a6 242#define STATS_OPTION "-stats"
e3c8eb86 243#define V_OPTION "-v"
fae15c93 244#define W_OPTION "-w"
fae15c93 245#define NDFA_OPTION "-ndfa"
dfa849f3
VM
246#define PROGRESS_OPTION "-progress"
247
fae15c93
VM
248/* The following flags are set up by function `initiate_automaton_gen'. */
249
250/* Make automata with nondeterministic reservation by insns (`-ndfa'). */
251static int ndfa_flag;
252
253/* Do not make minimization of DFA (`-no-minimization'). */
254static int no_minimization_flag;
255
256/* Value of this variable is number of automata being generated. The
257 actual number of automata may be less this value if there is not
258 sufficient number of units. This value is defined by argument of
259 option `-split' or by constructions automaton if the value is zero
260 (it is default value of the argument). */
261static int split_argument;
262
263/* Flag of output time statistics (`-time'). */
264static int time_flag;
265
df1133a6
BE
266/* Flag of automata statistics (`-stats'). */
267static int stats_flag;
268
fae15c93
VM
269/* Flag of creation of description file which contains description of
270 result automaton and statistics information (`-v'). */
271static int v_flag;
272
dfa849f3
VM
273/* Flag of output of a progress bar showing how many states were
274 generated so far for automaton being processed (`-progress'). */
275static int progress_flag;
276
fae15c93
VM
277/* Flag of generating warning instead of error for non-critical errors
278 (`-w'). */
279static int w_flag;
280
281
282/* Output file for pipeline hazard recognizer (PHR) being generated.
283 The value is NULL if the file is not defined. */
284static FILE *output_file;
285
286/* Description file of PHR. The value is NULL if the file is not
287 created. */
288static FILE *output_description_file;
289
290/* PHR description file name. */
291static char *output_description_file_name;
292
293/* Value of the following variable is node representing description
294 being processed. This is start point of IR. */
295static struct description *description;
296
297\f
298
299/* This page contains description of IR structure (nodes). */
300
301enum decl_mode
302{
303 dm_unit,
304 dm_bypass,
305 dm_automaton,
306 dm_excl,
307 dm_presence,
308 dm_absence,
309 dm_reserv,
310 dm_insn_reserv
311};
312
313/* This describes define_cpu_unit and define_query_cpu_unit (see file
314 rtl.def). */
315struct unit_decl
316{
1fb49ce7 317 const char *name;
fae15c93 318 /* NULL if the automaton name is absent. */
1fb49ce7 319 const char *automaton_name;
fae15c93
VM
320 /* If the following value is not zero, the cpu unit reservation is
321 described in define_query_cpu_unit. */
322 char query_p;
323
324 /* The following fields are defined by checker. */
325
326 /* The following field value is nonzero if the unit is used in an
327 regexp. */
328 char unit_is_used;
deb09eff 329
fae15c93
VM
330 /* The following field value is order number (0, 1, ...) of given
331 unit. */
332 int unit_num;
333 /* The following field value is corresponding declaration of
334 automaton which was given in description. If the field value is
335 NULL then automaton in the unit declaration was absent. */
336 struct automaton_decl *automaton_decl;
337 /* The following field value is maximal cycle number (1, ...) on
338 which given unit occurs in insns. Zero value means that given
339 unit is not used in insns. */
340 int max_occ_cycle_num;
30028c85
VM
341 /* The following field value is minimal cycle number (0, ...) on
342 which given unit occurs in insns. -1 value means that given
343 unit is not used in insns. */
344 int min_occ_cycle_num;
fae15c93
VM
345 /* The following list contains units which conflict with given
346 unit. */
347 unit_set_el_t excl_list;
30028c85 348 /* The following list contains patterns which are required to
fae15c93 349 reservation of given unit. */
30028c85
VM
350 pattern_set_el_t presence_list;
351 pattern_set_el_t final_presence_list;
352 /* The following list contains patterns which should be not present
353 in reservation for given unit. */
354 pattern_set_el_t absence_list;
355 pattern_set_el_t final_absence_list;
fae15c93
VM
356 /* The following is used only when `query_p' has nonzero value.
357 This is query number for the unit. */
358 int query_num;
1b1f249d
VM
359 /* The following is the last cycle on which the unit was checked for
360 correct distributions of units to automata in a regexp. */
361 int last_distribution_check_cycle;
fae15c93
VM
362
363 /* The following fields are defined by automaton generator. */
364
365 /* The following field value is number of the automaton to which
366 given unit belongs. */
367 int corresponding_automaton_num;
30028c85
VM
368 /* If the following value is not zero, the cpu unit is present in a
369 `exclusion_set' or in right part of a `presence_set',
370 `final_presence_set', `absence_set', and
371 `final_absence_set'define_query_cpu_unit. */
372 char in_set_p;
fae15c93
VM
373};
374
375/* This describes define_bypass (see file rtl.def). */
376struct bypass_decl
377{
378 int latency;
1fb49ce7
ZW
379 const char *out_insn_name;
380 const char *in_insn_name;
381 const char *bypass_guard_name;
fae15c93
VM
382
383 /* The following fields are defined by checker. */
384
385 /* output and input insns of given bypass. */
386 struct insn_reserv_decl *out_insn_reserv;
387 struct insn_reserv_decl *in_insn_reserv;
388 /* The next bypass for given output insn. */
389 struct bypass_decl *next;
390};
391
392/* This describes define_automaton (see file rtl.def). */
393struct automaton_decl
394{
1fb49ce7 395 const char *name;
fae15c93
VM
396
397 /* The following fields are defined by automaton generator. */
398
399 /* The following field value is nonzero if the automaton is used in
400 an regexp definition. */
401 char automaton_is_used;
402
403 /* The following fields are defined by checker. */
404
405 /* The following field value is the corresponding automaton. This
406 field is not NULL only if the automaton is present in unit
407 declarations and the automatic partition on automata is not
408 used. */
409 automaton_t corresponding_automaton;
410};
411
30028c85
VM
412/* This describes exclusion relations: exclusion_set (see file
413 rtl.def). */
414struct excl_rel_decl
fae15c93 415{
30028c85 416 int all_names_num;
fae15c93
VM
417 int first_list_length;
418 char *names [1];
419};
420
30028c85
VM
421/* This describes unit relations: [final_]presence_set or
422 [final_]absence_set (see file rtl.def). */
423struct unit_pattern_rel_decl
424{
425 int final_p;
426 int names_num;
427 int patterns_num;
428 char **names;
429 char ***patterns;
430};
431
fae15c93
VM
432/* This describes define_reservation (see file rtl.def). */
433struct reserv_decl
434{
1fb49ce7 435 const char *name;
fae15c93
VM
436 regexp_t regexp;
437
438 /* The following fields are defined by checker. */
439
440 /* The following field value is nonzero if the unit is used in an
441 regexp. */
442 char reserv_is_used;
443 /* The following field is used to check up cycle in expression
444 definition. */
445 int loop_pass_num;
446};
447
96e13905 448/* This describes define_insn_reservation (see file rtl.def). */
fae15c93
VM
449struct insn_reserv_decl
450{
451 rtx condexp;
452 int default_latency;
453 regexp_t regexp;
1fb49ce7 454 const char *name;
fae15c93
VM
455
456 /* The following fields are defined by checker. */
457
458 /* The following field value is order number (0, 1, ...) of given
459 insn. */
460 int insn_num;
461 /* The following field value is list of bypasses in which given insn
462 is output insn. */
463 struct bypass_decl *bypass_list;
464
465 /* The following fields are defined by automaton generator. */
466
467 /* The following field is the insn regexp transformed that
468 the regexp has not optional regexp, repetition regexp, and an
469 reservation name (i.e. reservation identifiers are changed by the
470 corresponding regexp) and all alternations are the topest level
471 of the regexp. The value can be NULL only if it is special
472 insn `cycle advancing'. */
473 regexp_t transformed_regexp;
474 /* The following field value is list of arcs marked given
96e13905 475 insn. The field is used in transformation NDFA -> DFA. */
fae15c93
VM
476 arc_t arcs_marked_by_insn;
477 /* The two following fields are used during minimization of a finite state
478 automaton. */
479 /* The field value is number of equivalence class of state into
480 which arc marked by given insn enters from a state (fixed during
481 an automaton minimization). */
482 int equiv_class_num;
fae15c93 483 /* The following member value is the list to automata which can be
deb09eff 484 changed by the insn issue. */
fae15c93
VM
485 automata_list_el_t important_automata_list;
486 /* The following member is used to process insn once for output. */
487 int processed_p;
488};
489
490/* This contains a declaration mentioned above. */
491struct decl
492{
493 /* What node in the union? */
494 enum decl_mode mode;
495 pos_t pos;
496 union
497 {
498 struct unit_decl unit;
499 struct bypass_decl bypass;
500 struct automaton_decl automaton;
30028c85
VM
501 struct excl_rel_decl excl;
502 struct unit_pattern_rel_decl presence;
503 struct unit_pattern_rel_decl absence;
fae15c93
VM
504 struct reserv_decl reserv;
505 struct insn_reserv_decl insn_reserv;
506 } decl;
507};
508
509/* The following structures represent parsed reservation strings. */
510enum regexp_mode
511{
512 rm_unit,
513 rm_reserv,
514 rm_nothing,
515 rm_sequence,
516 rm_repeat,
517 rm_allof,
518 rm_oneof
519};
520
521/* Cpu unit in reservation. */
522struct unit_regexp
523{
1fb49ce7 524 const char *name;
deb09eff 525 unit_decl_t unit_decl;
fae15c93
VM
526};
527
528/* Define_reservation in a reservation. */
529struct reserv_regexp
530{
1fb49ce7 531 const char *name;
fae15c93
VM
532 struct reserv_decl *reserv_decl;
533};
534
535/* Absence of reservation (represented by string `nothing'). */
536struct nothing_regexp
537{
538 /* This used to be empty but ISO C doesn't allow that. */
539 char unused;
540};
541
542/* Representation of reservations separated by ',' (see file
543 rtl.def). */
544struct sequence_regexp
545{
546 int regexps_num;
547 regexp_t regexps [1];
548};
549
550/* Representation of construction `repeat' (see file rtl.def). */
551struct repeat_regexp
552{
553 int repeat_num;
554 regexp_t regexp;
555};
556
557/* Representation of reservations separated by '+' (see file
558 rtl.def). */
559struct allof_regexp
560{
561 int regexps_num;
562 regexp_t regexps [1];
563};
564
565/* Representation of reservations separated by '|' (see file
566 rtl.def). */
567struct oneof_regexp
568{
569 int regexps_num;
570 regexp_t regexps [1];
571};
572
573/* Representation of a reservation string. */
574struct regexp
575{
576 /* What node in the union? */
577 enum regexp_mode mode;
578 pos_t pos;
579 union
580 {
581 struct unit_regexp unit;
582 struct reserv_regexp reserv;
583 struct nothing_regexp nothing;
584 struct sequence_regexp sequence;
585 struct repeat_regexp repeat;
586 struct allof_regexp allof;
587 struct oneof_regexp oneof;
588 } regexp;
589};
590
96e13905 591/* Represents description of pipeline hazard description based on
fae15c93
VM
592 NDFA. */
593struct description
594{
595 int decls_num;
596
597 /* The following fields are defined by checker. */
598
599 /* The following fields values are correspondingly number of all
600 units, query units, and insns in the description. */
601 int units_num;
602 int query_units_num;
603 int insns_num;
604 /* The following field value is max length (in cycles) of
605 reservations of insns. The field value is defined only for
606 correct programs. */
607 int max_insn_reserv_cycles;
608
609 /* The following fields are defined by automaton generator. */
610
611 /* The following field value is the first automaton. */
612 automaton_t first_automaton;
613
614 /* The following field is created by pipeline hazard parser and
615 contains all declarations. We allocate additional entry for
616 special insn "cycle advancing" which is added by the automaton
617 generator. */
618 decl_t decls [1];
619};
620
621
fae15c93
VM
622/* The following nodes are created in automaton checker. */
623
30028c85
VM
624/* The following nodes represent exclusion set for cpu units. Each
625 element is accessed through only one excl_list. */
fae15c93
VM
626struct unit_set_el
627{
deb09eff 628 unit_decl_t unit_decl;
fae15c93
VM
629 unit_set_el_t next_unit_set_el;
630};
631
30028c85
VM
632/* The following nodes represent presence or absence pattern for cpu
633 units. Each element is accessed through only one presence_list or
634 absence_list. */
635struct pattern_set_el
636{
637 /* The number of units in unit_decls. */
638 int units_num;
639 /* The units forming the pattern. */
640 struct unit_decl **unit_decls;
641 pattern_set_el_t next_pattern_set_el;
642};
fae15c93
VM
643
644
645/* The following nodes are created in automaton generator. */
646
30028c85
VM
647
648/* The following nodes represent presence or absence pattern for cpu
649 units. Each element is accessed through only one element of
650 unit_presence_set_table or unit_absence_set_table. */
651struct pattern_reserv
652{
653 reserv_sets_t reserv;
654 pattern_reserv_t next_pattern_reserv;
655};
656
fae15c93
VM
657/* The following node type describes state automaton. The state may
658 be deterministic or non-deterministic. Non-deterministic state has
659 several component states which represent alternative cpu units
660 reservations. The state also is used for describing a
661 deterministic reservation of automaton insn. */
662struct state
663{
664 /* The following member value is nonzero if there is a transition by
665 cycle advancing. */
666 int new_cycle_p;
667 /* The following field is list of processor unit reservations on
668 each cycle. */
669 reserv_sets_t reservs;
670 /* The following field is unique number of given state between other
671 states. */
672 int unique_num;
673 /* The following field value is automaton to which given state
674 belongs. */
675 automaton_t automaton;
676 /* The following field value is the first arc output from given
677 state. */
678 arc_t first_out_arc;
b6bbd675 679 unsigned int num_out_arcs;
fae15c93
VM
680 /* The following field is used to form NDFA. */
681 char it_was_placed_in_stack_for_NDFA_forming;
682 /* The following field is used to form DFA. */
683 char it_was_placed_in_stack_for_DFA_forming;
30028c85
VM
684 /* The following field is used to transform NDFA to DFA and DFA
685 minimization. The field value is not NULL if the state is a
686 compound state. In this case the value of field `unit_sets_list'
687 is NULL. All states in the list are in the hash table. The list
688 is formed through field `next_sorted_alt_state'. We should
689 support only one level of nesting state. */
fae15c93
VM
690 alt_state_t component_states;
691 /* The following field is used for passing graph of states. */
692 int pass_num;
693 /* The list of states belonging to one equivalence class is formed
694 with the aid of the following field. */
695 state_t next_equiv_class_state;
696 /* The two following fields are used during minimization of a finite
697 state automaton. */
698 int equiv_class_num_1, equiv_class_num_2;
699 /* The following field is used during minimization of a finite state
700 automaton. The field value is state corresponding to equivalence
701 class to which given state belongs. */
702 state_t equiv_class_state;
b6bbd675 703 unsigned int *presence_signature;
fae15c93
VM
704 /* The following field value is the order number of given state.
705 The states in final DFA is enumerated with the aid of the
706 following field. */
707 int order_state_num;
708 /* This member is used for passing states for searching minimal
709 delay time. */
710 int state_pass_num;
711 /* The following member is used to evaluate min issue delay of insn
712 for a state. */
713 int min_insn_issue_delay;
fae15c93
VM
714};
715
fae15c93
VM
716/* Automaton arc. */
717struct arc
718{
719 /* The following field refers for the state into which given arc
720 enters. */
721 state_t to_state;
722 /* The following field describes that the insn issue (with cycle
723 advancing for special insn `cycle advancing' and without cycle
724 advancing for others) makes transition from given state to
725 another given state. */
726 ainsn_t insn;
727 /* The following field value is the next arc output from the same
728 state. */
729 arc_t next_out_arc;
730 /* List of arcs marked given insn is formed with the following
96e13905 731 field. The field is used in transformation NDFA -> DFA. */
fae15c93 732 arc_t next_arc_marked_by_insn;
fae15c93
VM
733};
734
735/* The following node type describes a deterministic alternative in
736 non-deterministic state which characterizes cpu unit reservations
737 of automaton insn or which is part of NDFA. */
738struct alt_state
739{
fbe5a4a6 740 /* The following field is a deterministic state which characterizes
fae15c93
VM
741 unit reservations of the instruction. */
742 state_t state;
743 /* The following field refers to the next state which characterizes
744 unit reservations of the instruction. */
745 alt_state_t next_alt_state;
746 /* The following field refers to the next state in sorted list. */
747 alt_state_t next_sorted_alt_state;
748};
749
750/* The following node type describes insn of automaton. They are
751 labels of FA arcs. */
752struct ainsn
753{
754 /* The following field value is the corresponding insn declaration
755 of description. */
756 struct insn_reserv_decl *insn_reserv_decl;
757 /* The following field value is the next insn declaration for an
758 automaton. */
759 ainsn_t next_ainsn;
760 /* The following field is states which characterize automaton unit
761 reservations of the instruction. The value can be NULL only if it
762 is special insn `cycle advancing'. */
763 alt_state_t alt_states;
764 /* The following field is sorted list of states which characterize
765 automaton unit reservations of the instruction. The value can be
766 NULL only if it is special insn `cycle advancing'. */
767 alt_state_t sorted_alt_states;
768 /* The following field refers the next automaton insn with
769 the same reservations. */
770 ainsn_t next_same_reservs_insn;
771 /* The following field is flag of the first automaton insn with the
772 same reservations in the declaration list. Only arcs marked such
773 insn is present in the automaton. This significantly decreases
774 memory requirements especially when several automata are
775 formed. */
776 char first_insn_with_same_reservs;
777 /* The following member has nonzero value if there is arc from state of
778 the automaton marked by the ainsn. */
779 char arc_exists_p;
e0a2f705 780 /* Cyclic list of insns of an equivalence class is formed with the
fae15c93
VM
781 aid of the following field. */
782 ainsn_t next_equiv_class_insn;
783 /* The following field value is nonzero if the insn declaration is
784 the first insn declaration with given equivalence number. */
56ae04af 785 char first_ainsn_with_given_equivalence_num;
fae15c93
VM
786 /* The following field is number of class of equivalence of insns.
787 It is necessary because many insns may be equivalent with the
788 point of view of pipeline hazards. */
789 int insn_equiv_class_num;
790 /* The following member value is TRUE if there is an arc in the
791 automaton marked by the insn into another state. In other
792 words, the insn can change the state of the automaton. */
793 int important_p;
794};
795
fbe5a4a6 796/* The following describes an automaton for PHR. */
fae15c93
VM
797struct automaton
798{
799 /* The following field value is the list of insn declarations for
800 given automaton. */
801 ainsn_t ainsn_list;
802 /* The following field value is the corresponding automaton
803 declaration. This field is not NULL only if the automatic
804 partition on automata is not used. */
805 struct automaton_decl *corresponding_automaton_decl;
806 /* The following field value is the next automaton. */
807 automaton_t next_automaton;
808 /* The following field is start state of FA. There are not unit
809 reservations in the state. */
810 state_t start_state;
811 /* The following field value is number of equivalence classes of
812 insns (see field `insn_equiv_class_num' in
813 `insn_reserv_decl'). */
814 int insn_equiv_classes_num;
815 /* The following field value is number of states of final DFA. */
816 int achieved_states_num;
817 /* The following field value is the order number (0, 1, ...) of
818 given automaton. */
819 int automaton_order_num;
820 /* The following fields contain statistics information about
821 building automaton. */
822 int NDFA_states_num, DFA_states_num;
823 /* The following field value is defined only if minimization of DFA
824 is used. */
825 int minimal_DFA_states_num;
826 int NDFA_arcs_num, DFA_arcs_num;
827 /* The following field value is defined only if minimization of DFA
828 is used. */
829 int minimal_DFA_arcs_num;
8c94f366
ZW
830 /* The following member refers for two table state x ainsn -> int.
831 ??? Above sentence is incomprehensible. */
fae15c93 832 state_ainsn_table_t trans_table;
fae15c93
VM
833 /* The following member value is maximal value of min issue delay
834 for insns of the automaton. */
835 int max_min_delay;
836 /* Usually min issue delay is small and we can place several (2, 4,
837 8) elements in one vector element. So the compression factor can
838 be 1 (no compression), 2, 4, 8. */
839 int min_issue_delay_table_compression_factor;
5f2f0edd
ZW
840 /* Total number of locked states in this automaton. */
841 int locked_states;
fae15c93
VM
842};
843
844/* The following is the element of the list of automata. */
845struct automata_list_el
846{
847 /* The automaton itself. */
848 automaton_t automaton;
849 /* The next automata set element. */
850 automata_list_el_t next_automata_list_el;
851};
852
853/* The following structure describes a table state X ainsn -> int(>= 0). */
854struct state_ainsn_table
855{
856 /* Automaton to which given table belongs. */
857 automaton_t automaton;
858 /* The following tree vectors for comb vector implementation of the
859 table. */
860 vla_hwint_t comb_vect;
861 vla_hwint_t check_vect;
862 vla_hwint_t base_vect;
863 /* This is simple implementation of the table. */
864 vla_hwint_t full_vect;
865 /* Minimal and maximal values of the previous vectors. */
866 int min_comb_vect_el_value, max_comb_vect_el_value;
867 int min_base_vect_el_value, max_base_vect_el_value;
868};
869
4005971c
VM
870/* Macros to access members of unions. Use only them for access to
871 union members of declarations and regexps. */
872
873#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
874
875#define DECL_UNIT(d) __extension__ \
813674e0 876(({ struct decl *const _decl = (d); \
4005971c
VM
877 if (_decl->mode != dm_unit) \
878 decl_mode_check_failed (_decl->mode, "dm_unit", \
879 __FILE__, __LINE__, __FUNCTION__); \
880 &(_decl)->decl.unit; }))
881
882#define DECL_BYPASS(d) __extension__ \
813674e0 883(({ struct decl *const _decl = (d); \
4005971c
VM
884 if (_decl->mode != dm_bypass) \
885 decl_mode_check_failed (_decl->mode, "dm_bypass", \
886 __FILE__, __LINE__, __FUNCTION__); \
887 &(_decl)->decl.bypass; }))
888
889#define DECL_AUTOMATON(d) __extension__ \
3d7aafde 890(({ struct decl *const _decl = (d); \
4005971c
VM
891 if (_decl->mode != dm_automaton) \
892 decl_mode_check_failed (_decl->mode, "dm_automaton", \
893 __FILE__, __LINE__, __FUNCTION__); \
894 &(_decl)->decl.automaton; }))
895
896#define DECL_EXCL(d) __extension__ \
3d7aafde 897(({ struct decl *const _decl = (d); \
4005971c
VM
898 if (_decl->mode != dm_excl) \
899 decl_mode_check_failed (_decl->mode, "dm_excl", \
900 __FILE__, __LINE__, __FUNCTION__); \
901 &(_decl)->decl.excl; }))
902
903#define DECL_PRESENCE(d) __extension__ \
813674e0 904(({ struct decl *const _decl = (d); \
4005971c
VM
905 if (_decl->mode != dm_presence) \
906 decl_mode_check_failed (_decl->mode, "dm_presence", \
907 __FILE__, __LINE__, __FUNCTION__); \
908 &(_decl)->decl.presence; }))
909
910#define DECL_ABSENCE(d) __extension__ \
3d7aafde 911(({ struct decl *const _decl = (d); \
4005971c
VM
912 if (_decl->mode != dm_absence) \
913 decl_mode_check_failed (_decl->mode, "dm_absence", \
914 __FILE__, __LINE__, __FUNCTION__); \
915 &(_decl)->decl.absence; }))
916
917#define DECL_RESERV(d) __extension__ \
813674e0 918(({ struct decl *const _decl = (d); \
4005971c 919 if (_decl->mode != dm_reserv) \
813674e0 920 decl_mode_check_failed (_decl->mode, "dm_reserv", \
4005971c
VM
921 __FILE__, __LINE__, __FUNCTION__); \
922 &(_decl)->decl.reserv; }))
923
924#define DECL_INSN_RESERV(d) __extension__ \
3d7aafde 925(({ struct decl *const _decl = (d); \
4005971c
VM
926 if (_decl->mode != dm_insn_reserv) \
927 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
928 __FILE__, __LINE__, __FUNCTION__); \
929 &(_decl)->decl.insn_reserv; }))
930
3d7aafde
AJ
931static const char *decl_name (enum decl_mode);
932static void decl_mode_check_failed (enum decl_mode, const char *,
82e5a12a
KG
933 const char *, int, const char *)
934 ATTRIBUTE_NORETURN;
4005971c
VM
935
936/* Return string representation of declaration mode MODE. */
937static const char *
3d7aafde 938decl_name (enum decl_mode mode)
4005971c
VM
939{
940 static char str [100];
941
942 if (mode == dm_unit)
943 return "dm_unit";
944 else if (mode == dm_bypass)
945 return "dm_bypass";
946 else if (mode == dm_automaton)
947 return "dm_automaton";
948 else if (mode == dm_excl)
949 return "dm_excl";
950 else if (mode == dm_presence)
951 return "dm_presence";
952 else if (mode == dm_absence)
953 return "dm_absence";
954 else if (mode == dm_reserv)
955 return "dm_reserv";
956 else if (mode == dm_insn_reserv)
957 return "dm_insn_reserv";
958 else
959 sprintf (str, "unknown (%d)", (int) mode);
960 return str;
961}
962
963/* The function prints message about unexpected declaration and finish
964 the program. */
965static void
3d7aafde
AJ
966decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
967 const char *file, int line, const char *func)
4005971c
VM
968{
969 fprintf
970 (stderr,
971 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
972 file, line, func, expected_mode_str, decl_name (mode));
973 exit (1);
974}
975
976
977#define REGEXP_UNIT(r) __extension__ \
813674e0 978(({ struct regexp *const _regexp = (r); \
4005971c
VM
979 if (_regexp->mode != rm_unit) \
980 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
981 __FILE__, __LINE__, __FUNCTION__); \
982 &(_regexp)->regexp.unit; }))
983
984#define REGEXP_RESERV(r) __extension__ \
813674e0 985(({ struct regexp *const _regexp = (r); \
4005971c
VM
986 if (_regexp->mode != rm_reserv) \
987 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
988 __FILE__, __LINE__, __FUNCTION__); \
989 &(_regexp)->regexp.reserv; }))
990
991#define REGEXP_SEQUENCE(r) __extension__ \
813674e0 992(({ struct regexp *const _regexp = (r); \
4005971c
VM
993 if (_regexp->mode != rm_sequence) \
994 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
995 __FILE__, __LINE__, __FUNCTION__); \
996 &(_regexp)->regexp.sequence; }))
997
998#define REGEXP_REPEAT(r) __extension__ \
813674e0 999(({ struct regexp *const _regexp = (r); \
4005971c
VM
1000 if (_regexp->mode != rm_repeat) \
1001 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1002 __FILE__, __LINE__, __FUNCTION__); \
1003 &(_regexp)->regexp.repeat; }))
1004
1005#define REGEXP_ALLOF(r) __extension__ \
813674e0 1006(({ struct regexp *const _regexp = (r); \
4005971c
VM
1007 if (_regexp->mode != rm_allof) \
1008 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1009 __FILE__, __LINE__, __FUNCTION__); \
1010 &(_regexp)->regexp.allof; }))
1011
1012#define REGEXP_ONEOF(r) __extension__ \
813674e0 1013(({ struct regexp *const _regexp = (r); \
4005971c
VM
1014 if (_regexp->mode != rm_oneof) \
1015 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1016 __FILE__, __LINE__, __FUNCTION__); \
1017 &(_regexp)->regexp.oneof; }))
1018
3d7aafde
AJ
1019static const char *regexp_name (enum regexp_mode);
1020static void regexp_mode_check_failed (enum regexp_mode, const char *,
1021 const char *, int,
82e5a12a 1022 const char *) ATTRIBUTE_NORETURN;
4005971c
VM
1023
1024
1025/* Return string representation of regexp mode MODE. */
1026static const char *
3d7aafde 1027regexp_name (enum regexp_mode mode)
4005971c 1028{
b2d59f6f
NS
1029 switch (mode)
1030 {
1031 case rm_unit:
1032 return "rm_unit";
1033 case rm_reserv:
1034 return "rm_reserv";
1035 case rm_nothing:
1036 return "rm_nothing";
1037 case rm_sequence:
1038 return "rm_sequence";
1039 case rm_repeat:
1040 return "rm_repeat";
1041 case rm_allof:
1042 return "rm_allof";
1043 case rm_oneof:
1044 return "rm_oneof";
1045 default:
1046 gcc_unreachable ();
1047 }
4005971c
VM
1048}
1049
1050/* The function prints message about unexpected regexp and finish the
1051 program. */
1052static void
3d7aafde
AJ
1053regexp_mode_check_failed (enum regexp_mode mode,
1054 const char *expected_mode_str,
1055 const char *file, int line, const char *func)
4005971c
VM
1056{
1057 fprintf
1058 (stderr,
1059 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1060 file, line, func, expected_mode_str, regexp_name (mode));
1061 exit (1);
1062}
1063
1064#else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1065
1066#define DECL_UNIT(d) (&(d)->decl.unit)
1067#define DECL_BYPASS(d) (&(d)->decl.bypass)
1068#define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1069#define DECL_EXCL(d) (&(d)->decl.excl)
1070#define DECL_PRESENCE(d) (&(d)->decl.presence)
1071#define DECL_ABSENCE(d) (&(d)->decl.absence)
1072#define DECL_RESERV(d) (&(d)->decl.reserv)
1073#define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1074
1075#define REGEXP_UNIT(r) (&(r)->regexp.unit)
1076#define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1077#define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1078#define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1079#define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1080#define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1081
1082#endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1083
fae15c93
VM
1084/* Create IR structure (node). */
1085static void *
3d7aafde 1086create_node (size_t size)
fae15c93
VM
1087{
1088 void *result;
1089
1090 obstack_blank (&irp, size);
1091 result = obstack_base (&irp);
1092 obstack_finish (&irp);
1093 /* Default values of members are NULL and zero. */
1094 memset (result, 0, size);
1095 return result;
1096}
1097
1098/* Copy IR structure (node). */
1099static void *
3d7aafde 1100copy_node (const void *from, size_t size)
fae15c93 1101{
813674e0 1102 void *const result = create_node (size);
fae15c93
VM
1103 memcpy (result, from, size);
1104 return result;
1105}
1106
1107/* The function checks that NAME does not contain quotes (`"'). */
1fb49ce7
ZW
1108static const char *
1109check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
fae15c93 1110{
813674e0 1111 const char *str;
fae15c93
VM
1112
1113 for (str = name; *str != '\0'; str++)
1114 if (*str == '\"')
1115 error ("Name `%s' contains quotes", name);
1116 return name;
1117}
1118
96e13905 1119/* Pointers to all declarations during IR generation are stored in the
fae15c93 1120 following. */
1fb49ce7 1121static VEC(decl_t,heap) *decls;
fae15c93 1122
e0a2f705 1123/* Given a pointer to a (char *) and a separator, return an alloc'ed
fae15c93
VM
1124 string containing the next separated element, taking parentheses
1125 into account if PAR_FLAG has nonzero value. Advance the pointer to
1126 after the string scanned, or the end-of-string. Return NULL if at
1127 end of string. */
1128static char *
1fb49ce7 1129next_sep_el (const char **pstr, int sep, int par_flag)
fae15c93
VM
1130{
1131 char *out_str;
1fb49ce7 1132 const char *p;
fae15c93
VM
1133 int pars_num;
1134 int n_spaces;
1135
1136 /* Remove leading whitespaces. */
1f8e4682 1137 while (ISSPACE ((int) **pstr))
fae15c93
VM
1138 (*pstr)++;
1139
1140 if (**pstr == '\0')
1141 return NULL;
1142
1143 n_spaces = 0;
1144 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1145 {
1146 if (par_flag && *p == '(')
1147 pars_num++;
1148 else if (par_flag && *p == ')')
1149 pars_num--;
1150 else if (pars_num == 0 && *p == sep)
1151 break;
1f8e4682 1152 if (pars_num == 0 && ISSPACE ((int) *p))
fae15c93
VM
1153 n_spaces++;
1154 else
1155 {
1156 for (; n_spaces != 0; n_spaces--)
1157 obstack_1grow (&irp, p [-n_spaces]);
1158 obstack_1grow (&irp, *p);
1159 }
1160 }
1161 obstack_1grow (&irp, '\0');
1162 out_str = obstack_base (&irp);
1163 obstack_finish (&irp);
1164
1165 *pstr = p;
1166 if (**pstr == sep)
1167 (*pstr)++;
1168
1169 return out_str;
1170}
1171
1172/* Given a string and a separator, return the number of separated
1173 elements in it, taking parentheses into account if PAR_FLAG has
fbe5a4a6 1174 nonzero value. Return 0 for the null string, -1 if parentheses is
fae15c93
VM
1175 not balanced. */
1176static int
1fb49ce7 1177n_sep_els (const char *s, int sep, int par_flag)
fae15c93
VM
1178{
1179 int n;
1180 int pars_num;
1181
1182 if (*s == '\0')
1183 return 0;
1184
1185 for (pars_num = 0, n = 1; *s; s++)
1186 if (par_flag && *s == '(')
1187 pars_num++;
1188 else if (par_flag && *s == ')')
1189 pars_num--;
1190 else if (pars_num == 0 && *s == sep)
1191 n++;
1192
1193 return (pars_num != 0 ? -1 : n);
1194}
1195
1196/* Given a string and a separator, return vector of strings which are
1197 elements in the string and number of elements through els_num.
30028c85
VM
1198 Take parentheses into account if PAREN_P has nonzero value. The
1199 function also inserts the end marker NULL at the end of vector.
e0bb17a8 1200 Return 0 for the null string, -1 if parentheses are not balanced. */
fae15c93 1201static char **
1fb49ce7 1202get_str_vect (const char *str, int *els_num, int sep, int paren_p)
fae15c93
VM
1203{
1204 int i;
1205 char **vect;
1fb49ce7 1206 const char **pstr;
b2d59f6f 1207 char *trail;
fae15c93 1208
30028c85 1209 *els_num = n_sep_els (str, sep, paren_p);
fae15c93
VM
1210 if (*els_num <= 0)
1211 return NULL;
30028c85 1212 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
fae15c93
VM
1213 vect = (char **) obstack_base (&irp);
1214 obstack_finish (&irp);
1215 pstr = &str;
1216 for (i = 0; i < *els_num; i++)
30028c85 1217 vect [i] = next_sep_el (pstr, sep, paren_p);
b2d59f6f
NS
1218 trail = next_sep_el (pstr, sep, paren_p);
1219 gcc_assert (!trail);
30028c85 1220 vect [i] = NULL;
fae15c93
VM
1221 return vect;
1222}
1223
3d7aafde 1224/* Process a DEFINE_CPU_UNIT.
fae15c93
VM
1225
1226 This gives information about a unit contained in CPU. We fill a
1227 struct unit_decl with information used later by `expand_automata'. */
8c94f366 1228static void
3d7aafde 1229gen_cpu_unit (rtx def)
fae15c93
VM
1230{
1231 decl_t decl;
1232 char **str_cpu_units;
1233 int vect_length;
1234 int i;
1235
1fb49ce7 1236 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
fae15c93
VM
1237 if (str_cpu_units == NULL)
1238 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1239 for (i = 0; i < vect_length; i++)
1240 {
1241 decl = create_node (sizeof (struct decl));
1242 decl->mode = dm_unit;
1243 decl->pos = 0;
4005971c 1244 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1fb49ce7 1245 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
4005971c 1246 DECL_UNIT (decl)->query_p = 0;
30028c85
VM
1247 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1248 DECL_UNIT (decl)->in_set_p = 0;
1fb49ce7 1249 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1250 }
1251}
1252
3d7aafde 1253/* Process a DEFINE_QUERY_CPU_UNIT.
fae15c93
VM
1254
1255 This gives information about a unit contained in CPU. We fill a
1256 struct unit_decl with information used later by `expand_automata'. */
8c94f366 1257static void
3d7aafde 1258gen_query_cpu_unit (rtx def)
fae15c93
VM
1259{
1260 decl_t decl;
1261 char **str_cpu_units;
1262 int vect_length;
1263 int i;
1264
1fb49ce7 1265 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
30028c85 1266 FALSE);
fae15c93
VM
1267 if (str_cpu_units == NULL)
1268 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1269 for (i = 0; i < vect_length; i++)
1270 {
1271 decl = create_node (sizeof (struct decl));
1272 decl->mode = dm_unit;
1273 decl->pos = 0;
4005971c 1274 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1fb49ce7 1275 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
4005971c 1276 DECL_UNIT (decl)->query_p = 1;
1fb49ce7 1277 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1278 }
1279}
1280
3d7aafde 1281/* Process a DEFINE_BYPASS.
fae15c93
VM
1282
1283 This gives information about a unit contained in the CPU. We fill
1284 in a struct bypass_decl with information used later by
1285 `expand_automata'. */
8c94f366 1286static void
3d7aafde 1287gen_bypass (rtx def)
fae15c93
VM
1288{
1289 decl_t decl;
1290 char **out_insns;
1291 int out_length;
1292 char **in_insns;
1293 int in_length;
1294 int i, j;
1295
1fb49ce7 1296 out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
fae15c93
VM
1297 if (out_insns == NULL)
1298 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1fb49ce7 1299 in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
fae15c93
VM
1300 if (in_insns == NULL)
1301 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1302 for (i = 0; i < out_length; i++)
1303 for (j = 0; j < in_length; j++)
1304 {
1305 decl = create_node (sizeof (struct decl));
1306 decl->mode = dm_bypass;
1307 decl->pos = 0;
4005971c
VM
1308 DECL_BYPASS (decl)->latency = XINT (def, 0);
1309 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1310 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1fb49ce7
ZW
1311 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
1312 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1313 }
1314}
1315
3d7aafde 1316/* Process an EXCLUSION_SET.
fae15c93
VM
1317
1318 This gives information about a cpu unit conflicts. We fill a
30028c85 1319 struct excl_rel_decl (excl) with information used later by
fae15c93 1320 `expand_automata'. */
8c94f366 1321static void
3d7aafde 1322gen_excl_set (rtx def)
fae15c93
VM
1323{
1324 decl_t decl;
1325 char **first_str_cpu_units;
1326 char **second_str_cpu_units;
1327 int first_vect_length;
1328 int length;
1329 int i;
1330
1331 first_str_cpu_units
1fb49ce7 1332 = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
fae15c93
VM
1333 if (first_str_cpu_units == NULL)
1334 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1fb49ce7 1335 second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
30028c85 1336 FALSE);
fae15c93
VM
1337 if (second_str_cpu_units == NULL)
1338 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1339 length += first_vect_length;
1340 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1341 decl->mode = dm_excl;
1342 decl->pos = 0;
30028c85 1343 DECL_EXCL (decl)->all_names_num = length;
4005971c 1344 DECL_EXCL (decl)->first_list_length = first_vect_length;
fae15c93
VM
1345 for (i = 0; i < length; i++)
1346 if (i < first_vect_length)
4005971c 1347 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
fae15c93 1348 else
4005971c
VM
1349 DECL_EXCL (decl)->names [i]
1350 = second_str_cpu_units [i - first_vect_length];
1fb49ce7 1351 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1352}
1353
30028c85
VM
1354/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1355 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
fae15c93
VM
1356
1357 This gives information about a cpu unit reservation requirements.
30028c85
VM
1358 We fill a struct unit_pattern_rel_decl with information used later
1359 by `expand_automata'. */
1360static void
3d7aafde 1361gen_presence_absence_set (rtx def, int presence_p, int final_p)
fae15c93
VM
1362{
1363 decl_t decl;
30028c85 1364 char **str_cpu_units;
1fb49ce7 1365 char **str_pattern_lists;
30028c85
VM
1366 char ***str_patterns;
1367 int cpu_units_length;
fae15c93 1368 int length;
30028c85 1369 int patterns_length;
fae15c93
VM
1370 int i;
1371
1fb49ce7 1372 str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
30028c85
VM
1373 FALSE);
1374 if (str_cpu_units == NULL)
1375 fatal ((presence_p
1376 ? (final_p
1377 ? "invalid first string `%s' in final_presence_set"
1378 : "invalid first string `%s' in presence_set")
1379 : (final_p
1380 ? "invalid first string `%s' in final_absence_set"
1381 : "invalid first string `%s' in absence_set")),
1382 XSTR (def, 0));
1fb49ce7
ZW
1383 str_pattern_lists = get_str_vect (XSTR (def, 1),
1384 &patterns_length, ',', FALSE);
1385 if (str_pattern_lists == NULL)
30028c85
VM
1386 fatal ((presence_p
1387 ? (final_p
1388 ? "invalid second string `%s' in final_presence_set"
1389 : "invalid second string `%s' in presence_set")
1390 : (final_p
1391 ? "invalid second string `%s' in final_absence_set"
1392 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1fb49ce7 1393 str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
30028c85
VM
1394 for (i = 0; i < patterns_length; i++)
1395 {
1fb49ce7
ZW
1396 str_patterns [i] = get_str_vect (str_pattern_lists [i],
1397 &length, ' ', FALSE);
b2d59f6f 1398 gcc_assert (str_patterns [i]);
30028c85
VM
1399 }
1400 decl = create_node (sizeof (struct decl));
fae15c93 1401 decl->pos = 0;
30028c85
VM
1402 if (presence_p)
1403 {
1404 decl->mode = dm_presence;
1405 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1406 DECL_PRESENCE (decl)->names = str_cpu_units;
1407 DECL_PRESENCE (decl)->patterns = str_patterns;
1408 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1409 DECL_PRESENCE (decl)->final_p = final_p;
1410 }
1411 else
1412 {
1413 decl->mode = dm_absence;
1414 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1415 DECL_ABSENCE (decl)->names = str_cpu_units;
1416 DECL_ABSENCE (decl)->patterns = str_patterns;
1417 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1418 DECL_ABSENCE (decl)->final_p = final_p;
1419 }
1fb49ce7 1420 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1421}
1422
3d7aafde
AJ
1423/* Process a PRESENCE_SET.
1424
30028c85
VM
1425 This gives information about a cpu unit reservation requirements.
1426 We fill a struct unit_pattern_rel_decl (presence) with information
1427 used later by `expand_automata'. */
8c94f366 1428static void
3d7aafde 1429gen_presence_set (rtx def)
30028c85
VM
1430{
1431 gen_presence_absence_set (def, TRUE, FALSE);
1432}
3d7aafde
AJ
1433
1434/* Process a FINAL_PRESENCE_SET.
30028c85
VM
1435
1436 This gives information about a cpu unit reservation requirements.
1437 We fill a struct unit_pattern_rel_decl (presence) with information
1438 used later by `expand_automata'. */
8c94f366 1439static void
3d7aafde 1440gen_final_presence_set (rtx def)
30028c85
VM
1441{
1442 gen_presence_absence_set (def, TRUE, TRUE);
1443}
3d7aafde 1444
30028c85 1445/* Process an ABSENCE_SET.
fae15c93
VM
1446
1447 This gives information about a cpu unit reservation requirements.
30028c85
VM
1448 We fill a struct unit_pattern_rel_decl (absence) with information
1449 used later by `expand_automata'. */
8c94f366 1450static void
3d7aafde 1451gen_absence_set (rtx def)
fae15c93 1452{
30028c85 1453 gen_presence_absence_set (def, FALSE, FALSE);
fae15c93 1454}
3d7aafde 1455
30028c85 1456/* Process a FINAL_ABSENCE_SET.
fae15c93 1457
30028c85
VM
1458 This gives information about a cpu unit reservation requirements.
1459 We fill a struct unit_pattern_rel_decl (absence) with information
1460 used later by `expand_automata'. */
8c94f366 1461static void
3d7aafde 1462gen_final_absence_set (rtx def)
30028c85
VM
1463{
1464 gen_presence_absence_set (def, FALSE, TRUE);
1465}
3d7aafde
AJ
1466
1467/* Process a DEFINE_AUTOMATON.
fae15c93
VM
1468
1469 This gives information about a finite state automaton used for
1470 recognizing pipeline hazards. We fill a struct automaton_decl
1471 with information used later by `expand_automata'. */
8c94f366 1472static void
3d7aafde 1473gen_automaton (rtx def)
fae15c93
VM
1474{
1475 decl_t decl;
1476 char **str_automata;
1477 int vect_length;
1478 int i;
1479
1fb49ce7 1480 str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
fae15c93
VM
1481 if (str_automata == NULL)
1482 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1483 for (i = 0; i < vect_length; i++)
1484 {
1485 decl = create_node (sizeof (struct decl));
1486 decl->mode = dm_automaton;
1487 decl->pos = 0;
4005971c 1488 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1fb49ce7 1489 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1490 }
1491}
1492
3d7aafde 1493/* Process an AUTOMATA_OPTION.
fae15c93
VM
1494
1495 This gives information how to generate finite state automaton used
1496 for recognizing pipeline hazards. */
8c94f366 1497static void
3d7aafde 1498gen_automata_option (rtx def)
fae15c93 1499{
703ad42b 1500 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
fae15c93 1501 no_minimization_flag = 1;
703ad42b 1502 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
e3c8eb86 1503 time_flag = 1;
df1133a6
BE
1504 else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
1505 stats_flag = 1;
703ad42b 1506 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
e3c8eb86 1507 v_flag = 1;
703ad42b 1508 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
fae15c93 1509 w_flag = 1;
703ad42b 1510 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
fae15c93 1511 ndfa_flag = 1;
dfa849f3
VM
1512 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1513 progress_flag = 1;
fae15c93
VM
1514 else
1515 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1516}
1517
1518/* Name in reservation to denote absence reservation. */
1519#define NOTHING_NAME "nothing"
1520
1521/* The following string contains original reservation string being
1522 parsed. */
1fb49ce7 1523static const char *reserv_str;
fae15c93
VM
1524
1525/* Parse an element in STR. */
1526static regexp_t
1fb49ce7 1527gen_regexp_el (const char *str)
fae15c93
VM
1528{
1529 regexp_t regexp;
1fb49ce7 1530 char *dstr;
fae15c93
VM
1531 int len;
1532
1533 if (*str == '(')
1534 {
1535 len = strlen (str);
1536 if (str [len - 1] != ')')
1537 fatal ("garbage after ) in reservation `%s'", reserv_str);
1fb49ce7
ZW
1538 dstr = alloca (len - 1);
1539 memcpy (dstr, str + 1, len - 2);
1540 dstr [len-2] = '\0';
1541 regexp = gen_regexp_sequence (dstr);
fae15c93
VM
1542 }
1543 else if (strcmp (str, NOTHING_NAME) == 0)
1544 {
9c40feeb 1545 regexp = create_node (sizeof *regexp);
fae15c93
VM
1546 regexp->mode = rm_nothing;
1547 }
1548 else
1549 {
9c40feeb 1550 regexp = create_node (sizeof *regexp);
fae15c93 1551 regexp->mode = rm_unit;
4005971c 1552 REGEXP_UNIT (regexp)->name = str;
fae15c93
VM
1553 }
1554 return regexp;
1555}
1556
1557/* Parse construction `repeat' in STR. */
1558static regexp_t
1fb49ce7 1559gen_regexp_repeat (const char *str)
fae15c93
VM
1560{
1561 regexp_t regexp;
1562 regexp_t repeat;
1563 char **repeat_vect;
1564 int els_num;
1565 int i;
1566
30028c85 1567 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
fae15c93
VM
1568 if (repeat_vect == NULL)
1569 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1570 if (els_num > 1)
1571 {
1572 regexp = gen_regexp_el (repeat_vect [0]);
1573 for (i = 1; i < els_num; i++)
1574 {
1575 repeat = create_node (sizeof (struct regexp));
1576 repeat->mode = rm_repeat;
4005971c
VM
1577 REGEXP_REPEAT (repeat)->regexp = regexp;
1578 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
1579 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
fae15c93
VM
1580 fatal ("repetition `%s' <= 1 in reservation `%s'",
1581 str, reserv_str);
1582 regexp = repeat;
1583 }
1584 return regexp;
1585 }
1586 else
1587 return gen_regexp_el (str);
1588}
1589
1590/* Parse reservation STR which possibly contains separator '+'. */
1591static regexp_t
1fb49ce7 1592gen_regexp_allof (const char *str)
fae15c93
VM
1593{
1594 regexp_t allof;
1595 char **allof_vect;
1596 int els_num;
1597 int i;
1598
30028c85 1599 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
fae15c93
VM
1600 if (allof_vect == NULL)
1601 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1602 if (els_num > 1)
1603 {
1604 allof = create_node (sizeof (struct regexp)
1605 + sizeof (regexp_t) * (els_num - 1));
1606 allof->mode = rm_allof;
4005971c 1607 REGEXP_ALLOF (allof)->regexps_num = els_num;
fae15c93 1608 for (i = 0; i < els_num; i++)
4005971c 1609 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
fae15c93
VM
1610 return allof;
1611 }
1612 else
1613 return gen_regexp_repeat (str);
1614}
1615
1616/* Parse reservation STR which possibly contains separator '|'. */
1617static regexp_t
1fb49ce7 1618gen_regexp_oneof (const char *str)
fae15c93
VM
1619{
1620 regexp_t oneof;
1621 char **oneof_vect;
1622 int els_num;
1623 int i;
1624
30028c85 1625 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
fae15c93
VM
1626 if (oneof_vect == NULL)
1627 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1628 if (els_num > 1)
1629 {
1630 oneof = create_node (sizeof (struct regexp)
1631 + sizeof (regexp_t) * (els_num - 1));
1632 oneof->mode = rm_oneof;
4005971c 1633 REGEXP_ONEOF (oneof)->regexps_num = els_num;
fae15c93 1634 for (i = 0; i < els_num; i++)
4005971c 1635 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
fae15c93
VM
1636 return oneof;
1637 }
1638 else
1639 return gen_regexp_allof (str);
1640}
1641
1642/* Parse reservation STR which possibly contains separator ','. */
1643static regexp_t
1fb49ce7 1644gen_regexp_sequence (const char *str)
fae15c93
VM
1645{
1646 regexp_t sequence;
1647 char **sequence_vect;
1648 int els_num;
1649 int i;
1650
30028c85 1651 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
fae15c93
VM
1652 if (els_num > 1)
1653 {
1654 sequence = create_node (sizeof (struct regexp)
1655 + sizeof (regexp_t) * (els_num - 1));
1656 sequence->mode = rm_sequence;
4005971c 1657 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
fae15c93 1658 for (i = 0; i < els_num; i++)
4005971c 1659 REGEXP_SEQUENCE (sequence)->regexps [i]
fae15c93
VM
1660 = gen_regexp_oneof (sequence_vect [i]);
1661 return sequence;
1662 }
1663 else
1664 return gen_regexp_oneof (str);
1665}
1666
1667/* Parse construction reservation STR. */
1668static regexp_t
1fb49ce7 1669gen_regexp (const char *str)
fae15c93
VM
1670{
1671 reserv_str = str;
1672 return gen_regexp_sequence (str);;
1673}
1674
1675/* Process a DEFINE_RESERVATION.
1676
1677 This gives information about a reservation of cpu units. We fill
1678 in a struct reserv_decl with information used later by
1679 `expand_automata'. */
8c94f366 1680static void
3d7aafde 1681gen_reserv (rtx def)
fae15c93
VM
1682{
1683 decl_t decl;
1684
1685 decl = create_node (sizeof (struct decl));
1686 decl->mode = dm_reserv;
1687 decl->pos = 0;
1fb49ce7
ZW
1688 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
1689 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
1690 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1691}
1692
1693/* Process a DEFINE_INSN_RESERVATION.
1694
1695 This gives information about the reservation of cpu units by an
1696 insn. We fill a struct insn_reserv_decl with information used
1697 later by `expand_automata'. */
8c94f366 1698static void
3d7aafde 1699gen_insn_reserv (rtx def)
fae15c93
VM
1700{
1701 decl_t decl;
1702
1703 decl = create_node (sizeof (struct decl));
1704 decl->mode = dm_insn_reserv;
1705 decl->pos = 0;
4005971c 1706 DECL_INSN_RESERV (decl)->name
1fb49ce7 1707 = check_name (XSTR (def, 0), decl->pos);
4005971c
VM
1708 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
1709 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
1fb49ce7
ZW
1710 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
1711 VEC_safe_push (decl_t,heap, decls, decl);
fae15c93
VM
1712}
1713
1714\f
1715
1716/* The function evaluates hash value (0..UINT_MAX) of string. */
1717static unsigned
3d7aafde 1718string_hash (const char *string)
fae15c93
VM
1719{
1720 unsigned result, i;
1721
1722 for (result = i = 0;*string++ != '\0'; i++)
1723 result += ((unsigned char) *string << (i % CHAR_BIT));
1724 return result;
1725}
1726
1727\f
1728
1729/* This page contains abstract data `table of automaton declarations'.
1730 Elements of the table is nodes representing automaton declarations.
96e13905 1731 Key of the table elements is name of given automaton. Remember
fae15c93
VM
1732 that automaton names have own space. */
1733
e0a2f705 1734/* The function evaluates hash value of an automaton declaration. The
fae15c93
VM
1735 function is used by abstract data `hashtab'. The function returns
1736 hash value (0..UINT_MAX) of given automaton declaration. */
fb7e6024 1737static hashval_t
3d7aafde 1738automaton_decl_hash (const void *automaton_decl)
fae15c93
VM
1739{
1740 const decl_t decl = (decl_t) automaton_decl;
1741
b2d59f6f
NS
1742 gcc_assert (decl->mode != dm_automaton
1743 || DECL_AUTOMATON (decl)->name);
4005971c 1744 return string_hash (DECL_AUTOMATON (decl)->name);
fae15c93
VM
1745}
1746
1747/* The function tests automaton declarations on equality of their
1748 keys. The function is used by abstract data `hashtab'. The
1749 function returns 1 if the declarations have the same key, 0
1750 otherwise. */
1751static int
3d7aafde
AJ
1752automaton_decl_eq_p (const void* automaton_decl_1,
1753 const void* automaton_decl_2)
fae15c93
VM
1754{
1755 const decl_t decl1 = (decl_t) automaton_decl_1;
1756 const decl_t decl2 = (decl_t) automaton_decl_2;
1757
b2d59f6f
NS
1758 gcc_assert (decl1->mode == dm_automaton
1759 && DECL_AUTOMATON (decl1)->name
1760 && decl2->mode == dm_automaton
1761 && DECL_AUTOMATON (decl2)->name);
4005971c
VM
1762 return strcmp (DECL_AUTOMATON (decl1)->name,
1763 DECL_AUTOMATON (decl2)->name) == 0;
fae15c93
VM
1764}
1765
1766/* The automaton declaration table itself is represented by the
1767 following variable. */
1768static htab_t automaton_decl_table;
1769
1770/* The function inserts automaton declaration into the table. The
1771 function does nothing if an automaton declaration with the same key
1772 exists already in the table. The function returns automaton
1773 declaration node in the table with the same key as given automaton
1774 declaration node. */
1775static decl_t
3d7aafde 1776insert_automaton_decl (decl_t automaton_decl)
fae15c93
VM
1777{
1778 void **entry_ptr;
1779
1780 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
1781 if (*entry_ptr == NULL)
1782 *entry_ptr = (void *) automaton_decl;
1783 return (decl_t) *entry_ptr;
1784}
1785
1786/* The following variable value is node representing automaton
1787 declaration. The node used for searching automaton declaration
1788 with given name. */
1789static struct decl work_automaton_decl;
1790
1791/* The function searches for automaton declaration in the table with
1792 the same key as node representing name of the automaton
1793 declaration. The function returns node found in the table, NULL if
1794 such node does not exist in the table. */
1795static decl_t
1fb49ce7 1796find_automaton_decl (const char *name)
fae15c93
VM
1797{
1798 void *entry;
1799
4005971c
VM
1800 work_automaton_decl.mode = dm_automaton;
1801 DECL_AUTOMATON (&work_automaton_decl)->name = name;
fae15c93
VM
1802 entry = htab_find (automaton_decl_table, &work_automaton_decl);
1803 return (decl_t) entry;
1804}
1805
1806/* The function creates empty automaton declaration table and node
1807 representing automaton declaration and used for searching automaton
1808 declaration with given name. The function must be called only once
1809 before any work with the automaton declaration table. */
1810static void
3d7aafde 1811initiate_automaton_decl_table (void)
fae15c93
VM
1812{
1813 work_automaton_decl.mode = dm_automaton;
1814 automaton_decl_table = htab_create (10, automaton_decl_hash,
1815 automaton_decl_eq_p, (htab_del) 0);
1816}
1817
1818/* The function deletes the automaton declaration table. Only call of
1819 function `initiate_automaton_decl_table' is possible immediately
1820 after this function call. */
1821static void
3d7aafde 1822finish_automaton_decl_table (void)
fae15c93
VM
1823{
1824 htab_delete (automaton_decl_table);
1825}
1826
1827\f
1828
1829/* This page contains abstract data `table of insn declarations'.
1830 Elements of the table is nodes representing insn declarations. Key
1831 of the table elements is name of given insn (in corresponding
96e13905 1832 define_insn_reservation). Remember that insn names have own
fae15c93
VM
1833 space. */
1834
e0a2f705 1835/* The function evaluates hash value of an insn declaration. The
fae15c93
VM
1836 function is used by abstract data `hashtab'. The function returns
1837 hash value (0..UINT_MAX) of given insn declaration. */
fb7e6024 1838static hashval_t
3d7aafde 1839insn_decl_hash (const void *insn_decl)
fae15c93
VM
1840{
1841 const decl_t decl = (decl_t) insn_decl;
1842
b2d59f6f
NS
1843 gcc_assert (decl->mode == dm_insn_reserv
1844 && DECL_INSN_RESERV (decl)->name);
4005971c 1845 return string_hash (DECL_INSN_RESERV (decl)->name);
fae15c93
VM
1846}
1847
1848/* The function tests insn declarations on equality of their keys.
1849 The function is used by abstract data `hashtab'. The function
1850 returns 1 if declarations have the same key, 0 otherwise. */
1851static int
3d7aafde 1852insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
fae15c93
VM
1853{
1854 const decl_t decl1 = (decl_t) insn_decl_1;
1855 const decl_t decl2 = (decl_t) insn_decl_2;
1856
b2d59f6f
NS
1857 gcc_assert (decl1->mode == dm_insn_reserv
1858 && DECL_INSN_RESERV (decl1)->name
1859 && decl2->mode == dm_insn_reserv
1860 && DECL_INSN_RESERV (decl2)->name);
4005971c
VM
1861 return strcmp (DECL_INSN_RESERV (decl1)->name,
1862 DECL_INSN_RESERV (decl2)->name) == 0;
fae15c93
VM
1863}
1864
1865/* The insn declaration table itself is represented by the following
1866 variable. The table does not contain insn reservation
1867 declarations. */
1868static htab_t insn_decl_table;
1869
1870/* The function inserts insn declaration into the table. The function
1871 does nothing if an insn declaration with the same key exists
1872 already in the table. The function returns insn declaration node
1873 in the table with the same key as given insn declaration node. */
1874static decl_t
3d7aafde 1875insert_insn_decl (decl_t insn_decl)
fae15c93
VM
1876{
1877 void **entry_ptr;
1878
1879 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
1880 if (*entry_ptr == NULL)
1881 *entry_ptr = (void *) insn_decl;
1882 return (decl_t) *entry_ptr;
1883}
1884
1885/* The following variable value is node representing insn reservation
1886 declaration. The node used for searching insn reservation
1887 declaration with given name. */
1888static struct decl work_insn_decl;
1889
1890/* The function searches for insn reservation declaration in the table
1891 with the same key as node representing name of the insn reservation
1892 declaration. The function returns node found in the table, NULL if
1893 such node does not exist in the table. */
1894static decl_t
1fb49ce7 1895find_insn_decl (const char *name)
fae15c93
VM
1896{
1897 void *entry;
1898
4005971c
VM
1899 work_insn_decl.mode = dm_insn_reserv;
1900 DECL_INSN_RESERV (&work_insn_decl)->name = name;
fae15c93
VM
1901 entry = htab_find (insn_decl_table, &work_insn_decl);
1902 return (decl_t) entry;
1903}
1904
1905/* The function creates empty insn declaration table and node
1906 representing insn declaration and used for searching insn
1907 declaration with given name. The function must be called only once
1908 before any work with the insn declaration table. */
1909static void
3d7aafde 1910initiate_insn_decl_table (void)
fae15c93
VM
1911{
1912 work_insn_decl.mode = dm_insn_reserv;
1913 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
1914 (htab_del) 0);
1915}
1916
1917/* The function deletes the insn declaration table. Only call of
1918 function `initiate_insn_decl_table' is possible immediately after
1919 this function call. */
1920static void
3d7aafde 1921finish_insn_decl_table (void)
fae15c93
VM
1922{
1923 htab_delete (insn_decl_table);
1924}
1925
1926\f
1927
1928/* This page contains abstract data `table of declarations'. Elements
1929 of the table is nodes representing declarations (of units and
1930 reservations). Key of the table elements is names of given
1931 declarations. */
1932
1933/* The function evaluates hash value of a declaration. The function
1934 is used by abstract data `hashtab'. The function returns hash
1935 value (0..UINT_MAX) of given declaration. */
fb7e6024 1936static hashval_t
3d7aafde 1937decl_hash (const void *decl)
fae15c93
VM
1938{
1939 const decl_t d = (const decl_t) decl;
1940
b2d59f6f
NS
1941 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
1942 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
fae15c93 1943 return string_hash (d->mode == dm_unit
4005971c 1944 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
fae15c93
VM
1945}
1946
1947/* The function tests declarations on equality of their keys. The
b2d59f6f 1948 function is used by abstract data 'hashtab'. The function
fae15c93
VM
1949 returns 1 if the declarations have the same key, 0 otherwise. */
1950static int
3d7aafde 1951decl_eq_p (const void *decl_1, const void *decl_2)
fae15c93
VM
1952{
1953 const decl_t d1 = (const decl_t) decl_1;
1954 const decl_t d2 = (const decl_t) decl_2;
1955
b2d59f6f
NS
1956 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
1957 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
1958 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
1959 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
fae15c93 1960 return strcmp ((d1->mode == dm_unit
4005971c 1961 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
fae15c93 1962 (d2->mode == dm_unit
4005971c 1963 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
fae15c93
VM
1964}
1965
1966/* The declaration table itself is represented by the following
1967 variable. */
1968static htab_t decl_table;
1969
1970/* The function inserts declaration into the table. The function does
1971 nothing if a declaration with the same key exists already in the
1972 table. The function returns declaration node in the table with the
1973 same key as given declaration node. */
1974
1975static decl_t
3d7aafde 1976insert_decl (decl_t decl)
fae15c93
VM
1977{
1978 void **entry_ptr;
1979
1980 entry_ptr = htab_find_slot (decl_table, decl, 1);
1981 if (*entry_ptr == NULL)
1982 *entry_ptr = (void *) decl;
1983 return (decl_t) *entry_ptr;
1984}
1985
1986/* The following variable value is node representing declaration. The
1987 node used for searching declaration with given name. */
1988static struct decl work_decl;
1989
1990/* The function searches for declaration in the table with the same
1991 key as node representing name of the declaration. The function
1992 returns node found in the table, NULL if such node does not exist
1993 in the table. */
1994static decl_t
1fb49ce7 1995find_decl (const char *name)
fae15c93
VM
1996{
1997 void *entry;
1998
4005971c
VM
1999 work_decl.mode = dm_unit;
2000 DECL_UNIT (&work_decl)->name = name;
fae15c93
VM
2001 entry = htab_find (decl_table, &work_decl);
2002 return (decl_t) entry;
2003}
2004
2005/* The function creates empty declaration table and node representing
2006 declaration and used for searching declaration with given name.
2007 The function must be called only once before any work with the
2008 declaration table. */
2009static void
3d7aafde 2010initiate_decl_table (void)
fae15c93
VM
2011{
2012 work_decl.mode = dm_unit;
2013 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2014}
2015
2016/* The function deletes the declaration table. Only call of function
2017 `initiate_declaration_table' is possible immediately after this
2018 function call. */
2019static void
3d7aafde 2020finish_decl_table (void)
fae15c93
VM
2021{
2022 htab_delete (decl_table);
2023}
2024
2025\f
2026
2027/* This page contains checker of pipeline hazard description. */
2028
2029/* Checking NAMES in an exclusion clause vector and returning formed
2030 unit_set_el_list. */
2031static unit_set_el_t
3d7aafde 2032process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
fae15c93
VM
2033{
2034 unit_set_el_t el_list;
2035 unit_set_el_t last_el;
2036 unit_set_el_t new_el;
2037 decl_t decl_in_table;
2038 int i;
2039
2040 el_list = NULL;
2041 last_el = NULL;
2042 for (i = 0; i < num; i++)
2043 {
2044 decl_in_table = find_decl (names [i]);
2045 if (decl_in_table == NULL)
2046 error ("unit `%s' in exclusion is not declared", names [i]);
2047 else if (decl_in_table->mode != dm_unit)
2048 error ("`%s' in exclusion is not unit", names [i]);
2049 else
2050 {
2051 new_el = create_node (sizeof (struct unit_set_el));
4005971c 2052 new_el->unit_decl = DECL_UNIT (decl_in_table);
fae15c93
VM
2053 new_el->next_unit_set_el = NULL;
2054 if (last_el == NULL)
2055 el_list = last_el = new_el;
2056 else
2057 {
2058 last_el->next_unit_set_el = new_el;
2059 last_el = last_el->next_unit_set_el;
2060 }
2061 }
2062 }
2063 return el_list;
2064}
2065
2066/* The function adds each element from SOURCE_LIST to the exclusion
2067 list of the each element from DEST_LIST. Checking situation "unit
2068 excludes itself". */
2069static void
3d7aafde
AJ
2070add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2071 pos_t excl_pos ATTRIBUTE_UNUSED)
fae15c93
VM
2072{
2073 unit_set_el_t dst;
2074 unit_set_el_t src;
2075 unit_set_el_t curr_el;
2076 unit_set_el_t prev_el;
2077 unit_set_el_t copy;
2078
2079 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2080 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2081 {
2082 if (dst->unit_decl == src->unit_decl)
2083 {
2084 error ("unit `%s' excludes itself", src->unit_decl->name);
2085 continue;
2086 }
2087 if (dst->unit_decl->automaton_name != NULL
2088 && src->unit_decl->automaton_name != NULL
2089 && strcmp (dst->unit_decl->automaton_name,
2090 src->unit_decl->automaton_name) != 0)
2091 {
2092 error ("units `%s' and `%s' in exclusion set belong to different automata",
2093 src->unit_decl->name, dst->unit_decl->name);
2094 continue;
2095 }
2096 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2097 curr_el != NULL;
2098 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2099 if (curr_el->unit_decl == src->unit_decl)
2100 break;
2101 if (curr_el == NULL)
2102 {
2103 /* Element not found - insert. */
2104 copy = copy_node (src, sizeof (*src));
2105 copy->next_unit_set_el = NULL;
2106 if (prev_el == NULL)
2107 dst->unit_decl->excl_list = copy;
2108 else
2109 prev_el->next_unit_set_el = copy;
2110 }
2111 }
2112}
2113
30028c85
VM
2114/* Checking NAMES in presence/absence clause and returning the
2115 formed unit_set_el_list. The function is called only after
2116 processing all exclusion sets. */
fae15c93 2117static unit_set_el_t
3d7aafde
AJ
2118process_presence_absence_names (char **names, int num,
2119 pos_t req_pos ATTRIBUTE_UNUSED,
2120 int presence_p, int final_p)
fae15c93
VM
2121{
2122 unit_set_el_t el_list;
2123 unit_set_el_t last_el;
2124 unit_set_el_t new_el;
2125 decl_t decl_in_table;
2126 int i;
2127
2128 el_list = NULL;
2129 last_el = NULL;
2130 for (i = 0; i < num; i++)
2131 {
2132 decl_in_table = find_decl (names [i]);
2133 if (decl_in_table == NULL)
2134 error ((presence_p
30028c85
VM
2135 ? (final_p
2136 ? "unit `%s' in final presence set is not declared"
2137 : "unit `%s' in presence set is not declared")
2138 : (final_p
2139 ? "unit `%s' in final absence set is not declared"
2140 : "unit `%s' in absence set is not declared")), names [i]);
fae15c93
VM
2141 else if (decl_in_table->mode != dm_unit)
2142 error ((presence_p
30028c85
VM
2143 ? (final_p
2144 ? "`%s' in final presence set is not unit"
2145 : "`%s' in presence set is not unit")
2146 : (final_p
2147 ? "`%s' in final absence set is not unit"
2148 : "`%s' in absence set is not unit")), names [i]);
fae15c93
VM
2149 else
2150 {
2151 new_el = create_node (sizeof (struct unit_set_el));
4005971c 2152 new_el->unit_decl = DECL_UNIT (decl_in_table);
fae15c93
VM
2153 new_el->next_unit_set_el = NULL;
2154 if (last_el == NULL)
2155 el_list = last_el = new_el;
2156 else
2157 {
2158 last_el->next_unit_set_el = new_el;
2159 last_el = last_el->next_unit_set_el;
2160 }
2161 }
2162 }
2163 return el_list;
2164}
2165
30028c85
VM
2166/* Checking NAMES in patterns of a presence/absence clause and
2167 returning the formed pattern_set_el_list. The function is called
2168 only after processing all exclusion sets. */
2169static pattern_set_el_t
3d7aafde
AJ
2170process_presence_absence_patterns (char ***patterns, int num,
2171 pos_t req_pos ATTRIBUTE_UNUSED,
2172 int presence_p, int final_p)
30028c85
VM
2173{
2174 pattern_set_el_t el_list;
2175 pattern_set_el_t last_el;
2176 pattern_set_el_t new_el;
2177 decl_t decl_in_table;
2178 int i, j;
2179
2180 el_list = NULL;
2181 last_el = NULL;
2182 for (i = 0; i < num; i++)
2183 {
2184 for (j = 0; patterns [i] [j] != NULL; j++)
2185 ;
2186 new_el = create_node (sizeof (struct pattern_set_el)
2187 + sizeof (struct unit_decl *) * j);
2188 new_el->unit_decls
2189 = (struct unit_decl **) ((char *) new_el
2190 + sizeof (struct pattern_set_el));
2191 new_el->next_pattern_set_el = NULL;
2192 if (last_el == NULL)
2193 el_list = last_el = new_el;
2194 else
2195 {
2196 last_el->next_pattern_set_el = new_el;
2197 last_el = last_el->next_pattern_set_el;
2198 }
2199 new_el->units_num = 0;
2200 for (j = 0; patterns [i] [j] != NULL; j++)
2201 {
2202 decl_in_table = find_decl (patterns [i] [j]);
2203 if (decl_in_table == NULL)
2204 error ((presence_p
2205 ? (final_p
2206 ? "unit `%s' in final presence set is not declared"
2207 : "unit `%s' in presence set is not declared")
2208 : (final_p
2209 ? "unit `%s' in final absence set is not declared"
2210 : "unit `%s' in absence set is not declared")),
2211 patterns [i] [j]);
2212 else if (decl_in_table->mode != dm_unit)
2213 error ((presence_p
2214 ? (final_p
2215 ? "`%s' in final presence set is not unit"
2216 : "`%s' in presence set is not unit")
2217 : (final_p
2218 ? "`%s' in final absence set is not unit"
2219 : "`%s' in absence set is not unit")),
2220 patterns [i] [j]);
2221 else
2222 {
2223 new_el->unit_decls [new_el->units_num]
2224 = DECL_UNIT (decl_in_table);
2225 new_el->units_num++;
2226 }
2227 }
2228 }
2229 return el_list;
2230}
2231
2232/* The function adds each element from PATTERN_LIST to presence (if
fae15c93 2233 PRESENCE_P) or absence list of the each element from DEST_LIST.
30028c85
VM
2234 Checking situations "unit requires own absence", and "unit excludes
2235 and requires presence of ...", "unit requires absence and presence
2236 of ...", "units in (final) presence set belong to different
2237 automata", and "units in (final) absence set belong to different
2238 automata". Remember that we process absence sets only after all
2239 presence sets. */
2240static void
3d7aafde
AJ
2241add_presence_absence (unit_set_el_t dest_list,
2242 pattern_set_el_t pattern_list,
2243 pos_t req_pos ATTRIBUTE_UNUSED,
2244 int presence_p, int final_p)
fae15c93
VM
2245{
2246 unit_set_el_t dst;
30028c85
VM
2247 pattern_set_el_t pat;
2248 struct unit_decl *unit;
2249 unit_set_el_t curr_excl_el;
2250 pattern_set_el_t curr_pat_el;
2251 pattern_set_el_t prev_el;
2252 pattern_set_el_t copy;
2253 int i;
2254 int no_error_flag;
fae15c93
VM
2255
2256 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
30028c85 2257 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
fae15c93 2258 {
30028c85 2259 for (i = 0; i < pat->units_num; i++)
fae15c93 2260 {
30028c85
VM
2261 unit = pat->unit_decls [i];
2262 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2263 {
2264 error ("unit `%s' requires own absence", unit->name);
2265 continue;
2266 }
2267 if (dst->unit_decl->automaton_name != NULL
2268 && unit->automaton_name != NULL
2269 && strcmp (dst->unit_decl->automaton_name,
2270 unit->automaton_name) != 0)
2271 {
2272 error ((presence_p
2273 ? (final_p
2274 ? "units `%s' and `%s' in final presence set belong to different automata"
2275 : "units `%s' and `%s' in presence set belong to different automata")
2276 : (final_p
2277 ? "units `%s' and `%s' in final absence set belong to different automata"
2278 : "units `%s' and `%s' in absence set belong to different automata")),
2279 unit->name, dst->unit_decl->name);
2280 continue;
2281 }
2282 no_error_flag = 1;
fae15c93 2283 if (presence_p)
30028c85
VM
2284 for (curr_excl_el = dst->unit_decl->excl_list;
2285 curr_excl_el != NULL;
2286 curr_excl_el = curr_excl_el->next_unit_set_el)
fae15c93 2287 {
30028c85 2288 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
fae15c93
VM
2289 {
2290 if (!w_flag)
2291 {
30028c85
VM
2292 error ("unit `%s' excludes and requires presence of `%s'",
2293 dst->unit_decl->name, unit->name);
fae15c93
VM
2294 no_error_flag = 0;
2295 }
2296 else
2297 warning
d4ee4d25 2298 (0, "unit `%s' excludes and requires presence of `%s'",
30028c85 2299 dst->unit_decl->name, unit->name);
fae15c93
VM
2300 }
2301 }
30028c85
VM
2302 else if (pat->units_num == 1)
2303 for (curr_pat_el = dst->unit_decl->presence_list;
2304 curr_pat_el != NULL;
2305 curr_pat_el = curr_pat_el->next_pattern_set_el)
2306 if (curr_pat_el->units_num == 1
2307 && unit == curr_pat_el->unit_decls [0])
2308 {
2309 if (!w_flag)
2310 {
2311 error
fae15c93 2312 ("unit `%s' requires absence and presence of `%s'",
30028c85
VM
2313 dst->unit_decl->name, unit->name);
2314 no_error_flag = 0;
2315 }
2316 else
2317 warning
d4ee4d25 2318 (0, "unit `%s' requires absence and presence of `%s'",
30028c85
VM
2319 dst->unit_decl->name, unit->name);
2320 }
fae15c93
VM
2321 if (no_error_flag)
2322 {
30028c85
VM
2323 for (prev_el = (presence_p
2324 ? (final_p
2325 ? dst->unit_decl->final_presence_list
2326 : dst->unit_decl->final_presence_list)
2327 : (final_p
2328 ? dst->unit_decl->final_absence_list
2329 : dst->unit_decl->absence_list));
2330 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2331 prev_el = prev_el->next_pattern_set_el)
2332 ;
2333 copy = copy_node (pat, sizeof (*pat));
2334 copy->next_pattern_set_el = NULL;
fae15c93
VM
2335 if (prev_el == NULL)
2336 {
2337 if (presence_p)
30028c85
VM
2338 {
2339 if (final_p)
2340 dst->unit_decl->final_presence_list = copy;
2341 else
2342 dst->unit_decl->presence_list = copy;
2343 }
2344 else if (final_p)
2345 dst->unit_decl->final_absence_list = copy;
fae15c93
VM
2346 else
2347 dst->unit_decl->absence_list = copy;
2348 }
2349 else
30028c85 2350 prev_el->next_pattern_set_el = copy;
fae15c93 2351 }
30028c85
VM
2352 }
2353 }
fae15c93
VM
2354}
2355
30028c85 2356
fae15c93
VM
2357/* The function searches for bypass with given IN_INSN_RESERV in given
2358 BYPASS_LIST. */
2359static struct bypass_decl *
3d7aafde
AJ
2360find_bypass (struct bypass_decl *bypass_list,
2361 struct insn_reserv_decl *in_insn_reserv)
fae15c93
VM
2362{
2363 struct bypass_decl *bypass;
2364
2365 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2366 if (bypass->in_insn_reserv == in_insn_reserv)
2367 break;
2368 return bypass;
2369}
2370
2371/* The function processes pipeline description declarations, checks
2372 their correctness, and forms exclusion/presence/absence sets. */
2373static void
3d7aafde 2374process_decls (void)
fae15c93
VM
2375{
2376 decl_t decl;
2377 decl_t automaton_decl;
2378 decl_t decl_in_table;
2379 decl_t out_insn_reserv;
2380 decl_t in_insn_reserv;
2381 struct bypass_decl *bypass;
2382 int automaton_presence;
2383 int i;
2384
2385 /* Checking repeated automata declarations. */
2386 automaton_presence = 0;
2387 for (i = 0; i < description->decls_num; i++)
2388 {
2389 decl = description->decls [i];
2390 if (decl->mode == dm_automaton)
2391 {
2392 automaton_presence = 1;
2393 decl_in_table = insert_automaton_decl (decl);
2394 if (decl_in_table != decl)
2395 {
2396 if (!w_flag)
2397 error ("repeated declaration of automaton `%s'",
4005971c 2398 DECL_AUTOMATON (decl)->name);
fae15c93 2399 else
d4ee4d25 2400 warning (0, "repeated declaration of automaton `%s'",
4005971c 2401 DECL_AUTOMATON (decl)->name);
fae15c93
VM
2402 }
2403 }
2404 }
2405 /* Checking undeclared automata, repeated declarations (except for
2406 automata) and correctness of their attributes (insn latency times
2407 etc.). */
2408 for (i = 0; i < description->decls_num; i++)
2409 {
2410 decl = description->decls [i];
2411 if (decl->mode == dm_insn_reserv)
2412 {
4005971c 2413 if (DECL_INSN_RESERV (decl)->default_latency < 0)
fae15c93 2414 error ("define_insn_reservation `%s' has negative latency time",
4005971c
VM
2415 DECL_INSN_RESERV (decl)->name);
2416 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
fae15c93
VM
2417 description->insns_num++;
2418 decl_in_table = insert_insn_decl (decl);
2419 if (decl_in_table != decl)
2420 error ("`%s' is already used as insn reservation name",
4005971c 2421 DECL_INSN_RESERV (decl)->name);
fae15c93
VM
2422 }
2423 else if (decl->mode == dm_bypass)
2424 {
4005971c 2425 if (DECL_BYPASS (decl)->latency < 0)
fae15c93 2426 error ("define_bypass `%s - %s' has negative latency time",
4005971c
VM
2427 DECL_BYPASS (decl)->out_insn_name,
2428 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2429 }
2430 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2431 {
2432 if (decl->mode == dm_unit)
2433 {
4005971c
VM
2434 DECL_UNIT (decl)->automaton_decl = NULL;
2435 if (DECL_UNIT (decl)->automaton_name != NULL)
fae15c93
VM
2436 {
2437 automaton_decl
4005971c 2438 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
fae15c93
VM
2439 if (automaton_decl == NULL)
2440 error ("automaton `%s' is not declared",
4005971c 2441 DECL_UNIT (decl)->automaton_name);
fae15c93
VM
2442 else
2443 {
4005971c
VM
2444 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2445 DECL_UNIT (decl)->automaton_decl
2446 = DECL_AUTOMATON (automaton_decl);
fae15c93
VM
2447 }
2448 }
2449 else if (automaton_presence)
2450 error ("define_unit `%s' without automaton when one defined",
4005971c
VM
2451 DECL_UNIT (decl)->name);
2452 DECL_UNIT (decl)->unit_num = description->units_num;
fae15c93 2453 description->units_num++;
4005971c 2454 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
fae15c93
VM
2455 {
2456 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2457 continue;
2458 }
4005971c 2459 decl_in_table = find_decl (DECL_UNIT (decl)->name);
fae15c93
VM
2460 }
2461 else
2462 {
4005971c 2463 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
fae15c93
VM
2464 {
2465 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2466 continue;
2467 }
4005971c 2468 decl_in_table = find_decl (DECL_RESERV (decl)->name);
fae15c93
VM
2469 }
2470 if (decl_in_table == NULL)
2471 decl_in_table = insert_decl (decl);
2472 else
2473 {
2474 if (decl->mode == dm_unit)
2475 error ("repeated declaration of unit `%s'",
4005971c 2476 DECL_UNIT (decl)->name);
fae15c93
VM
2477 else
2478 error ("repeated declaration of reservation `%s'",
4005971c 2479 DECL_RESERV (decl)->name);
fae15c93
VM
2480 }
2481 }
2482 }
2483 /* Check bypasses and form list of bypasses for each (output)
2484 insn. */
2485 for (i = 0; i < description->decls_num; i++)
2486 {
2487 decl = description->decls [i];
2488 if (decl->mode == dm_bypass)
2489 {
4005971c
VM
2490 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2491 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2492 if (out_insn_reserv == NULL)
2493 error ("there is no insn reservation `%s'",
4005971c 2494 DECL_BYPASS (decl)->out_insn_name);
fae15c93
VM
2495 else if (in_insn_reserv == NULL)
2496 error ("there is no insn reservation `%s'",
4005971c 2497 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2498 else
2499 {
4005971c
VM
2500 DECL_BYPASS (decl)->out_insn_reserv
2501 = DECL_INSN_RESERV (out_insn_reserv);
2502 DECL_BYPASS (decl)->in_insn_reserv
2503 = DECL_INSN_RESERV (in_insn_reserv);
fae15c93 2504 bypass
4005971c
VM
2505 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2506 DECL_BYPASS (decl)->in_insn_reserv);
fae15c93
VM
2507 if (bypass != NULL)
2508 {
4005971c 2509 if (DECL_BYPASS (decl)->latency == bypass->latency)
fae15c93
VM
2510 {
2511 if (!w_flag)
2512 error
2513 ("the same bypass `%s - %s' is already defined",
4005971c
VM
2514 DECL_BYPASS (decl)->out_insn_name,
2515 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2516 else
2517 warning
d4ee4d25 2518 (0, "the same bypass `%s - %s' is already defined",
4005971c
VM
2519 DECL_BYPASS (decl)->out_insn_name,
2520 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2521 }
2522 else
2523 error ("bypass `%s - %s' is already defined",
4005971c
VM
2524 DECL_BYPASS (decl)->out_insn_name,
2525 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
2526 }
2527 else
2528 {
4005971c
VM
2529 DECL_BYPASS (decl)->next
2530 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2531 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2532 = DECL_BYPASS (decl);
fae15c93
VM
2533 }
2534 }
2535 }
2536 }
2537
96e13905 2538 /* Check exclusion set declarations and form exclusion sets. */
fae15c93
VM
2539 for (i = 0; i < description->decls_num; i++)
2540 {
2541 decl = description->decls [i];
2542 if (decl->mode == dm_excl)
2543 {
2544 unit_set_el_t unit_set_el_list;
2545 unit_set_el_t unit_set_el_list_2;
3d7aafde 2546
fae15c93 2547 unit_set_el_list
4005971c
VM
2548 = process_excls (DECL_EXCL (decl)->names,
2549 DECL_EXCL (decl)->first_list_length, decl->pos);
fae15c93 2550 unit_set_el_list_2
4005971c
VM
2551 = process_excls (&DECL_EXCL (decl)->names
2552 [DECL_EXCL (decl)->first_list_length],
30028c85 2553 DECL_EXCL (decl)->all_names_num
4005971c 2554 - DECL_EXCL (decl)->first_list_length,
fae15c93
VM
2555 decl->pos);
2556 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2557 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2558 }
2559 }
2560
2561 /* Check presence set declarations and form presence sets. */
2562 for (i = 0; i < description->decls_num; i++)
2563 {
2564 decl = description->decls [i];
2565 if (decl->mode == dm_presence)
2566 {
2567 unit_set_el_t unit_set_el_list;
30028c85 2568 pattern_set_el_t pattern_set_el_list;
3d7aafde 2569
fae15c93 2570 unit_set_el_list
30028c85
VM
2571 = process_presence_absence_names
2572 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
2573 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2574 pattern_set_el_list
2575 = process_presence_absence_patterns
2576 (DECL_PRESENCE (decl)->patterns,
2577 DECL_PRESENCE (decl)->patterns_num,
2578 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2579 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2580 decl->pos, TRUE,
2581 DECL_PRESENCE (decl)->final_p);
fae15c93
VM
2582 }
2583 }
2584
2585 /* Check absence set declarations and form absence sets. */
2586 for (i = 0; i < description->decls_num; i++)
2587 {
2588 decl = description->decls [i];
2589 if (decl->mode == dm_absence)
2590 {
2591 unit_set_el_t unit_set_el_list;
30028c85 2592 pattern_set_el_t pattern_set_el_list;
3d7aafde 2593
fae15c93 2594 unit_set_el_list
30028c85
VM
2595 = process_presence_absence_names
2596 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
2597 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2598 pattern_set_el_list
2599 = process_presence_absence_patterns
2600 (DECL_ABSENCE (decl)->patterns,
2601 DECL_ABSENCE (decl)->patterns_num,
2602 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2603 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2604 decl->pos, FALSE,
2605 DECL_ABSENCE (decl)->final_p);
fae15c93
VM
2606 }
2607 }
2608}
2609
2610/* The following function checks that declared automaton is used. If
2611 the automaton is not used, the function fixes error/warning. The
2612 following function must be called only after `process_decls'. */
2613static void
3d7aafde 2614check_automaton_usage (void)
fae15c93
VM
2615{
2616 decl_t decl;
2617 int i;
2618
2619 for (i = 0; i < description->decls_num; i++)
2620 {
2621 decl = description->decls [i];
2622 if (decl->mode == dm_automaton
4005971c 2623 && !DECL_AUTOMATON (decl)->automaton_is_used)
fae15c93
VM
2624 {
2625 if (!w_flag)
4005971c 2626 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
fae15c93 2627 else
d4ee4d25 2628 warning (0, "automaton `%s' is not used",
4005971c 2629 DECL_AUTOMATON (decl)->name);
fae15c93
VM
2630 }
2631 }
2632}
2633
2634/* The following recursive function processes all regexp in order to
2635 fix usage of units or reservations and to fix errors of undeclared
2636 name. The function may change unit_regexp onto reserv_regexp.
2637 Remember that reserv_regexp does not exist before the function
2638 call. */
2639static regexp_t
3d7aafde 2640process_regexp (regexp_t regexp)
fae15c93
VM
2641{
2642 decl_t decl_in_table;
2643 regexp_t new_regexp;
2644 int i;
3d7aafde 2645
b2d59f6f 2646 switch (regexp->mode)
fae15c93 2647 {
b2d59f6f 2648 case rm_unit:
4005971c 2649 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
fae15c93
VM
2650 if (decl_in_table == NULL)
2651 error ("undeclared unit or reservation `%s'",
4005971c 2652 REGEXP_UNIT (regexp)->name);
fae15c93 2653 else
b2d59f6f
NS
2654 switch (decl_in_table->mode)
2655 {
2656 case dm_unit:
2657 DECL_UNIT (decl_in_table)->unit_is_used = 1;
2658 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
2659 break;
2660
2661 case dm_reserv:
2662 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
2663 new_regexp = create_node (sizeof (struct regexp));
2664 new_regexp->mode = rm_reserv;
2665 new_regexp->pos = regexp->pos;
2666 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
2667 REGEXP_RESERV (new_regexp)->reserv_decl
2668 = DECL_RESERV (decl_in_table);
2669 regexp = new_regexp;
2670 break;
2671
2672 default:
2673 gcc_unreachable ();
2674 }
2675 break;
2676 case rm_sequence:
2677 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2678 REGEXP_SEQUENCE (regexp)->regexps [i]
2679 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
2680 break;
2681 case rm_allof:
2682 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2683 REGEXP_ALLOF (regexp)->regexps [i]
2684 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
2685 break;
2686 case rm_oneof:
2687 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2688 REGEXP_ONEOF (regexp)->regexps [i]
2689 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
2690 break;
2691 case rm_repeat:
2692 REGEXP_REPEAT (regexp)->regexp
2693 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
2694 break;
2695 case rm_nothing:
2696 break;
2697 default:
2698 gcc_unreachable ();
fae15c93 2699 }
fae15c93
VM
2700 return regexp;
2701}
2702
2703/* The following function processes regexp of define_reservation and
2704 define_insn_reservation with the aid of function
2705 `process_regexp'. */
2706static void
3d7aafde 2707process_regexp_decls (void)
fae15c93
VM
2708{
2709 decl_t decl;
2710 int i;
2711
2712 for (i = 0; i < description->decls_num; i++)
2713 {
2714 decl = description->decls [i];
2715 if (decl->mode == dm_reserv)
4005971c
VM
2716 DECL_RESERV (decl)->regexp
2717 = process_regexp (DECL_RESERV (decl)->regexp);
fae15c93 2718 else if (decl->mode == dm_insn_reserv)
4005971c
VM
2719 DECL_INSN_RESERV (decl)->regexp
2720 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
fae15c93
VM
2721 }
2722}
2723
2724/* The following function checks that declared unit is used. If the
2725 unit is not used, the function fixes errors/warnings. The
2726 following function must be called only after `process_decls',
2727 `process_regexp_decls'. */
2728static void
3d7aafde 2729check_usage (void)
fae15c93
VM
2730{
2731 decl_t decl;
2732 int i;
2733
2734 for (i = 0; i < description->decls_num; i++)
2735 {
2736 decl = description->decls [i];
4005971c 2737 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
fae15c93
VM
2738 {
2739 if (!w_flag)
4005971c 2740 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
fae15c93 2741 else
d4ee4d25 2742 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
fae15c93 2743 }
4005971c 2744 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
fae15c93
VM
2745 {
2746 if (!w_flag)
4005971c 2747 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
fae15c93 2748 else
d4ee4d25 2749 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
fae15c93
VM
2750 }
2751 }
2752}
2753
2754/* The following variable value is number of reservation being
2755 processed on loop recognition. */
2756static int curr_loop_pass_num;
2757
2758/* The following recursive function returns nonzero value if REGEXP
2759 contains given decl or reservations in given regexp refers for
2760 given decl. */
2761static int
3d7aafde 2762loop_in_regexp (regexp_t regexp, decl_t start_decl)
fae15c93
VM
2763{
2764 int i;
2765
2766 if (regexp == NULL)
2767 return 0;
b2d59f6f 2768 switch (regexp->mode)
fae15c93 2769 {
b2d59f6f
NS
2770 case rm_unit:
2771 return 0;
2772
2773 case rm_reserv:
fae15c93 2774 if (start_decl->mode == dm_reserv
4005971c 2775 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
fae15c93 2776 return 1;
4005971c 2777 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
fae15c93
VM
2778 == curr_loop_pass_num)
2779 /* declaration has been processed. */
2780 return 0;
2781 else
2782 {
4005971c 2783 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
fae15c93 2784 = curr_loop_pass_num;
4005971c 2785 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
fae15c93
VM
2786 start_decl);
2787 }
b2d59f6f
NS
2788
2789 case rm_sequence:
4005971c
VM
2790 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2791 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
fae15c93
VM
2792 return 1;
2793 return 0;
b2d59f6f
NS
2794
2795 case rm_allof:
4005971c
VM
2796 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2797 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
fae15c93
VM
2798 return 1;
2799 return 0;
b2d59f6f
NS
2800
2801 case rm_oneof:
4005971c
VM
2802 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2803 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
fae15c93
VM
2804 return 1;
2805 return 0;
b2d59f6f
NS
2806
2807 case rm_repeat:
2808 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
2809
2810 case rm_nothing:
fae15c93 2811 return 0;
b2d59f6f
NS
2812
2813 default:
2814 gcc_unreachable ();
fae15c93
VM
2815 }
2816}
2817
2818/* The following function fixes errors "cycle in definition ...". The
2819 function uses function `loop_in_regexp' for that. */
2820static void
3d7aafde 2821check_loops_in_regexps (void)
fae15c93
VM
2822{
2823 decl_t decl;
2824 int i;
2825
2826 for (i = 0; i < description->decls_num; i++)
2827 {
2828 decl = description->decls [i];
2829 if (decl->mode == dm_reserv)
4005971c 2830 DECL_RESERV (decl)->loop_pass_num = 0;
fae15c93
VM
2831 }
2832 for (i = 0; i < description->decls_num; i++)
2833 {
2834 decl = description->decls [i];
2835 curr_loop_pass_num = i;
3d7aafde 2836
fae15c93
VM
2837 if (decl->mode == dm_reserv)
2838 {
4005971c
VM
2839 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
2840 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
fae15c93 2841 {
b2d59f6f 2842 gcc_assert (DECL_RESERV (decl)->regexp);
fae15c93 2843 error ("cycle in definition of reservation `%s'",
4005971c 2844 DECL_RESERV (decl)->name);
fae15c93
VM
2845 }
2846 }
2847 }
2848}
2849
2850/* The function recursively processes IR of reservation and defines
30028c85
VM
2851 max and min cycle for reservation of unit. */
2852static void
3d7aafde
AJ
2853process_regexp_cycles (regexp_t regexp, int max_start_cycle,
2854 int min_start_cycle, int *max_finish_cycle,
2855 int *min_finish_cycle)
fae15c93
VM
2856{
2857 int i;
2858
b2d59f6f 2859 switch (regexp->mode)
fae15c93 2860 {
b2d59f6f 2861 case rm_unit:
30028c85
VM
2862 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
2863 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
2864 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
2865 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
2866 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
2867 *max_finish_cycle = max_start_cycle;
2868 *min_finish_cycle = min_start_cycle;
b2d59f6f
NS
2869 break;
2870
2871 case rm_reserv:
2872 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2873 max_start_cycle, min_start_cycle,
2874 max_finish_cycle, min_finish_cycle);
2875 break;
2876
2877 case rm_repeat:
4005971c 2878 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
30028c85
VM
2879 {
2880 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
2881 max_start_cycle, min_start_cycle,
2882 max_finish_cycle, min_finish_cycle);
2883 max_start_cycle = *max_finish_cycle + 1;
2884 min_start_cycle = *min_finish_cycle + 1;
2885 }
b2d59f6f
NS
2886 break;
2887
2888 case rm_sequence:
4005971c 2889 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
30028c85
VM
2890 {
2891 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
2892 max_start_cycle, min_start_cycle,
2893 max_finish_cycle, min_finish_cycle);
2894 max_start_cycle = *max_finish_cycle + 1;
2895 min_start_cycle = *min_finish_cycle + 1;
2896 }
b2d59f6f 2897 break;
fae15c93 2898
b2d59f6f
NS
2899 case rm_allof:
2900 {
2901 int max_cycle = 0;
2902 int min_cycle = 0;
2903
2904 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2905 {
2906 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
2907 max_start_cycle, min_start_cycle,
2908 max_finish_cycle, min_finish_cycle);
2909 if (max_cycle < *max_finish_cycle)
2910 max_cycle = *max_finish_cycle;
2911 if (i == 0 || min_cycle > *min_finish_cycle)
2912 min_cycle = *min_finish_cycle;
2913 }
2914 *max_finish_cycle = max_cycle;
2915 *min_finish_cycle = min_cycle;
2916 }
2917 break;
fae15c93 2918
b2d59f6f
NS
2919 case rm_oneof:
2920 {
2921 int max_cycle = 0;
2922 int min_cycle = 0;
2923
2924 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2925 {
2926 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
2927 max_start_cycle, min_start_cycle,
2928 max_finish_cycle, min_finish_cycle);
2929 if (max_cycle < *max_finish_cycle)
2930 max_cycle = *max_finish_cycle;
2931 if (i == 0 || min_cycle > *min_finish_cycle)
2932 min_cycle = *min_finish_cycle;
2933 }
2934 *max_finish_cycle = max_cycle;
2935 *min_finish_cycle = min_cycle;
2936 }
2937 break;
2938
2939 case rm_nothing:
30028c85
VM
2940 *max_finish_cycle = max_start_cycle;
2941 *min_finish_cycle = min_start_cycle;
b2d59f6f
NS
2942 break;
2943
2944 default:
2945 gcc_unreachable ();
fae15c93
VM
2946 }
2947}
2948
2949/* The following function is called only for correct program. The
2950 function defines max reservation of insns in cycles. */
2951static void
3d7aafde 2952evaluate_max_reserv_cycles (void)
fae15c93
VM
2953{
2954 int max_insn_cycles_num;
30028c85 2955 int min_insn_cycles_num;
fae15c93
VM
2956 decl_t decl;
2957 int i;
2958
2959 description->max_insn_reserv_cycles = 0;
2960 for (i = 0; i < description->decls_num; i++)
2961 {
2962 decl = description->decls [i];
2963 if (decl->mode == dm_insn_reserv)
2964 {
30028c85
VM
2965 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
2966 &max_insn_cycles_num, &min_insn_cycles_num);
fae15c93
VM
2967 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
2968 description->max_insn_reserv_cycles = max_insn_cycles_num;
2969 }
2970 }
deb09eff 2971 description->max_insn_reserv_cycles++;
fae15c93
VM
2972}
2973
2974/* The following function calls functions for checking all
2975 description. */
2976static void
3d7aafde 2977check_all_description (void)
fae15c93
VM
2978{
2979 process_decls ();
2980 check_automaton_usage ();
2981 process_regexp_decls ();
2982 check_usage ();
2983 check_loops_in_regexps ();
2984 if (!have_error)
2985 evaluate_max_reserv_cycles ();
2986}
2987
2988\f
2989
2990/* The page contains abstract data `ticker'. This data is used to
2991 report time of different phases of building automata. It is
2992 possibly to write a description for which automata will be built
2993 during several minutes even on fast machine. */
2994
2995/* The following function creates ticker and makes it active. */
2996static ticker_t
3d7aafde 2997create_ticker (void)
fae15c93
VM
2998{
2999 ticker_t ticker;
3000
3001 ticker.modified_creation_time = get_run_time ();
3002 ticker.incremented_off_time = 0;
3003 return ticker;
3004}
3005
3006/* The following function switches off given ticker. */
3007static void
3d7aafde 3008ticker_off (ticker_t *ticker)
fae15c93
VM
3009{
3010 if (ticker->incremented_off_time == 0)
3011 ticker->incremented_off_time = get_run_time () + 1;
3012}
3013
3014/* The following function switches on given ticker. */
3015static void
3d7aafde 3016ticker_on (ticker_t *ticker)
fae15c93
VM
3017{
3018 if (ticker->incremented_off_time != 0)
3019 {
3020 ticker->modified_creation_time
3021 += get_run_time () - ticker->incremented_off_time + 1;
3022 ticker->incremented_off_time = 0;
3023 }
3024}
3025
3026/* The following function returns current time in milliseconds since
3027 the moment when given ticker was created. */
3028static int
3d7aafde 3029active_time (ticker_t ticker)
fae15c93
VM
3030{
3031 if (ticker.incremented_off_time != 0)
3032 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3033 else
3034 return get_run_time () - ticker.modified_creation_time;
3035}
3036
3037/* The following function returns string representation of active time
3038 of given ticker. The result is string representation of seconds
3039 with accuracy of 1/100 second. Only result of the last call of the
3040 function exists. Therefore the following code is not correct
3041
3042 printf ("parser time: %s\ngeneration time: %s\n",
3043 active_time_string (parser_ticker),
3044 active_time_string (generation_ticker));
3045
3046 Correct code has to be the following
3047
3048 printf ("parser time: %s\n", active_time_string (parser_ticker));
3049 printf ("generation time: %s\n",
3050 active_time_string (generation_ticker));
3051
3052*/
3053static void
3d7aafde 3054print_active_time (FILE *f, ticker_t ticker)
fae15c93
VM
3055{
3056 int msecs;
3057
3058 msecs = active_time (ticker);
3059 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3060}
3061
3062\f
3063
3064/* The following variable value is number of automaton which are
3065 really being created. This value is defined on the base of
3066 argument of option `-split'. If the variable has zero value the
3067 number of automata is defined by the constructions `%automaton'.
96e13905 3068 This case occurs when option `-split' is absent or has zero
fae15c93
VM
3069 argument. If constructions `define_automaton' is absent only one
3070 automaton is created. */
3071static int automata_num;
3072
3073/* The following variable values are times of
3074 o transformation of regular expressions
3075 o building NDFA (DFA if !ndfa_flag)
3076 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3077 o DFA minimization
3078 o building insn equivalence classes
3079 o all previous ones
3080 o code output */
3081static ticker_t transform_time;
3082static ticker_t NDFA_time;
3083static ticker_t NDFA_to_DFA_time;
3084static ticker_t minimize_time;
3085static ticker_t equiv_time;
3086static ticker_t automaton_generation_time;
3087static ticker_t output_time;
3088
3089/* The following variable values are times of
3090 all checking
3091 all generation
3092 all pipeline hazard translator work */
3093static ticker_t check_time;
3094static ticker_t generation_time;
3095static ticker_t all_time;
3096
3097\f
3098
3099/* Pseudo insn decl which denotes advancing cycle. */
3100static decl_t advance_cycle_insn_decl;
3101static void
3d7aafde 3102add_advance_cycle_insn_decl (void)
fae15c93
VM
3103{
3104 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3105 advance_cycle_insn_decl->mode = dm_insn_reserv;
3106 advance_cycle_insn_decl->pos = no_pos;
4005971c 3107 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
1fb49ce7 3108 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
4005971c
VM
3109 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3110 = description->insns_num;
fae15c93
VM
3111 description->decls [description->decls_num] = advance_cycle_insn_decl;
3112 description->decls_num++;
3113 description->insns_num++;
fae15c93
VM
3114}
3115
3116\f
96e13905 3117/* Abstract data `alternative states' which represents
fae15c93
VM
3118 nondeterministic nature of the description (see comments for
3119 structures alt_state and state). */
3120
3121/* List of free states. */
3122static alt_state_t first_free_alt_state;
3123
3124#ifndef NDEBUG
3125/* The following variables is maximal number of allocated nodes
3126 alt_state. */
3127static int allocated_alt_states_num = 0;
3128#endif
3129
3130/* The following function returns free node alt_state. It may be new
96e13905 3131 allocated node or node freed earlier. */
3d7aafde
AJ
3132static alt_state_t
3133get_free_alt_state (void)
fae15c93
VM
3134{
3135 alt_state_t result;
3136
3137 if (first_free_alt_state != NULL)
3138 {
3139 result = first_free_alt_state;
3140 first_free_alt_state = first_free_alt_state->next_alt_state;
3141 }
3142 else
3143 {
3144#ifndef NDEBUG
3145 allocated_alt_states_num++;
3146#endif
3147 result = create_node (sizeof (struct alt_state));
3148 }
3149 result->state = NULL;
3150 result->next_alt_state = NULL;
3151 result->next_sorted_alt_state = NULL;
3152 return result;
3153}
3154
3155/* The function frees node ALT_STATE. */
3156static void
3d7aafde 3157free_alt_state (alt_state_t alt_state)
fae15c93
VM
3158{
3159 if (alt_state == NULL)
3160 return;
3161 alt_state->next_alt_state = first_free_alt_state;
3162 first_free_alt_state = alt_state;
3163}
3164
3165/* The function frees list started with node ALT_STATE_LIST. */
3166static void
3d7aafde 3167free_alt_states (alt_state_t alt_states_list)
fae15c93
VM
3168{
3169 alt_state_t curr_alt_state;
3170 alt_state_t next_alt_state;
3171
3172 for (curr_alt_state = alt_states_list;
3173 curr_alt_state != NULL;
3174 curr_alt_state = next_alt_state)
3175 {
3176 next_alt_state = curr_alt_state->next_alt_state;
3177 free_alt_state (curr_alt_state);
3178 }
3179}
3180
3181/* The function compares unique numbers of alt states. */
3182static int
3d7aafde 3183alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
fae15c93
VM
3184{
3185 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3186 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3187 return 0;
3188 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3189 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3190 return -1;
3191 else
3192 return 1;
3193}
3194
3195/* The function sorts ALT_STATES_LIST and removes duplicated alt
3196 states from the list. The comparison key is alt state unique
3197 number. */
1fb49ce7 3198
3d7aafde
AJ
3199static alt_state_t
3200uniq_sort_alt_states (alt_state_t alt_states_list)
fae15c93
VM
3201{
3202 alt_state_t curr_alt_state;
1fb49ce7 3203 VEC(alt_state_t,heap) *alt_states;
fae15c93
VM
3204 size_t i;
3205 size_t prev_unique_state_ind;
3206 alt_state_t result;
fae15c93 3207
1fb49ce7
ZW
3208 if (alt_states_list == 0)
3209 return 0;
3210 if (alt_states_list->next_alt_state == 0)
3211 return alt_states_list;
3212
3213 alt_states = VEC_alloc (alt_state_t,heap, 150);
fae15c93
VM
3214 for (curr_alt_state = alt_states_list;
3215 curr_alt_state != NULL;
3216 curr_alt_state = curr_alt_state->next_alt_state)
1fb49ce7
ZW
3217 VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
3218
3219 qsort (VEC_address (alt_state_t, alt_states),
3220 VEC_length (alt_state_t, alt_states),
fae15c93 3221 sizeof (alt_state_t), alt_state_cmp);
1fb49ce7
ZW
3222
3223 prev_unique_state_ind = 0;
3224 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3225 if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
3226 != VEC_index (alt_state_t, alt_states, i)->state)
3227 {
3228 prev_unique_state_ind++;
3229 VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
3230 VEC_index (alt_state_t, alt_states, i));
3231 }
3232 VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
3233
3234 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3235 VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
3236 = VEC_index (alt_state_t, alt_states, i);
3237 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
3238
3239 result = VEC_index (alt_state_t, alt_states, 0);
3240
3241 VEC_free (alt_state_t,heap, alt_states);
fae15c93
VM
3242 return result;
3243}
3244
3245/* The function checks equality of alt state lists. Remember that the
3246 lists must be already sorted by the previous function. */
3247static int
3d7aafde 3248alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
fae15c93
VM
3249{
3250 while (alt_states_1 != NULL && alt_states_2 != NULL
3251 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3252 {
3253 alt_states_1 = alt_states_1->next_sorted_alt_state;
3254 alt_states_2 = alt_states_2->next_sorted_alt_state;
3255 }
3256 return alt_states_1 == alt_states_2;
3257}
3258
3259/* Initialization of the abstract data. */
3260static void
3d7aafde 3261initiate_alt_states (void)
fae15c93
VM
3262{
3263 first_free_alt_state = NULL;
3264}
3265
3266/* Finishing work with the abstract data. */
3267static void
3d7aafde 3268finish_alt_states (void)
fae15c93
VM
3269{
3270}
3271
3272\f
3273
3274/* The page contains macros for work with bits strings. We could use
3275 standard gcc bitmap or sbitmap but it would result in difficulties
3276 of building canadian cross. */
3277
3278/* Set bit number bitno in the bit string. The macro is not side
3279 effect proof. */
3280#define SET_BIT(bitstring, bitno) \
3281 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3282
30028c85
VM
3283#define CLEAR_BIT(bitstring, bitno) \
3284 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3285
fae15c93
VM
3286/* Test if bit number bitno in the bitstring is set. The macro is not
3287 side effect proof. */
3288#define TEST_BIT(bitstring, bitno) \
3289 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3290
3291\f
3292
3293/* This page contains abstract data `state'. */
3294
deb09eff 3295/* Maximal length of reservations in cycles (>= 1). */
fae15c93
VM
3296static int max_cycles_num;
3297
3298/* Number of set elements (see type set_el_t) needed for
3299 representation of one cycle reservation. It is depended on units
3300 number. */
3301static int els_in_cycle_reserv;
3302
3303/* Number of set elements (see type set_el_t) needed for
3304 representation of maximal length reservation. Deterministic
3305 reservation is stored as set (bit string) of length equal to the
3306 variable value * number of bits in set_el_t. */
3307static int els_in_reservs;
3308
1fb49ce7 3309/* Array of pointers to unit declarations. */
deb09eff 3310static unit_decl_t *units_array;
fae15c93 3311
30028c85
VM
3312/* Temporary reservation of maximal length. */
3313static reserv_sets_t temp_reserv;
3314
fae15c93
VM
3315/* The state table itself is represented by the following variable. */
3316static htab_t state_table;
3317
1fb49ce7
ZW
3318/* Linked list of free 'state' structures to be recycled. The
3319 next_equiv_class_state pointer is borrowed for a free list. */
3320static state_t first_free_state;
fae15c93
VM
3321
3322static int curr_unique_state_num;
3323
3324#ifndef NDEBUG
3325/* The following variables is maximal number of allocated nodes
3326 `state'. */
3327static int allocated_states_num = 0;
3328#endif
3329
3330/* Allocate new reservation set. */
3331static reserv_sets_t
3d7aafde 3332alloc_empty_reserv_sets (void)
fae15c93
VM
3333{
3334 reserv_sets_t result;
3335
3336 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3337 result = (reserv_sets_t) obstack_base (&irp);
3338 obstack_finish (&irp);
3339 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3340 return result;
3341}
3342
3343/* Hash value of reservation set. */
3344static unsigned
3d7aafde 3345reserv_sets_hash_value (reserv_sets_t reservs)
fae15c93 3346{
dceb2b75
VM
3347 set_el_t hash_value;
3348 unsigned result;
3349 int reservs_num, i;
fae15c93
VM
3350 set_el_t *reserv_ptr;
3351
3352 hash_value = 0;
3353 reservs_num = els_in_reservs;
3354 reserv_ptr = reservs;
dceb2b75 3355 i = 0;
fae15c93
VM
3356 while (reservs_num != 0)
3357 {
3358 reservs_num--;
dceb2b75
VM
3359 hash_value += ((*reserv_ptr >> i)
3360 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3361 i++;
3362 if (i == sizeof (set_el_t) * CHAR_BIT)
3363 i = 0;
fae15c93
VM
3364 reserv_ptr++;
3365 }
96b1f73b 3366 if (sizeof (set_el_t) <= sizeof (unsigned))
dceb2b75
VM
3367 return hash_value;
3368 result = 0;
b326b2c1 3369 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
dceb2b75
VM
3370 {
3371 result += (unsigned) hash_value;
b326b2c1 3372 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
dceb2b75
VM
3373 }
3374 return result;
fae15c93
VM
3375}
3376
3377/* Comparison of given reservation sets. */
3378static int
3d7aafde 3379reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
fae15c93
VM
3380{
3381 int reservs_num;
3382 set_el_t *reserv_ptr_1;
3383 set_el_t *reserv_ptr_2;
3384
b2d59f6f 3385 gcc_assert (reservs_1 && reservs_2);
fae15c93
VM
3386 reservs_num = els_in_reservs;
3387 reserv_ptr_1 = reservs_1;
3388 reserv_ptr_2 = reservs_2;
3389 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3390 {
3391 reservs_num--;
3392 reserv_ptr_1++;
3393 reserv_ptr_2++;
3394 }
3395 if (reservs_num == 0)
3396 return 0;
3397 else if (*reserv_ptr_1 < *reserv_ptr_2)
3398 return -1;
3399 else
3400 return 1;
3401}
3402
3403/* The function checks equality of the reservation sets. */
3404static int
3d7aafde 3405reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
fae15c93
VM
3406{
3407 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3408}
3409
3410/* Set up in the reservation set that unit with UNIT_NUM is used on
3411 CYCLE_NUM. */
3412static void
3d7aafde 3413set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
fae15c93 3414{
b2d59f6f 3415 gcc_assert (cycle_num < max_cycles_num);
fae15c93
VM
3416 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3417 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3418}
3419
3420/* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3421 used on CYCLE_NUM. */
3422static int
3d7aafde 3423test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
fae15c93 3424{
b2d59f6f 3425 gcc_assert (cycle_num < max_cycles_num);
fae15c93
VM
3426 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3427 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3428}
3429
fae15c93
VM
3430/* The function checks that the reservation sets are intersected,
3431 i.e. there is a unit reservation on a cycle in both reservation
3432 sets. */
3433static int
3d7aafde
AJ
3434reserv_sets_are_intersected (reserv_sets_t operand_1,
3435 reserv_sets_t operand_2)
fae15c93
VM
3436{
3437 set_el_t *el_ptr_1;
3438 set_el_t *el_ptr_2;
3439 set_el_t *cycle_ptr_1;
3440 set_el_t *cycle_ptr_2;
fae15c93 3441
b2d59f6f 3442 gcc_assert (operand_1 && operand_2);
fae15c93
VM
3443 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3444 el_ptr_1 < operand_1 + els_in_reservs;
3445 el_ptr_1++, el_ptr_2++)
3446 if (*el_ptr_1 & *el_ptr_2)
3447 return 1;
30028c85 3448 reserv_sets_or (temp_reserv, operand_1, operand_2);
fae15c93
VM
3449 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3450 cycle_ptr_1 < operand_1 + els_in_reservs;
3451 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3452 {
3453 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3454 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3455 el_ptr_1++, el_ptr_2++)
3456 if (*el_ptr_1 & *el_ptr_2)
3457 return 1;
30028c85
VM
3458 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3459 return 1;
3460 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3461 - operand_2),
3462 cycle_ptr_2, TRUE))
3463 return 1;
3464 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3465 return 1;
3466 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3467 cycle_ptr_2, TRUE))
fae15c93 3468 return 1;
fae15c93
VM
3469 }
3470 return 0;
3471}
3472
3473/* The function sets up RESULT bits by bits of OPERAND shifted on one
3474 cpu cycle. The remaining bits of OPERAND (representing the last
fbe5a4a6 3475 cycle unit reservations) are not changed. */
fae15c93 3476static void
3d7aafde 3477reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
fae15c93
VM
3478{
3479 int i;
3480
b2d59f6f 3481 gcc_assert (result && operand && result != operand);
fae15c93
VM
3482 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3483 result [i - els_in_cycle_reserv] = operand [i];
3484}
3485
3486/* OR of the reservation sets. */
3487static void
3d7aafde
AJ
3488reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3489 reserv_sets_t operand_2)
fae15c93
VM
3490{
3491 set_el_t *el_ptr_1;
3492 set_el_t *el_ptr_2;
3493 set_el_t *result_set_el_ptr;
3494
b2d59f6f 3495 gcc_assert (result && operand_1 && operand_2);
fae15c93
VM
3496 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3497 el_ptr_1 < operand_1 + els_in_reservs;
3498 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3499 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3500}
3501
3502/* AND of the reservation sets. */
3503static void
3d7aafde
AJ
3504reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3505 reserv_sets_t operand_2)
fae15c93
VM
3506{
3507 set_el_t *el_ptr_1;
3508 set_el_t *el_ptr_2;
3509 set_el_t *result_set_el_ptr;
3510
b2d59f6f 3511 gcc_assert (result && operand_1 && operand_2);
fae15c93
VM
3512 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3513 el_ptr_1 < operand_1 + els_in_reservs;
3514 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3515 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3516}
3517
3518/* The function outputs string representation of units reservation on
3519 cycle START_CYCLE in the reservation set. The function uses repeat
3520 construction if REPETITION_NUM > 1. */
3521static void
3d7aafde
AJ
3522output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3523 int repetition_num)
fae15c93
VM
3524{
3525 int unit_num;
3526 int reserved_units_num;
3527
3528 reserved_units_num = 0;
3529 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3530 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3531 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3532 reserved_units_num++;
b2d59f6f 3533 gcc_assert (repetition_num > 0);
fae15c93
VM
3534 if (repetition_num != 1 && reserved_units_num > 1)
3535 fprintf (f, "(");
3536 reserved_units_num = 0;
3537 for (unit_num = 0;
3538 unit_num < description->units_num;
3539 unit_num++)
3540 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3541 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3542 {
3543 if (reserved_units_num != 0)
3544 fprintf (f, "+");
3545 reserved_units_num++;
3546 fprintf (f, "%s", units_array [unit_num]->name);
3547 }
3548 if (reserved_units_num == 0)
3549 fprintf (f, NOTHING_NAME);
b2d59f6f 3550 gcc_assert (repetition_num > 0);
30028c85 3551 if (repetition_num != 1 && reserved_units_num > 1)
dceb2b75
VM
3552 fprintf (f, ")");
3553 if (repetition_num != 1)
3554 fprintf (f, "*%d", repetition_num);
fae15c93
VM
3555}
3556
3557/* The function outputs string representation of units reservation in
3558 the reservation set. */
3559static void
3d7aafde 3560output_reserv_sets (FILE *f, reserv_sets_t reservs)
fae15c93
VM
3561{
3562 int start_cycle = 0;
3563 int cycle;
3564 int repetition_num;
3565
3566 repetition_num = 0;
3567 for (cycle = 0; cycle < max_cycles_num; cycle++)
3568 if (repetition_num == 0)
3569 {
3570 repetition_num++;
3571 start_cycle = cycle;
3572 }
3573 else if (memcmp
3574 ((char *) reservs + start_cycle * els_in_cycle_reserv
3575 * sizeof (set_el_t),
3576 (char *) reservs + cycle * els_in_cycle_reserv
3577 * sizeof (set_el_t),
3578 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3579 repetition_num++;
3580 else
3581 {
3582 if (start_cycle != 0)
3583 fprintf (f, ", ");
3584 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3585 repetition_num = 1;
3586 start_cycle = cycle;
3587 }
3588 if (start_cycle < max_cycles_num)
3589 {
3590 if (start_cycle != 0)
3591 fprintf (f, ", ");
3592 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3593 }
3594}
3595
3596/* The following function returns free node state for AUTOMATON. It
96e13905 3597 may be new allocated node or node freed earlier. The function also
fae15c93
VM
3598 allocates reservation set if WITH_RESERVS has nonzero value. */
3599static state_t
3d7aafde 3600get_free_state (int with_reservs, automaton_t automaton)
fae15c93
VM
3601{
3602 state_t result;
3603
b2d59f6f 3604 gcc_assert (max_cycles_num > 0 && automaton);
1fb49ce7 3605 if (first_free_state)
fae15c93 3606 {
1fb49ce7
ZW
3607 result = first_free_state;
3608 first_free_state = result->next_equiv_class_state;
3609
3610 result->next_equiv_class_state = NULL;
fae15c93
VM
3611 result->automaton = automaton;
3612 result->first_out_arc = NULL;
3613 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3614 result->it_was_placed_in_stack_for_DFA_forming = 0;
3615 result->component_states = NULL;
fae15c93
VM
3616 }
3617 else
3618 {
3619#ifndef NDEBUG
3620 allocated_states_num++;
3621#endif
3622 result = create_node (sizeof (struct state));
3623 result->automaton = automaton;
3624 result->first_out_arc = NULL;
3625 result->unique_num = curr_unique_state_num;
fae15c93
VM
3626 curr_unique_state_num++;
3627 }
3628 if (with_reservs)
3629 {
3630 if (result->reservs == NULL)
3631 result->reservs = alloc_empty_reserv_sets ();
3632 else
3633 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3634 }
3635 return result;
3636}
3637
3638/* The function frees node STATE. */
3639static void
3d7aafde 3640free_state (state_t state)
fae15c93
VM
3641{
3642 free_alt_states (state->component_states);
1fb49ce7
ZW
3643 state->next_equiv_class_state = first_free_state;
3644 first_free_state = state;
fae15c93
VM
3645}
3646
3647/* Hash value of STATE. If STATE represents deterministic state it is
3648 simply hash value of the corresponding reservation set. Otherwise
3649 it is formed from hash values of the component deterministic
3650 states. One more key is order number of state automaton. */
fb7e6024 3651static hashval_t
3d7aafde 3652state_hash (const void *state)
fae15c93
VM
3653{
3654 unsigned int hash_value;
3655 alt_state_t alt_state;
3656
3657 if (((state_t) state)->component_states == NULL)
3658 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
3659 else
3660 {
3661 hash_value = 0;
3662 for (alt_state = ((state_t) state)->component_states;
3663 alt_state != NULL;
3664 alt_state = alt_state->next_sorted_alt_state)
3665 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3666 | (hash_value << CHAR_BIT))
3667 + alt_state->state->unique_num);
3668 }
3669 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3670 | (hash_value << CHAR_BIT))
3671 + ((state_t) state)->automaton->automaton_order_num);
3672 return hash_value;
3673}
3674
3675/* Return nonzero value if the states are the same. */
3676static int
3d7aafde 3677state_eq_p (const void *state_1, const void *state_2)
fae15c93
VM
3678{
3679 alt_state_t alt_state_1;
3680 alt_state_t alt_state_2;
3681
3682 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
3683 return 0;
3684 else if (((state_t) state_1)->component_states == NULL
3685 && ((state_t) state_2)->component_states == NULL)
3686 return reserv_sets_eq (((state_t) state_1)->reservs,
3687 ((state_t) state_2)->reservs);
3688 else if (((state_t) state_1)->component_states != NULL
3689 && ((state_t) state_2)->component_states != NULL)
3690 {
3691 for (alt_state_1 = ((state_t) state_1)->component_states,
3692 alt_state_2 = ((state_t) state_2)->component_states;
3693 alt_state_1 != NULL && alt_state_2 != NULL;
3694 alt_state_1 = alt_state_1->next_sorted_alt_state,
3695 alt_state_2 = alt_state_2->next_sorted_alt_state)
3696 /* All state in the list must be already in the hash table.
3697 Also the lists must be sorted. */
3698 if (alt_state_1->state != alt_state_2->state)
3699 return 0;
3700 return alt_state_1 == alt_state_2;
3701 }
3702 else
3703 return 0;
3704}
3705
3706/* Insert STATE into the state table. */
3707static state_t
3d7aafde 3708insert_state (state_t state)
fae15c93
VM
3709{
3710 void **entry_ptr;
3711
3712 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
3713 if (*entry_ptr == NULL)
3714 *entry_ptr = (void *) state;
3715 return (state_t) *entry_ptr;
3716}
3717
3718/* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3719 deterministic STATE. */
3720static void
3d7aafde 3721set_state_reserv (state_t state, int cycle_num, int unit_num)
fae15c93
VM
3722{
3723 set_unit_reserv (state->reservs, cycle_num, unit_num);
3724}
3725
3726/* Return nonzero value if the deterministic states contains a
3727 reservation of the same cpu unit on the same cpu cycle. */
3728static int
3d7aafde 3729intersected_state_reservs_p (state_t state1, state_t state2)
fae15c93 3730{
b2d59f6f 3731 gcc_assert (state1->automaton == state2->automaton);
fae15c93
VM
3732 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3733}
3734
3735/* Return deterministic state (inserted into the table) which
30028c85
VM
3736 representing the automaton state which is union of reservations of
3737 the deterministic states masked by RESERVS. */
fae15c93 3738static state_t
3d7aafde 3739states_union (state_t state1, state_t state2, reserv_sets_t reservs)
fae15c93
VM
3740{
3741 state_t result;
3742 state_t state_in_table;
3743
b2d59f6f 3744 gcc_assert (state1->automaton == state2->automaton);
fae15c93
VM
3745 result = get_free_state (1, state1->automaton);
3746 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
30028c85 3747 reserv_sets_and (result->reservs, result->reservs, reservs);
fae15c93
VM
3748 state_in_table = insert_state (result);
3749 if (result != state_in_table)
3750 {
3751 free_state (result);
3752 result = state_in_table;
3753 }
3754 return result;
3755}
3756
3757/* Return deterministic state (inserted into the table) which
3758 represent the automaton state is obtained from deterministic STATE
30028c85 3759 by advancing cpu cycle and masking by RESERVS. */
fae15c93 3760static state_t
3d7aafde 3761state_shift (state_t state, reserv_sets_t reservs)
fae15c93
VM
3762{
3763 state_t result;
3764 state_t state_in_table;
3765
3766 result = get_free_state (1, state->automaton);
3767 reserv_sets_shift (result->reservs, state->reservs);
30028c85 3768 reserv_sets_and (result->reservs, result->reservs, reservs);
fae15c93
VM
3769 state_in_table = insert_state (result);
3770 if (result != state_in_table)
3771 {
3772 free_state (result);
3773 result = state_in_table;
3774 }
3775 return result;
3776}
3777
3778/* Initialization of the abstract data. */
3779static void
3d7aafde 3780initiate_states (void)
fae15c93
VM
3781{
3782 decl_t decl;
3783 int i;
3784
1fb49ce7 3785 if (description->units_num)
5ed6ace5 3786 units_array = XNEWVEC (unit_decl_t, description->units_num);
1fb49ce7
ZW
3787 else
3788 units_array = 0;
3789
fae15c93
VM
3790 for (i = 0; i < description->decls_num; i++)
3791 {
3792 decl = description->decls [i];
3793 if (decl->mode == dm_unit)
4005971c 3794 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
fae15c93
VM
3795 }
3796 max_cycles_num = description->max_insn_reserv_cycles;
fae15c93
VM
3797 els_in_cycle_reserv
3798 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3799 / (sizeof (set_el_t) * CHAR_BIT));
3800 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3801 curr_unique_state_num = 0;
3802 initiate_alt_states ();
fae15c93 3803 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
30028c85 3804 temp_reserv = alloc_empty_reserv_sets ();
fae15c93
VM
3805}
3806
4977bab6 3807/* Finishing work with the abstract data. */
fae15c93 3808static void
3d7aafde 3809finish_states (void)
fae15c93 3810{
1fb49ce7
ZW
3811 free (units_array);
3812 units_array = 0;
fae15c93 3813 htab_delete (state_table);
1fb49ce7 3814 first_free_state = NULL;
fae15c93
VM
3815 finish_alt_states ();
3816}
3817
3818\f
3819
3820/* Abstract data `arcs'. */
3821
3822/* List of free arcs. */
3823static arc_t first_free_arc;
3824
3825#ifndef NDEBUG
3826/* The following variables is maximal number of allocated nodes
3827 `arc'. */
3828static int allocated_arcs_num = 0;
3829#endif
3830
3831/* The function frees node ARC. */
3832static void
3d7aafde 3833free_arc (arc_t arc)
fae15c93
VM
3834{
3835 arc->next_out_arc = first_free_arc;
3836 first_free_arc = arc;
3837}
3838
3839/* The function removes and frees ARC staring from FROM_STATE. */
3840static void
3d7aafde 3841remove_arc (state_t from_state, arc_t arc)
fae15c93
VM
3842{
3843 arc_t prev_arc;
3844 arc_t curr_arc;
3845
b2d59f6f 3846 gcc_assert (arc);
fae15c93
VM
3847 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3848 curr_arc != NULL;
3849 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3850 if (curr_arc == arc)
3851 break;
b2d59f6f 3852 gcc_assert (curr_arc);
fae15c93
VM
3853 if (prev_arc == NULL)
3854 from_state->first_out_arc = arc->next_out_arc;
3855 else
3856 prev_arc->next_out_arc = arc->next_out_arc;
b6bbd675 3857 from_state->num_out_arcs--;
fae15c93
VM
3858 free_arc (arc);
3859}
3860
3861/* The functions returns arc with given characteristics (or NULL if
3862 the arc does not exist). */
3863static arc_t
3d7aafde 3864find_arc (state_t from_state, state_t to_state, ainsn_t insn)
fae15c93
VM
3865{
3866 arc_t arc;
3867
3868 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3869 if (arc->to_state == to_state && arc->insn == insn)
3870 return arc;
3871 return NULL;
3872}
3873
8c94f366
ZW
3874/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN.
3875 The function returns added arc (or already existing arc). */
fae15c93 3876static arc_t
8c94f366 3877add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
fae15c93
VM
3878{
3879 arc_t new_arc;
3880
3881 new_arc = find_arc (from_state, to_state, ainsn);
3882 if (new_arc != NULL)
3883 return new_arc;
3884 if (first_free_arc == NULL)
3885 {
3886#ifndef NDEBUG
3887 allocated_arcs_num++;
3888#endif
3889 new_arc = create_node (sizeof (struct arc));
3890 new_arc->to_state = NULL;
3891 new_arc->insn = NULL;
3892 new_arc->next_out_arc = NULL;
3893 }
3894 else
3895 {
3896 new_arc = first_free_arc;
3897 first_free_arc = first_free_arc->next_out_arc;
3898 }
3899 new_arc->to_state = to_state;
3900 new_arc->insn = ainsn;
3901 ainsn->arc_exists_p = 1;
3902 new_arc->next_out_arc = from_state->first_out_arc;
3903 from_state->first_out_arc = new_arc;
b6bbd675 3904 from_state->num_out_arcs++;
fae15c93 3905 new_arc->next_arc_marked_by_insn = NULL;
fae15c93
VM
3906 return new_arc;
3907}
3908
3909/* The function returns the first arc starting from STATE. */
3910static arc_t
3d7aafde 3911first_out_arc (state_t state)
fae15c93
VM
3912{
3913 return state->first_out_arc;
3914}
3915
3916/* The function returns next out arc after ARC. */
3917static arc_t
3d7aafde 3918next_out_arc (arc_t arc)
fae15c93
VM
3919{
3920 return arc->next_out_arc;
3921}
3922
3923/* Initialization of the abstract data. */
3924static void
3d7aafde 3925initiate_arcs (void)
fae15c93
VM
3926{
3927 first_free_arc = NULL;
3928}
3929
3930/* Finishing work with the abstract data. */
3931static void
3d7aafde 3932finish_arcs (void)
fae15c93
VM
3933{
3934}
3935
3936\f
3937
3938/* Abstract data `automata lists'. */
3939
3940/* List of free states. */
3941static automata_list_el_t first_free_automata_list_el;
3942
3943/* The list being formed. */
3944static automata_list_el_t current_automata_list;
3945
3946/* Hash table of automata lists. */
3947static htab_t automata_list_table;
3948
3949/* The following function returns free automata list el. It may be
3950 new allocated node or node freed earlier. */
3d7aafde
AJ
3951static automata_list_el_t
3952get_free_automata_list_el (void)
fae15c93
VM
3953{
3954 automata_list_el_t result;
3955
3956 if (first_free_automata_list_el != NULL)
3957 {
3958 result = first_free_automata_list_el;
3959 first_free_automata_list_el
3960 = first_free_automata_list_el->next_automata_list_el;
3961 }
3962 else
3963 result = create_node (sizeof (struct automata_list_el));
3964 result->automaton = NULL;
3965 result->next_automata_list_el = NULL;
3966 return result;
3967}
3968
3969/* The function frees node AUTOMATA_LIST_EL. */
3970static void
3d7aafde 3971free_automata_list_el (automata_list_el_t automata_list_el)
fae15c93
VM
3972{
3973 if (automata_list_el == NULL)
3974 return;
3975 automata_list_el->next_automata_list_el = first_free_automata_list_el;
3976 first_free_automata_list_el = automata_list_el;
3977}
3978
3979/* The function frees list AUTOMATA_LIST. */
3980static void
3d7aafde 3981free_automata_list (automata_list_el_t automata_list)
fae15c93
VM
3982{
3983 automata_list_el_t curr_automata_list_el;
3984 automata_list_el_t next_automata_list_el;
3985
3986 for (curr_automata_list_el = automata_list;
3987 curr_automata_list_el != NULL;
3988 curr_automata_list_el = next_automata_list_el)
3989 {
3990 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
3991 free_automata_list_el (curr_automata_list_el);
3992 }
3993}
3994
3995/* Hash value of AUTOMATA_LIST. */
fb7e6024 3996static hashval_t
3d7aafde 3997automata_list_hash (const void *automata_list)
fae15c93
VM
3998{
3999 unsigned int hash_value;
4000 automata_list_el_t curr_automata_list_el;
4001
4002 hash_value = 0;
4003 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4004 curr_automata_list_el != NULL;
4005 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4006 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4007 | (hash_value << CHAR_BIT))
4008 + curr_automata_list_el->automaton->automaton_order_num);
4009 return hash_value;
4010}
4011
4012/* Return nonzero value if the automata_lists are the same. */
4013static int
3d7aafde 4014automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
fae15c93
VM
4015{
4016 automata_list_el_t automata_list_el_1;
4017 automata_list_el_t automata_list_el_2;
4018
4019 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4020 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4021 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4022 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4023 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4024 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4025 return 0;
4026 return automata_list_el_1 == automata_list_el_2;
4027}
4028
4029/* Initialization of the abstract data. */
4030static void
3d7aafde 4031initiate_automata_lists (void)
fae15c93
VM
4032{
4033 first_free_automata_list_el = NULL;
4034 automata_list_table = htab_create (1500, automata_list_hash,
4035 automata_list_eq_p, (htab_del) 0);
4036}
4037
4038/* The following function starts new automata list and makes it the
4039 current one. */
4040static void
3d7aafde 4041automata_list_start (void)
fae15c93
VM
4042{
4043 current_automata_list = NULL;
4044}
4045
4046/* The following function adds AUTOMATON to the current list. */
4047static void
3d7aafde 4048automata_list_add (automaton_t automaton)
fae15c93
VM
4049{
4050 automata_list_el_t el;
4051
4052 el = get_free_automata_list_el ();
4053 el->automaton = automaton;
4054 el->next_automata_list_el = current_automata_list;
4055 current_automata_list = el;
4056}
4057
4058/* The following function finishes forming the current list, inserts
4059 it into the table and returns it. */
4060static automata_list_el_t
3d7aafde 4061automata_list_finish (void)
fae15c93
VM
4062{
4063 void **entry_ptr;
4064
4065 if (current_automata_list == NULL)
4066 return NULL;
4067 entry_ptr = htab_find_slot (automata_list_table,
4068 (void *) current_automata_list, 1);
4069 if (*entry_ptr == NULL)
4070 *entry_ptr = (void *) current_automata_list;
4071 else
4072 free_automata_list (current_automata_list);
4073 current_automata_list = NULL;
4074 return (automata_list_el_t) *entry_ptr;
4075}
4076
4077/* Finishing work with the abstract data. */
4078static void
3d7aafde 4079finish_automata_lists (void)
fae15c93
VM
4080{
4081 htab_delete (automata_list_table);
4082}
4083
4084\f
4085
4086/* The page contains abstract data for work with exclusion sets (see
4087 exclusion_set in file rtl.def). */
4088
4089/* The following variable refers to an exclusion set returned by
4090 get_excl_set. This is bit string of length equal to cpu units
4091 number. If exclusion set for given unit contains 1 for a unit,
4092 then simultaneous reservation of the units is prohibited. */
4093static reserv_sets_t excl_set;
4094
4095/* The array contains exclusion sets for each unit. */
4096static reserv_sets_t *unit_excl_set_table;
4097
4098/* The following function forms the array containing exclusion sets
4099 for each unit. */
4100static void
3d7aafde 4101initiate_excl_sets (void)
fae15c93
VM
4102{
4103 decl_t decl;
4104 reserv_sets_t unit_excl_set;
4105 unit_set_el_t el;
4106 int i;
4107
4108 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4109 excl_set = (reserv_sets_t) obstack_base (&irp);
4110 obstack_finish (&irp);
4111 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4112 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4113 obstack_finish (&irp);
4114 /* Evaluate unit exclusion sets. */
4115 for (i = 0; i < description->decls_num; i++)
4116 {
4117 decl = description->decls [i];
4118 if (decl->mode == dm_unit)
4119 {
4120 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4121 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4122 obstack_finish (&irp);
4123 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4005971c 4124 for (el = DECL_UNIT (decl)->excl_list;
fae15c93
VM
4125 el != NULL;
4126 el = el->next_unit_set_el)
30028c85
VM
4127 {
4128 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4129 el->unit_decl->in_set_p = TRUE;
4130 }
4005971c 4131 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
fae15c93
VM
4132 }
4133 }
4134}
4135
4136/* The function sets up and return EXCL_SET which is union of
4137 exclusion sets for each unit in IN_SET. */
4138static reserv_sets_t
3d7aafde 4139get_excl_set (reserv_sets_t in_set)
fae15c93
VM
4140{
4141 int excl_char_num;
4142 int chars_num;
4143 int i;
4144 int start_unit_num;
4145 int unit_num;
4146
4147 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4148 memset (excl_set, 0, chars_num);
4149 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4150 if (((unsigned char *) in_set) [excl_char_num])
4151 for (i = CHAR_BIT - 1; i >= 0; i--)
4152 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4153 {
4154 start_unit_num = excl_char_num * CHAR_BIT + i;
4155 if (start_unit_num >= description->units_num)
4156 return excl_set;
4157 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4158 {
4159 excl_set [unit_num]
4160 |= unit_excl_set_table [start_unit_num] [unit_num];
4161 }
4162 }
4163 return excl_set;
4164}
4165
4166\f
4167
30028c85
VM
4168/* The page contains abstract data for work with presence/absence
4169 pattern sets (see presence_set/absence_set in file rtl.def). */
fae15c93 4170
30028c85
VM
4171/* The following arrays contain correspondingly presence, final
4172 presence, absence, and final absence patterns for each unit. */
4173static pattern_reserv_t *unit_presence_set_table;
4174static pattern_reserv_t *unit_final_presence_set_table;
4175static pattern_reserv_t *unit_absence_set_table;
4176static pattern_reserv_t *unit_final_absence_set_table;
4177
4178/* The following function forms list of reservation sets for given
4179 PATTERN_LIST. */
4180static pattern_reserv_t
3d7aafde 4181form_reserv_sets_list (pattern_set_el_t pattern_list)
30028c85
VM
4182{
4183 pattern_set_el_t el;
4184 pattern_reserv_t first, curr, prev;
4185 int i;
fae15c93 4186
30028c85
VM
4187 prev = first = NULL;
4188 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4189 {
4190 curr = create_node (sizeof (struct pattern_reserv));
4191 curr->reserv = alloc_empty_reserv_sets ();
4192 curr->next_pattern_reserv = NULL;
4193 for (i = 0; i < el->units_num; i++)
4194 {
4195 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4196 el->unit_decls [i]->in_set_p = TRUE;
4197 }
4198 if (prev != NULL)
4199 prev->next_pattern_reserv = curr;
4200 else
4201 first = curr;
4202 prev = curr;
4203 }
4204 return first;
4205}
fae15c93 4206
30028c85
VM
4207 /* The following function forms the array containing presence and
4208 absence pattern sets for each unit. */
fae15c93 4209static void
3d7aafde 4210initiate_presence_absence_pattern_sets (void)
fae15c93
VM
4211{
4212 decl_t decl;
fae15c93
VM
4213 int i;
4214
30028c85
VM
4215 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4216 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
fae15c93 4217 obstack_finish (&irp);
30028c85
VM
4218 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4219 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
fae15c93 4220 obstack_finish (&irp);
30028c85
VM
4221 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4222 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
fae15c93 4223 obstack_finish (&irp);
30028c85
VM
4224 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4225 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
fae15c93
VM
4226 obstack_finish (&irp);
4227 /* Evaluate unit presence/absence sets. */
4228 for (i = 0; i < description->decls_num; i++)
4229 {
4230 decl = description->decls [i];
4231 if (decl->mode == dm_unit)
4232 {
30028c85
VM
4233 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4234 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4235 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4236 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4237 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4238 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4239 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4240 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
fae15c93
VM
4241 }
4242 }
4243}
4244
30028c85
VM
4245/* The function checks that CHECKED_SET satisfies all presence pattern
4246 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4247 is ok. */
4248static int
3d7aafde
AJ
4249check_presence_pattern_sets (reserv_sets_t checked_set,
4250 reserv_sets_t origional_set,
4251 int final_p)
fae15c93
VM
4252{
4253 int char_num;
4254 int chars_num;
4255 int i;
4256 int start_unit_num;
4257 int unit_num;
30028c85
VM
4258 int presence_p;
4259 pattern_reserv_t pat_reserv;
3d7aafde 4260
30028c85
VM
4261 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4262 for (char_num = 0; char_num < chars_num; char_num++)
4263 if (((unsigned char *) origional_set) [char_num])
4264 for (i = CHAR_BIT - 1; i >= 0; i--)
4265 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4266 {
4267 start_unit_num = char_num * CHAR_BIT + i;
4268 if (start_unit_num >= description->units_num)
4269 break;
4270 if ((final_p
4271 && unit_final_presence_set_table [start_unit_num] == NULL)
4272 || (!final_p
4273 && unit_presence_set_table [start_unit_num] == NULL))
4274 continue;
4275 presence_p = FALSE;
4276 for (pat_reserv = (final_p
4277 ? unit_final_presence_set_table [start_unit_num]
4278 : unit_presence_set_table [start_unit_num]);
4279 pat_reserv != NULL;
4280 pat_reserv = pat_reserv->next_pattern_reserv)
4281 {
4282 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4283 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4284 != pat_reserv->reserv [unit_num])
4285 break;
4286 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4287 }
4288 if (!presence_p)
4289 return FALSE;
4290 }
4291 return TRUE;
4292}
fae15c93 4293
30028c85
VM
4294/* The function checks that CHECKED_SET satisfies all absence pattern
4295 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4296 is ok. */
4297static int
3d7aafde
AJ
4298check_absence_pattern_sets (reserv_sets_t checked_set,
4299 reserv_sets_t origional_set,
4300 int final_p)
30028c85
VM
4301{
4302 int char_num;
4303 int chars_num;
4304 int i;
4305 int start_unit_num;
4306 int unit_num;
4307 pattern_reserv_t pat_reserv;
3d7aafde 4308
fae15c93 4309 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
fae15c93 4310 for (char_num = 0; char_num < chars_num; char_num++)
30028c85 4311 if (((unsigned char *) origional_set) [char_num])
fae15c93 4312 for (i = CHAR_BIT - 1; i >= 0; i--)
30028c85 4313 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
fae15c93
VM
4314 {
4315 start_unit_num = char_num * CHAR_BIT + i;
4316 if (start_unit_num >= description->units_num)
30028c85
VM
4317 break;
4318 for (pat_reserv = (final_p
4319 ? unit_final_absence_set_table [start_unit_num]
4320 : unit_absence_set_table [start_unit_num]);
4321 pat_reserv != NULL;
4322 pat_reserv = pat_reserv->next_pattern_reserv)
4323 {
4324 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4325 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4326 != pat_reserv->reserv [unit_num]
4327 && pat_reserv->reserv [unit_num])
4328 break;
4329 if (unit_num >= els_in_cycle_reserv)
4330 return FALSE;
4331 }
fae15c93 4332 }
30028c85 4333 return TRUE;
fae15c93
VM
4334}
4335
4336\f
4337
4338/* This page contains code for transformation of original reservations
4339 described in .md file. The main goal of transformations is
4340 simplifying reservation and lifting up all `|' on the top of IR
4341 reservation representation. */
4342
4343
4344/* The following function makes copy of IR representation of
4345 reservation. The function also substitutes all reservations
4346 defined by define_reservation by corresponding value during making
4347 the copy. */
4348static regexp_t
3d7aafde 4349copy_insn_regexp (regexp_t regexp)
fae15c93
VM
4350{
4351 regexp_t result;
4352 int i;
4353
b2d59f6f 4354 switch (regexp->mode)
fae15c93 4355 {
b2d59f6f
NS
4356 case rm_reserv:
4357 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4358 break;
4359
4360 case rm_unit:
4361 result = copy_node (regexp, sizeof (struct regexp));
4362 break;
4363
4364 case rm_repeat:
fae15c93 4365 result = copy_node (regexp, sizeof (struct regexp));
4005971c
VM
4366 REGEXP_REPEAT (result)->regexp
4367 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
b2d59f6f
NS
4368 break;
4369
4370 case rm_sequence:
fae15c93
VM
4371 result = copy_node (regexp,
4372 sizeof (struct regexp) + sizeof (regexp_t)
4005971c
VM
4373 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4374 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4375 REGEXP_SEQUENCE (result)->regexps [i]
4376 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
b2d59f6f
NS
4377 break;
4378
4379 case rm_allof:
fae15c93
VM
4380 result = copy_node (regexp,
4381 sizeof (struct regexp) + sizeof (regexp_t)
4005971c
VM
4382 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4383 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4384 REGEXP_ALLOF (result)->regexps [i]
4385 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
b2d59f6f
NS
4386 break;
4387
4388 case rm_oneof:
fae15c93
VM
4389 result = copy_node (regexp,
4390 sizeof (struct regexp) + sizeof (regexp_t)
4005971c
VM
4391 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4392 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4393 REGEXP_ONEOF (result)->regexps [i]
4394 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
b2d59f6f
NS
4395 break;
4396
4397 case rm_nothing:
fae15c93 4398 result = copy_node (regexp, sizeof (struct regexp));
b2d59f6f
NS
4399 break;
4400
4401 default:
4402 gcc_unreachable ();
fae15c93
VM
4403 }
4404 return result;
4405}
4406
4407/* The following variable is set up 1 if a transformation has been
4408 applied. */
4409static int regexp_transformed_p;
4410
4411/* The function makes transformation
4412 A*N -> A, A, ... */
4413static regexp_t
3d7aafde 4414transform_1 (regexp_t regexp)
fae15c93
VM
4415{
4416 int i;
4417 int repeat_num;
4418 regexp_t operand;
4419 pos_t pos;
4420
4421 if (regexp->mode == rm_repeat)
4422 {
4005971c 4423 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
b2d59f6f 4424 gcc_assert (repeat_num > 1);
4005971c 4425 operand = REGEXP_REPEAT (regexp)->regexp;
fae15c93
VM
4426 pos = regexp->mode;
4427 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4428 * (repeat_num - 1));
4429 regexp->mode = rm_sequence;
4430 regexp->pos = pos;
4005971c 4431 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
fae15c93 4432 for (i = 0; i < repeat_num; i++)
4005971c 4433 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
fae15c93
VM
4434 regexp_transformed_p = 1;
4435 }
4436 return regexp;
4437}
4438
4439/* The function makes transformations
4440 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4441 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4442 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4443static regexp_t
3d7aafde 4444transform_2 (regexp_t regexp)
fae15c93
VM
4445{
4446 if (regexp->mode == rm_sequence)
4447 {
e3c8eb86 4448 regexp_t sequence = NULL;
fae15c93 4449 regexp_t result;
e3c8eb86 4450 int sequence_index = 0;
fae15c93
VM
4451 int i, j;
4452
4005971c
VM
4453 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4454 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
fae15c93
VM
4455 {
4456 sequence_index = i;
4005971c 4457 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
fae15c93
VM
4458 break;
4459 }
4005971c 4460 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
fae15c93 4461 {
b2d59f6f
NS
4462 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4463 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
fae15c93
VM
4464 result = create_node (sizeof (struct regexp)
4465 + sizeof (regexp_t)
4005971c
VM
4466 * (REGEXP_SEQUENCE (regexp)->regexps_num
4467 + REGEXP_SEQUENCE (sequence)->regexps_num
fae15c93
VM
4468 - 2));
4469 result->mode = rm_sequence;
4470 result->pos = regexp->pos;
4005971c
VM
4471 REGEXP_SEQUENCE (result)->regexps_num
4472 = (REGEXP_SEQUENCE (regexp)->regexps_num
4473 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4474 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
fae15c93 4475 if (i < sequence_index)
4005971c
VM
4476 REGEXP_SEQUENCE (result)->regexps [i]
4477 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
fae15c93 4478 else if (i > sequence_index)
4005971c
VM
4479 REGEXP_SEQUENCE (result)->regexps
4480 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4481 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
fae15c93 4482 else
4005971c
VM
4483 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4484 REGEXP_SEQUENCE (result)->regexps [i + j]
4485 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
fae15c93
VM
4486 regexp_transformed_p = 1;
4487 regexp = result;
4488 }
4489 }
4490 else if (regexp->mode == rm_allof)
4491 {
e3c8eb86 4492 regexp_t allof = NULL;
fae15c93 4493 regexp_t result;
e3c8eb86 4494 int allof_index = 0;
fae15c93
VM
4495 int i, j;
4496
4005971c
VM
4497 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4498 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
fae15c93
VM
4499 {
4500 allof_index = i;
4005971c 4501 allof = REGEXP_ALLOF (regexp)->regexps [i];
fae15c93
VM
4502 break;
4503 }
4005971c 4504 if (i < REGEXP_ALLOF (regexp)->regexps_num)
fae15c93 4505 {
b2d59f6f
NS
4506 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4507 && REGEXP_ALLOF (regexp)->regexps_num > 1);
fae15c93
VM
4508 result = create_node (sizeof (struct regexp)
4509 + sizeof (regexp_t)
4005971c
VM
4510 * (REGEXP_ALLOF (regexp)->regexps_num
4511 + REGEXP_ALLOF (allof)->regexps_num - 2));
fae15c93
VM
4512 result->mode = rm_allof;
4513 result->pos = regexp->pos;
4005971c
VM
4514 REGEXP_ALLOF (result)->regexps_num
4515 = (REGEXP_ALLOF (regexp)->regexps_num
4516 + REGEXP_ALLOF (allof)->regexps_num - 1);
4517 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
fae15c93 4518 if (i < allof_index)
4005971c
VM
4519 REGEXP_ALLOF (result)->regexps [i]
4520 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
fae15c93 4521 else if (i > allof_index)
4005971c
VM
4522 REGEXP_ALLOF (result)->regexps
4523 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4524 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
fae15c93 4525 else
4005971c
VM
4526 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4527 REGEXP_ALLOF (result)->regexps [i + j]
4528 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
fae15c93
VM
4529 regexp_transformed_p = 1;
4530 regexp = result;
4531 }
4532 }
4533 else if (regexp->mode == rm_oneof)
4534 {
e3c8eb86 4535 regexp_t oneof = NULL;
fae15c93 4536 regexp_t result;
e3c8eb86 4537 int oneof_index = 0;
fae15c93
VM
4538 int i, j;
4539
4005971c
VM
4540 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4541 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
fae15c93
VM
4542 {
4543 oneof_index = i;
4005971c 4544 oneof = REGEXP_ONEOF (regexp)->regexps [i];
fae15c93
VM
4545 break;
4546 }
4005971c 4547 if (i < REGEXP_ONEOF (regexp)->regexps_num)
fae15c93 4548 {
b2d59f6f
NS
4549 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4550 && REGEXP_ONEOF (regexp)->regexps_num > 1);
fae15c93
VM
4551 result = create_node (sizeof (struct regexp)
4552 + sizeof (regexp_t)
4005971c
VM
4553 * (REGEXP_ONEOF (regexp)->regexps_num
4554 + REGEXP_ONEOF (oneof)->regexps_num - 2));
fae15c93
VM
4555 result->mode = rm_oneof;
4556 result->pos = regexp->pos;
4005971c
VM
4557 REGEXP_ONEOF (result)->regexps_num
4558 = (REGEXP_ONEOF (regexp)->regexps_num
4559 + REGEXP_ONEOF (oneof)->regexps_num - 1);
4560 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
fae15c93 4561 if (i < oneof_index)
4005971c
VM
4562 REGEXP_ONEOF (result)->regexps [i]
4563 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
fae15c93 4564 else if (i > oneof_index)
4005971c
VM
4565 REGEXP_ONEOF (result)->regexps
4566 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
4567 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
fae15c93 4568 else
4005971c
VM
4569 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
4570 REGEXP_ONEOF (result)->regexps [i + j]
4571 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
fae15c93
VM
4572 regexp_transformed_p = 1;
4573 regexp = result;
4574 }
4575 }
4576 return regexp;
4577}
4578
4579/* The function makes transformations
4580 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
317638a8 4581 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
dceb2b75
VM
4582 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4583 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
fae15c93 4584static regexp_t
3d7aafde 4585transform_3 (regexp_t regexp)
fae15c93
VM
4586{
4587 if (regexp->mode == rm_sequence)
4588 {
e3c8eb86
VM
4589 regexp_t oneof = NULL;
4590 int oneof_index = 0;
fae15c93
VM
4591 regexp_t result;
4592 regexp_t sequence;
4593 int i, j;
4594
4005971c
VM
4595 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4596 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
fae15c93
VM
4597 {
4598 oneof_index = i;
4005971c 4599 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
fae15c93
VM
4600 break;
4601 }
4005971c 4602 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
fae15c93 4603 {
b2d59f6f
NS
4604 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4605 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
fae15c93
VM
4606 result = create_node (sizeof (struct regexp)
4607 + sizeof (regexp_t)
4005971c 4608 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
fae15c93
VM
4609 result->mode = rm_oneof;
4610 result->pos = regexp->pos;
4005971c
VM
4611 REGEXP_ONEOF (result)->regexps_num
4612 = REGEXP_ONEOF (oneof)->regexps_num;
4613 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
fae15c93
VM
4614 {
4615 sequence
4616 = create_node (sizeof (struct regexp)
4617 + sizeof (regexp_t)
4005971c 4618 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
fae15c93
VM
4619 sequence->mode = rm_sequence;
4620 sequence->pos = regexp->pos;
4005971c
VM
4621 REGEXP_SEQUENCE (sequence)->regexps_num
4622 = REGEXP_SEQUENCE (regexp)->regexps_num;
4623 REGEXP_ONEOF (result)->regexps [i] = sequence;
4624 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
fae15c93 4625 if (j != oneof_index)
4005971c
VM
4626 REGEXP_SEQUENCE (sequence)->regexps [j]
4627 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
fae15c93 4628 else
4005971c
VM
4629 REGEXP_SEQUENCE (sequence)->regexps [j]
4630 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
fae15c93
VM
4631 }
4632 regexp_transformed_p = 1;
4633 regexp = result;
4634 }
4635 }
4636 else if (regexp->mode == rm_allof)
4637 {
30028c85
VM
4638 regexp_t oneof = NULL;
4639 regexp_t seq;
4640 int oneof_index = 0;
4641 int max_seq_length, allof_length;
fae15c93 4642 regexp_t result;
30028c85
VM
4643 regexp_t allof = NULL;
4644 regexp_t allof_op = NULL;
fae15c93
VM
4645 int i, j;
4646
4005971c
VM
4647 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4648 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
fae15c93
VM
4649 {
4650 oneof_index = i;
4005971c 4651 oneof = REGEXP_ALLOF (regexp)->regexps [i];
fae15c93
VM
4652 break;
4653 }
4005971c 4654 if (i < REGEXP_ALLOF (regexp)->regexps_num)
fae15c93 4655 {
b2d59f6f
NS
4656 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4657 && REGEXP_ALLOF (regexp)->regexps_num > 1);
fae15c93
VM
4658 result = create_node (sizeof (struct regexp)
4659 + sizeof (regexp_t)
4005971c 4660 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
fae15c93
VM
4661 result->mode = rm_oneof;
4662 result->pos = regexp->pos;
4005971c
VM
4663 REGEXP_ONEOF (result)->regexps_num
4664 = REGEXP_ONEOF (oneof)->regexps_num;
4665 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
fae15c93
VM
4666 {
4667 allof
4668 = create_node (sizeof (struct regexp)
4669 + sizeof (regexp_t)
4005971c 4670 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
fae15c93
VM
4671 allof->mode = rm_allof;
4672 allof->pos = regexp->pos;
4005971c
VM
4673 REGEXP_ALLOF (allof)->regexps_num
4674 = REGEXP_ALLOF (regexp)->regexps_num;
4675 REGEXP_ONEOF (result)->regexps [i] = allof;
4676 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
fae15c93 4677 if (j != oneof_index)
4005971c
VM
4678 REGEXP_ALLOF (allof)->regexps [j]
4679 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
fae15c93 4680 else
4005971c
VM
4681 REGEXP_ALLOF (allof)->regexps [j]
4682 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
fae15c93
VM
4683 }
4684 regexp_transformed_p = 1;
4685 regexp = result;
4686 }
dceb2b75 4687 max_seq_length = 0;
4005971c
VM
4688 if (regexp->mode == rm_allof)
4689 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
dd1b7476 4690 {
b2d59f6f 4691 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
dd1b7476 4692 {
b2d59f6f 4693 case rm_sequence:
dd1b7476
KG
4694 seq = REGEXP_ALLOF (regexp)->regexps [i];
4695 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
4696 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
dd1b7476 4697 break;
b2d59f6f
NS
4698
4699 case rm_unit:
4700 case rm_nothing:
4701 break;
4702
4703 default:
4704 max_seq_length = 0;
4705 goto break_for;
dd1b7476
KG
4706 }
4707 }
b2d59f6f 4708 break_for:
dceb2b75 4709 if (max_seq_length != 0)
317638a8 4710 {
b2d59f6f
NS
4711 gcc_assert (max_seq_length != 1
4712 && REGEXP_ALLOF (regexp)->regexps_num > 1);
317638a8 4713 result = create_node (sizeof (struct regexp)
dceb2b75 4714 + sizeof (regexp_t) * (max_seq_length - 1));
317638a8
VM
4715 result->mode = rm_sequence;
4716 result->pos = regexp->pos;
4005971c 4717 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
dceb2b75
VM
4718 for (i = 0; i < max_seq_length; i++)
4719 {
4720 allof_length = 0;
4005971c 4721 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
b2d59f6f 4722 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
dceb2b75 4723 {
b2d59f6f
NS
4724 case rm_sequence:
4725 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4726 ->regexps [j])->regexps_num))
4727 {
4728 allof_op
4729 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4730 ->regexps [j])
4731 ->regexps [i]);
4732 allof_length++;
4733 }
4734 break;
4735 case rm_unit:
4736 case rm_nothing:
4737 if (i == 0)
4738 {
4739 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4740 allof_length++;
4741 }
4742 break;
4743 default:
4744 break;
dceb2b75 4745 }
b2d59f6f 4746
dceb2b75 4747 if (allof_length == 1)
4005971c 4748 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
dceb2b75
VM
4749 else
4750 {
4751 allof = create_node (sizeof (struct regexp)
4752 + sizeof (regexp_t)
4753 * (allof_length - 1));
4754 allof->mode = rm_allof;
4755 allof->pos = regexp->pos;
4005971c
VM
4756 REGEXP_ALLOF (allof)->regexps_num = allof_length;
4757 REGEXP_SEQUENCE (result)->regexps [i] = allof;
dceb2b75 4758 allof_length = 0;
4005971c
VM
4759 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
4760 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
4761 && (i <
4762 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4763 ->regexps [j])->regexps_num)))
dceb2b75 4764 {
4005971c
VM
4765 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4766 ->regexps [j])
4767 ->regexps [i]);
4768 REGEXP_ALLOF (allof)->regexps [allof_length]
4769 = allof_op;
dceb2b75
VM
4770 allof_length++;
4771 }
4772 else if (i == 0
4005971c 4773 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
30028c85
VM
4774 == rm_unit
4775 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
4776 == rm_nothing)))
dceb2b75 4777 {
4005971c
VM
4778 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4779 REGEXP_ALLOF (allof)->regexps [allof_length]
4780 = allof_op;
dceb2b75
VM
4781 allof_length++;
4782 }
4783 }
4784 }
317638a8
VM
4785 regexp_transformed_p = 1;
4786 regexp = result;
4787 }
fae15c93
VM
4788 }
4789 return regexp;
4790}
4791
4792/* The function traverses IR of reservation and applies transformations
4793 implemented by FUNC. */
4794static regexp_t
3d7aafde 4795regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
fae15c93
VM
4796{
4797 int i;
4798
b2d59f6f
NS
4799 switch (regexp->mode)
4800 {
4801 case rm_sequence:
4802 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4803 REGEXP_SEQUENCE (regexp)->regexps [i]
4804 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
4805 func);
4806 break;
4807
4808 case rm_allof:
4809 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4810 REGEXP_ALLOF (regexp)->regexps [i]
4811 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
4812 break;
4813
4814 case rm_oneof:
4815 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4816 REGEXP_ONEOF (regexp)->regexps [i]
4817 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
4818 break;
4819
4820 case rm_repeat:
4821 REGEXP_REPEAT (regexp)->regexp
4822 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
4823 break;
4824
4825 case rm_nothing:
4826 case rm_unit:
4827 break;
4828
4829 default:
4830 gcc_unreachable ();
4831 }
fae15c93
VM
4832 return (*func) (regexp);
4833}
4834
4835/* The function applies all transformations for IR representation of
4836 reservation REGEXP. */
4837static regexp_t
3d7aafde 4838transform_regexp (regexp_t regexp)
fae15c93 4839{
3d7aafde 4840 regexp = regexp_transform_func (regexp, transform_1);
fae15c93
VM
4841 do
4842 {
4843 regexp_transformed_p = 0;
4844 regexp = regexp_transform_func (regexp, transform_2);
4845 regexp = regexp_transform_func (regexp, transform_3);
4846 }
4847 while (regexp_transformed_p);
4848 return regexp;
4849}
4850
fbe5a4a6 4851/* The function applies all transformations for reservations of all
fae15c93
VM
4852 insn declarations. */
4853static void
3d7aafde 4854transform_insn_regexps (void)
fae15c93
VM
4855{
4856 decl_t decl;
4857 int i;
4858
deb09eff
VM
4859 transform_time = create_ticker ();
4860 add_advance_cycle_insn_decl ();
dfa849f3
VM
4861 if (progress_flag)
4862 fprintf (stderr, "Reservation transformation...");
fae15c93
VM
4863 for (i = 0; i < description->decls_num; i++)
4864 {
4865 decl = description->decls [i];
4866 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4005971c 4867 DECL_INSN_RESERV (decl)->transformed_regexp
fae15c93 4868 = transform_regexp (copy_insn_regexp
4005971c 4869 (DECL_INSN_RESERV (decl)->regexp));
fae15c93 4870 }
dfa849f3
VM
4871 if (progress_flag)
4872 fprintf (stderr, "done\n");
deb09eff 4873 ticker_off (&transform_time);
deb09eff
VM
4874}
4875
4876\f
4877
30028c85
VM
4878/* The following variable value is TRUE if the first annotated message
4879 about units to automata distribution has been output. */
4880static int annotation_message_reported_p;
deb09eff 4881
1b1f249d
VM
4882/* The following structure describes usage of a unit in a reservation. */
4883struct unit_usage
4884{
4885 unit_decl_t unit_decl;
4886 /* The following forms a list of units used on the same cycle in the
4887 same alternative. */
4888 struct unit_usage *next;
4889};
1fb49ce7
ZW
4890typedef struct unit_usage *unit_usage_t;
4891
4892DEF_VEC_P(unit_usage_t);
4893DEF_VEC_ALLOC_P(unit_usage_t,heap);
1b1f249d
VM
4894
4895/* Obstack for unit_usage structures. */
4896static struct obstack unit_usages;
4897
4898/* VLA for representation of array of pointers to unit usage
4899 structures. There is an element for each combination of
4900 (alternative number, cycle). Unit usages on given cycle in
4901 alternative with given number are referred through element with
4902 index equals to the cycle * number of all alternatives in the regexp
4903 + the alternative number. */
1fb49ce7 4904static VEC(unit_usage_t,heap) *cycle_alt_unit_usages;
1b1f249d
VM
4905
4906/* The following function creates the structure unit_usage for UNIT on
4907 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
4908 accessed through cycle_alt_unit_usages. */
deb09eff 4909static void
3d7aafde
AJ
4910store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
4911 int alt_num)
deb09eff 4912{
1fb49ce7 4913 size_t length;
30028c85 4914 unit_decl_t unit_decl;
1fb49ce7 4915 unit_usage_t unit_usage_ptr;
1b1f249d 4916 int index;
deb09eff 4917
b2d59f6f
NS
4918 gcc_assert (regexp && regexp->mode == rm_oneof
4919 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
4005971c 4920 unit_decl = REGEXP_UNIT (unit)->unit_decl;
1fb49ce7 4921
1b1f249d 4922 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
1fb49ce7
ZW
4923 while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
4924 VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0);
4925
1b1f249d
VM
4926 obstack_blank (&unit_usages, sizeof (struct unit_usage));
4927 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
4928 obstack_finish (&unit_usages);
4929 unit_usage_ptr->unit_decl = unit_decl;
4930 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
1fb49ce7
ZW
4931 unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
4932 VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
1b1f249d 4933 unit_decl->last_distribution_check_cycle = -1; /* undefined */
deb09eff
VM
4934}
4935
30028c85
VM
4936/* The function processes given REGEXP to find units with the wrong
4937 distribution. */
deb09eff 4938static void
3d7aafde
AJ
4939check_regexp_units_distribution (const char *insn_reserv_name,
4940 regexp_t regexp)
deb09eff 4941{
1b1f249d 4942 int i, j, k, cycle;
deb09eff 4943 regexp_t seq, allof, unit;
1b1f249d 4944 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
deb09eff
VM
4945
4946 if (regexp == NULL || regexp->mode != rm_oneof)
4947 return;
1b1f249d
VM
4948 /* Store all unit usages in the regexp: */
4949 obstack_init (&unit_usages);
1fb49ce7
ZW
4950 cycle_alt_unit_usages = 0;
4951
4005971c 4952 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
deb09eff 4953 {
4005971c 4954 seq = REGEXP_ONEOF (regexp)->regexps [i];
b2d59f6f
NS
4955 switch (seq->mode)
4956 {
4957 case rm_sequence:
4958 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
4959 {
4960 allof = REGEXP_SEQUENCE (seq)->regexps [j];
4961 switch (allof->mode)
deb09eff 4962 {
b2d59f6f
NS
4963 case rm_allof:
4964 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
4965 {
4966 unit = REGEXP_ALLOF (allof)->regexps [k];
4967 if (unit->mode == rm_unit)
4968 store_alt_unit_usage (regexp, unit, j, i);
4969 else
4970 gcc_assert (unit->mode == rm_nothing);
4971 }
4972 break;
4973
4974 case rm_unit:
4975 store_alt_unit_usage (regexp, allof, j, i);
4976 break;
4977
4978 case rm_nothing:
4979 break;
4980
4981 default:
4982 gcc_unreachable ();
deb09eff 4983 }
b2d59f6f
NS
4984 }
4985 break;
4986
4987 case rm_allof:
4988 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
4989 {
4990 unit = REGEXP_ALLOF (seq)->regexps [k];
4991 switch (unit->mode)
4992 {
4993 case rm_unit:
4994 store_alt_unit_usage (regexp, unit, 0, i);
4995 break;
4996
4997 case rm_nothing:
4998 break;
4999
5000 default:
5001 gcc_unreachable ();
5002 }
5003 }
5004 break;
5005
5006 case rm_unit:
5007 store_alt_unit_usage (regexp, seq, 0, i);
5008 break;
5009
5010 case rm_nothing:
5011 break;
5012
5013 default:
5014 gcc_unreachable ();
5015 }
deb09eff 5016 }
1b1f249d 5017 /* Check distribution: */
1fb49ce7 5018 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
1b1f249d
VM
5019 {
5020 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
1fb49ce7 5021 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
1b1f249d
VM
5022 unit_usage_ptr != NULL;
5023 unit_usage_ptr = unit_usage_ptr->next)
5024 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5025 {
5026 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5027 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
1fb49ce7 5028 k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
1b1f249d
VM
5029 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5030 k++)
5031 {
1fb49ce7
ZW
5032 for (other_unit_usage_ptr
5033 = VEC_index (unit_usage_t, cycle_alt_unit_usages, k);
1b1f249d
VM
5034 other_unit_usage_ptr != NULL;
5035 other_unit_usage_ptr = other_unit_usage_ptr->next)
5036 if (unit_usage_ptr->unit_decl->automaton_decl
5037 == other_unit_usage_ptr->unit_decl->automaton_decl)
5038 break;
5039 if (other_unit_usage_ptr == NULL
1fb49ce7
ZW
5040 && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k)
5041 != NULL))
1b1f249d
VM
5042 break;
5043 }
1fb49ce7 5044 if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
1b1f249d
VM
5045 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5046 {
5047 if (!annotation_message_reported_p)
5048 {
5049 fprintf (stderr, "\n");
5050 error ("The following units do not satisfy units-automata distribution rule");
5051 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5052 annotation_message_reported_p = TRUE;
5053 }
5054 error ("Unit %s, reserv. %s, cycle %d",
5055 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5056 cycle);
5057 }
5058 }
5059 }
1fb49ce7 5060 VEC_free (unit_usage_t,heap, cycle_alt_unit_usages);
1b1f249d 5061 obstack_free (&unit_usages, NULL);
deb09eff
VM
5062}
5063
30028c85
VM
5064/* The function finds units which violates units to automata
5065 distribution rule. If the units exist, report about them. */
deb09eff 5066static void
3d7aafde 5067check_unit_distributions_to_automata (void)
deb09eff
VM
5068{
5069 decl_t decl;
deb09eff
VM
5070 int i;
5071
dfa849f3
VM
5072 if (progress_flag)
5073 fprintf (stderr, "Check unit distributions to automata...");
30028c85 5074 annotation_message_reported_p = FALSE;
deb09eff
VM
5075 for (i = 0; i < description->decls_num; i++)
5076 {
5077 decl = description->decls [i];
30028c85
VM
5078 if (decl->mode == dm_insn_reserv)
5079 check_regexp_units_distribution
5080 (DECL_INSN_RESERV (decl)->name,
5081 DECL_INSN_RESERV (decl)->transformed_regexp);
deb09eff 5082 }
dfa849f3
VM
5083 if (progress_flag)
5084 fprintf (stderr, "done\n");
fae15c93
VM
5085}
5086
5087\f
5088
5089/* The page contains code for building alt_states (see comments for
5090 IR) describing all possible insns reservations of an automaton. */
5091
5092/* Current state being formed for which the current alt_state
5093 refers. */
5094static state_t state_being_formed;
5095
5096/* Current alt_state being formed. */
5097static alt_state_t alt_state_being_formed;
3d7aafde 5098
fae15c93
VM
5099/* This recursive function processes `,' and units in reservation
5100 REGEXP for forming alt_states of AUTOMATON. It is believed that
5101 CURR_CYCLE is start cycle of all reservation REGEXP. */
5102static int
3d7aafde
AJ
5103process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5104 int curr_cycle)
fae15c93
VM
5105{
5106 int i;
5107
5108 if (regexp == NULL)
5109 return curr_cycle;
b2d59f6f
NS
5110
5111 switch (regexp->mode)
fae15c93 5112 {
b2d59f6f 5113 case rm_unit:
4005971c 5114 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
fae15c93
VM
5115 == automaton->automaton_order_num)
5116 set_state_reserv (state_being_formed, curr_cycle,
4005971c 5117 REGEXP_UNIT (regexp)->unit_decl->unit_num);
fae15c93 5118 return curr_cycle;
b2d59f6f
NS
5119
5120 case rm_sequence:
4005971c 5121 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
fae15c93
VM
5122 curr_cycle
5123 = process_seq_for_forming_states
4005971c 5124 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
fae15c93 5125 return curr_cycle;
fae15c93 5126
b2d59f6f
NS
5127 case rm_allof:
5128 {
5129 int finish_cycle = 0;
5130 int cycle;
5131
5132 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5133 {
5134 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5135 ->regexps [i],
5136 automaton, curr_cycle);
5137 if (finish_cycle < cycle)
5138 finish_cycle = cycle;
5139 }
5140 return finish_cycle;
5141 }
5142
5143 case rm_nothing:
fae15c93 5144 return curr_cycle;
b2d59f6f
NS
5145
5146 default:
5147 gcc_unreachable ();
fae15c93
VM
5148 }
5149}
5150
5151/* This recursive function finishes forming ALT_STATE of AUTOMATON and
5152 inserts alt_state into the table. */
5153static void
3d7aafde
AJ
5154finish_forming_alt_state (alt_state_t alt_state,
5155 automaton_t automaton ATTRIBUTE_UNUSED)
fae15c93
VM
5156{
5157 state_t state_in_table;
5158 state_t corresponding_state;
5159
5160 corresponding_state = alt_state->state;
5161 state_in_table = insert_state (corresponding_state);
5162 if (state_in_table != corresponding_state)
5163 {
5164 free_state (corresponding_state);
5165 alt_state->state = state_in_table;
5166 }
5167}
5168
5169/* The following variable value is current automaton insn for whose
5170 reservation the alt states are created. */
5171static ainsn_t curr_ainsn;
5172
5173/* This recursive function processes `|' in reservation REGEXP for
5174 forming alt_states of AUTOMATON. List of the alt states should
5175 have the same order as in the description. */
5176static void
3d7aafde
AJ
5177process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5178 int inside_oneof_p)
fae15c93
VM
5179{
5180 int i;
5181
5182 if (regexp->mode != rm_oneof)
5183 {
5184 alt_state_being_formed = get_free_alt_state ();
5185 state_being_formed = get_free_state (1, automaton);
5186 alt_state_being_formed->state = state_being_formed;
5187 /* We inserts in reverse order but we process alternatives also
5188 in reverse order. So we have the same order of alternative
5189 as in the description. */
5190 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5191 curr_ainsn->alt_states = alt_state_being_formed;
5192 (void) process_seq_for_forming_states (regexp, automaton, 0);
5193 finish_forming_alt_state (alt_state_being_formed, automaton);
5194 }
5195 else
5196 {
b2d59f6f 5197 gcc_assert (!inside_oneof_p);
fae15c93
VM
5198 /* We processes it in reverse order to get list with the same
5199 order as in the description. See also the previous
5200 commentary. */
4005971c
VM
5201 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5202 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
fae15c93
VM
5203 automaton, 1);
5204 }
5205}
5206
5207/* Create nodes alt_state for all AUTOMATON insns. */
5208static void
3d7aafde 5209create_alt_states (automaton_t automaton)
fae15c93
VM
5210{
5211 struct insn_reserv_decl *reserv_decl;
5212
5213 for (curr_ainsn = automaton->ainsn_list;
5214 curr_ainsn != NULL;
5215 curr_ainsn = curr_ainsn->next_ainsn)
5216 {
5217 reserv_decl = curr_ainsn->insn_reserv_decl;
4005971c 5218 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
fae15c93
VM
5219 {
5220 curr_ainsn->alt_states = NULL;
5221 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5222 automaton, 0);
5223 curr_ainsn->sorted_alt_states
5224 = uniq_sort_alt_states (curr_ainsn->alt_states);
5225 }
5226 }
5227}
5228
5229\f
5230
5231/* The page contains major code for building DFA(s) for fast pipeline
5232 hazards recognition. */
5233
5234/* The function forms list of ainsns of AUTOMATON with the same
5235 reservation. */
1fb49ce7 5236
fae15c93 5237static void
3d7aafde 5238form_ainsn_with_same_reservs (automaton_t automaton)
fae15c93
VM
5239{
5240 ainsn_t curr_ainsn;
5241 size_t i;
1fb49ce7 5242 VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150);
fae15c93 5243
fae15c93
VM
5244 for (curr_ainsn = automaton->ainsn_list;
5245 curr_ainsn != NULL;
5246 curr_ainsn = curr_ainsn->next_ainsn)
5247 if (curr_ainsn->insn_reserv_decl
4005971c 5248 == DECL_INSN_RESERV (advance_cycle_insn_decl))
fae15c93
VM
5249 {
5250 curr_ainsn->next_same_reservs_insn = NULL;
5251 curr_ainsn->first_insn_with_same_reservs = 1;
5252 }
5253 else
5254 {
1fb49ce7 5255 for (i = 0; i < VEC_length (ainsn_t, last_insns); i++)
fae15c93
VM
5256 if (alt_states_eq
5257 (curr_ainsn->sorted_alt_states,
1fb49ce7 5258 VEC_index (ainsn_t, last_insns, i)->sorted_alt_states))
fae15c93
VM
5259 break;
5260 curr_ainsn->next_same_reservs_insn = NULL;
1fb49ce7 5261 if (i < VEC_length (ainsn_t, last_insns))
fae15c93
VM
5262 {
5263 curr_ainsn->first_insn_with_same_reservs = 0;
1fb49ce7 5264 VEC_index (ainsn_t, last_insns, i)->next_same_reservs_insn
fae15c93 5265 = curr_ainsn;
1fb49ce7 5266 VEC_replace (ainsn_t, last_insns, i, curr_ainsn);
fae15c93
VM
5267 }
5268 else
5269 {
1fb49ce7 5270 VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn);
fae15c93
VM
5271 curr_ainsn->first_insn_with_same_reservs = 1;
5272 }
5273 }
1fb49ce7 5274 VEC_free (ainsn_t,heap, last_insns);
fae15c93
VM
5275}
5276
30028c85
VM
5277/* Forming unit reservations which can affect creating the automaton
5278 states achieved from a given state. It permits to build smaller
5279 automata in many cases. We would have the same automata after
5280 the minimization without such optimization, but the automaton
5281 right after the building could be huge. So in other words, usage
5282 of reservs_matter means some minimization during building the
5283 automaton. */
5284static reserv_sets_t
3d7aafde 5285form_reservs_matter (automaton_t automaton)
30028c85
VM
5286{
5287 int cycle, unit;
5288 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5289
5290 for (cycle = 0; cycle < max_cycles_num; cycle++)
5291 for (unit = 0; unit < description->units_num; unit++)
5292 if (units_array [unit]->automaton_decl
5293 == automaton->corresponding_automaton_decl
5294 && (cycle >= units_array [unit]->min_occ_cycle_num
5295 /* We can not remove queried unit from reservations. */
5296 || units_array [unit]->query_p
5297 /* We can not remove units which are used
5298 `exclusion_set', `presence_set',
5299 `final_presence_set', `absence_set', and
5300 `final_absence_set'. */
5301 || units_array [unit]->in_set_p))
5302 set_unit_reserv (reservs_matter, cycle, unit);
5303 return reservs_matter;
5304}
5305
1fb49ce7 5306/* The following function creates all states of nondeterministic AUTOMATON. */
fae15c93 5307static void
3d7aafde 5308make_automaton (automaton_t automaton)
fae15c93
VM
5309{
5310 ainsn_t ainsn;
5311 struct insn_reserv_decl *insn_reserv_decl;
5312 alt_state_t alt_state;
5313 state_t state;
5314 state_t start_state;
5315 state_t state2;
5316 ainsn_t advance_cycle_ainsn;
5317 arc_t added_arc;
1fb49ce7 5318 VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150);
30028c85
VM
5319 int states_n;
5320 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
fae15c93 5321
fae15c93
VM
5322 /* Create the start state (empty state). */
5323 start_state = insert_state (get_free_state (1, automaton));
5324 automaton->start_state = start_state;
5325 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
1fb49ce7 5326 VEC_safe_push (state_t,heap, state_stack, start_state);
30028c85 5327 states_n = 1;
1fb49ce7 5328 while (VEC_length (state_t, state_stack) != 0)
fae15c93 5329 {
1fb49ce7 5330 state = VEC_pop (state_t, state_stack);
fae15c93
VM
5331 advance_cycle_ainsn = NULL;
5332 for (ainsn = automaton->ainsn_list;
5333 ainsn != NULL;
5334 ainsn = ainsn->next_ainsn)
5335 if (ainsn->first_insn_with_same_reservs)
5336 {
5337 insn_reserv_decl = ainsn->insn_reserv_decl;
4005971c 5338 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
fae15c93
VM
5339 {
5340 /* We process alt_states in the same order as they are
5341 present in the description. */
5342 added_arc = NULL;
5343 for (alt_state = ainsn->alt_states;
5344 alt_state != NULL;
5345 alt_state = alt_state->next_alt_state)
5346 {
5347 state2 = alt_state->state;
5348 if (!intersected_state_reservs_p (state, state2))
5349 {
30028c85 5350 state2 = states_union (state, state2, reservs_matter);
fae15c93
VM
5351 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5352 {
5353 state2->it_was_placed_in_stack_for_NDFA_forming
5354 = 1;
1fb49ce7 5355 VEC_safe_push (state_t,heap, state_stack, state2);
30028c85 5356 states_n++;
dfa849f3 5357 if (progress_flag && states_n % 100 == 0)
1e8dcb41 5358 fprintf (stderr, ".");
fae15c93 5359 }
8c94f366 5360 added_arc = add_arc (state, state2, ainsn);
fae15c93
VM
5361 if (!ndfa_flag)
5362 break;
5363 }
5364 }
5365 if (!ndfa_flag && added_arc != NULL)
5366 {
fae15c93
VM
5367 for (alt_state = ainsn->alt_states;
5368 alt_state != NULL;
5369 alt_state = alt_state->next_alt_state)
8c94f366 5370 state2 = alt_state->state;
fae15c93
VM
5371 }
5372 }
5373 else
5374 advance_cycle_ainsn = ainsn;
5375 }
5376 /* Add transition to advance cycle. */
30028c85 5377 state2 = state_shift (state, reservs_matter);
fae15c93
VM
5378 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5379 {
5380 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
1fb49ce7 5381 VEC_safe_push (state_t,heap, state_stack, state2);
30028c85 5382 states_n++;
dfa849f3 5383 if (progress_flag && states_n % 100 == 0)
1e8dcb41 5384 fprintf (stderr, ".");
fae15c93 5385 }
b2d59f6f 5386 gcc_assert (advance_cycle_ainsn);
8c94f366 5387 add_arc (state, state2, advance_cycle_ainsn);
fae15c93 5388 }
1fb49ce7 5389 VEC_free (state_t,heap, state_stack);
fae15c93
VM
5390}
5391
5392/* Foms lists of all arcs of STATE marked by the same ainsn. */
5393static void
3d7aafde 5394form_arcs_marked_by_insn (state_t state)
fae15c93
VM
5395{
5396 decl_t decl;
5397 arc_t arc;
5398 int i;
5399
5400 for (i = 0; i < description->decls_num; i++)
5401 {
5402 decl = description->decls [i];
5403 if (decl->mode == dm_insn_reserv)
4005971c 5404 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
fae15c93
VM
5405 }
5406 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5407 {
b2d59f6f 5408 gcc_assert (arc->insn);
fae15c93
VM
5409 arc->next_arc_marked_by_insn
5410 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5411 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5412 }
5413}
5414
5415/* The function creates composed state (see comments for IR) from
5416 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5417 same insn. If the composed state is not in STATE_STACK yet, it is
30028c85 5418 pushed into STATE_STACK. */
1fb49ce7 5419
30028c85 5420static int
3d7aafde 5421create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
1fb49ce7 5422 VEC(state_t,heap) **state_stack)
fae15c93
VM
5423{
5424 state_t state;
30028c85 5425 alt_state_t alt_state, curr_alt_state;
fae15c93
VM
5426 alt_state_t new_alt_state;
5427 arc_t curr_arc;
5428 arc_t next_arc;
5429 state_t state_in_table;
5430 state_t temp_state;
5431 alt_state_t canonical_alt_states_list;
5432 int alts_number;
30028c85 5433 int new_state_p = 0;
fae15c93
VM
5434
5435 if (arcs_marked_by_insn == NULL)
30028c85 5436 return new_state_p;
fae15c93
VM
5437 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5438 state = arcs_marked_by_insn->to_state;
5439 else
5440 {
b2d59f6f 5441 gcc_assert (ndfa_flag);
fae15c93
VM
5442 /* Create composed state. */
5443 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5444 curr_alt_state = NULL;
5445 for (curr_arc = arcs_marked_by_insn;
5446 curr_arc != NULL;
5447 curr_arc = curr_arc->next_arc_marked_by_insn)
30028c85
VM
5448 if (curr_arc->to_state->component_states == NULL)
5449 {
5450 new_alt_state = get_free_alt_state ();
5451 new_alt_state->next_alt_state = curr_alt_state;
5452 new_alt_state->state = curr_arc->to_state;
5453 curr_alt_state = new_alt_state;
5454 }
5455 else
5456 for (alt_state = curr_arc->to_state->component_states;
5457 alt_state != NULL;
5458 alt_state = alt_state->next_sorted_alt_state)
5459 {
5460 new_alt_state = get_free_alt_state ();
5461 new_alt_state->next_alt_state = curr_alt_state;
5462 new_alt_state->state = alt_state->state;
b2d59f6f 5463 gcc_assert (!alt_state->state->component_states);
30028c85
VM
5464 curr_alt_state = new_alt_state;
5465 }
fae15c93
VM
5466 /* There are not identical sets in the alt state list. */
5467 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5468 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5469 {
5470 temp_state = state;
5471 state = canonical_alt_states_list->state;
5472 free_state (temp_state);
5473 }
5474 else
5475 {
5476 state->component_states = canonical_alt_states_list;
5477 state_in_table = insert_state (state);
5478 if (state_in_table != state)
5479 {
b2d59f6f
NS
5480 gcc_assert
5481 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
fae15c93
VM
5482 free_state (state);
5483 state = state_in_table;
5484 }
5485 else
5486 {
b2d59f6f 5487 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
30028c85 5488 new_state_p = 1;
fae15c93
VM
5489 for (curr_alt_state = state->component_states;
5490 curr_alt_state != NULL;
5491 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5492 for (curr_arc = first_out_arc (curr_alt_state->state);
5493 curr_arc != NULL;
5494 curr_arc = next_out_arc (curr_arc))
8c94f366 5495 add_arc (state, curr_arc->to_state, curr_arc->insn);
fae15c93
VM
5496 }
5497 arcs_marked_by_insn->to_state = state;
5498 for (alts_number = 0,
5499 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5500 curr_arc != NULL;
5501 curr_arc = next_arc)
5502 {
5503 next_arc = curr_arc->next_arc_marked_by_insn;
5504 remove_arc (original_state, curr_arc);
5505 alts_number++;
5506 }
fae15c93
VM
5507 }
5508 }
5509 if (!state->it_was_placed_in_stack_for_DFA_forming)
5510 {
5511 state->it_was_placed_in_stack_for_DFA_forming = 1;
1fb49ce7 5512 VEC_safe_push (state_t,heap, *state_stack, state);
fae15c93 5513 }
30028c85 5514 return new_state_p;
fae15c93
VM
5515}
5516
96e13905 5517/* The function transforms nondeterministic AUTOMATON into
fae15c93 5518 deterministic. */
1fb49ce7 5519
fae15c93 5520static void
3d7aafde 5521NDFA_to_DFA (automaton_t automaton)
fae15c93
VM
5522{
5523 state_t start_state;
5524 state_t state;
5525 decl_t decl;
1fb49ce7 5526 VEC(state_t,heap) *state_stack;
fae15c93 5527 int i;
30028c85 5528 int states_n;
fae15c93 5529
1fb49ce7
ZW
5530 state_stack = VEC_alloc (state_t,heap, 0);
5531
fae15c93
VM
5532 /* Create the start state (empty state). */
5533 start_state = automaton->start_state;
5534 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
1fb49ce7 5535 VEC_safe_push (state_t,heap, state_stack, start_state);
30028c85 5536 states_n = 1;
1fb49ce7 5537 while (VEC_length (state_t, state_stack) != 0)
fae15c93 5538 {
1fb49ce7 5539 state = VEC_pop (state_t, state_stack);
fae15c93
VM
5540 form_arcs_marked_by_insn (state);
5541 for (i = 0; i < description->decls_num; i++)
5542 {
5543 decl = description->decls [i];
30028c85
VM
5544 if (decl->mode == dm_insn_reserv
5545 && create_composed_state
5546 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5547 &state_stack))
5548 {
5549 states_n++;
dfa849f3 5550 if (progress_flag && states_n % 100 == 0)
1e8dcb41 5551 fprintf (stderr, ".");
30028c85 5552 }
fae15c93
VM
5553 }
5554 }
1fb49ce7 5555 VEC_free (state_t,heap, state_stack);
fae15c93
VM
5556}
5557
5558/* The following variable value is current number (1, 2, ...) of passing
5559 graph of states. */
5560static int curr_state_graph_pass_num;
5561
5562/* This recursive function passes all states achieved from START_STATE
5563 and applies APPLIED_FUNC to them. */
5564static void
3d7aafde 5565pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
fae15c93
VM
5566{
5567 arc_t arc;
5568
5569 if (start_state->pass_num == curr_state_graph_pass_num)
5570 return;
5571 start_state->pass_num = curr_state_graph_pass_num;
5572 (*applied_func) (start_state);
5573 for (arc = first_out_arc (start_state);
5574 arc != NULL;
5575 arc = next_out_arc (arc))
5576 pass_state_graph (arc->to_state, applied_func);
5577}
5578
5579/* This recursive function passes all states of AUTOMATON and applies
5580 APPLIED_FUNC to them. */
5581static void
3d7aafde 5582pass_states (automaton_t automaton, void (*applied_func) (state_t state))
fae15c93
VM
5583{
5584 curr_state_graph_pass_num++;
5585 pass_state_graph (automaton->start_state, applied_func);
5586}
5587
5588/* The function initializes code for passing of all states. */
5589static void
3d7aafde 5590initiate_pass_states (void)
fae15c93
VM
5591{
5592 curr_state_graph_pass_num = 0;
5593}
5594
5595/* The following vla is used for storing pointers to all achieved
5596 states. */
1fb49ce7 5597static VEC(state_t,heap) *all_achieved_states;
fae15c93
VM
5598
5599/* This function is called by function pass_states to add an achieved
5600 STATE. */
5601static void
3d7aafde 5602add_achieved_state (state_t state)
fae15c93 5603{
1fb49ce7 5604 VEC_safe_push (state_t,heap, all_achieved_states, state);
fae15c93
VM
5605}
5606
5607/* The function sets up equivalence numbers of insns which mark all
5608 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5609 nonzero value) or by equiv_class_num_2 of the destination state.
5610 The function returns number of out arcs of STATE. */
b6bbd675 5611static void
3d7aafde 5612set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
fae15c93 5613{
fae15c93
VM
5614 arc_t arc;
5615
fae15c93
VM
5616 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5617 {
8c94f366 5618 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
fae15c93
VM
5619 arc->insn->insn_reserv_decl->equiv_class_num
5620 = (odd_iteration_flag
5621 ? arc->to_state->equiv_class_num_1
5622 : arc->to_state->equiv_class_num_2);
8c94f366 5623 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
fae15c93 5624 }
fae15c93
VM
5625}
5626
5627/* The function clears equivalence numbers and alt_states in all insns
5628 which mark all out arcs of STATE. */
5629static void
3d7aafde 5630clear_arc_insns_equiv_num (state_t state)
fae15c93
VM
5631{
5632 arc_t arc;
5633
5634 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8c94f366 5635 arc->insn->insn_reserv_decl->equiv_class_num = 0;
fae15c93
VM
5636}
5637
fae15c93 5638
30028c85
VM
5639/* The following function returns TRUE if STATE reserves the unit with
5640 UNIT_NUM on the first cycle. */
5641static int
3d7aafde 5642first_cycle_unit_presence (state_t state, int unit_num)
30028c85 5643{
96ddf8ef 5644 alt_state_t alt_state;
30028c85
VM
5645
5646 if (state->component_states == NULL)
96ddf8ef 5647 return test_unit_reserv (state->reservs, 0, unit_num);
30028c85 5648 else
96ddf8ef
VM
5649 {
5650 for (alt_state = state->component_states;
5651 alt_state != NULL;
5652 alt_state = alt_state->next_sorted_alt_state)
5653 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
5654 return true;
5655 }
5656 return false;
30028c85
VM
5657}
5658
b6bbd675
MM
5659/* This fills in the presence_signature[] member of STATE. */
5660static void
5661cache_presence (state_t state)
5662{
5663 int i, num = 0;
5664 unsigned int sz;
5665 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5666 / (sizeof (int) * CHAR_BIT);
5667
5668 state->presence_signature = create_node (sz * sizeof (int));
5669 for (i = 0; i < description->units_num; i++)
5670 if (units_array [i]->query_p)
5671 {
5672 int presence1_p = first_cycle_unit_presence (state, i);
5673 state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
5674 |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
5675 num++;
5676 }
5677}
5678
fae15c93 5679/* The function returns nonzero value if STATE is not equivalent to
30028c85
VM
5680 ANOTHER_STATE from the same current partition on equivalence
5681 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
fae15c93
VM
5682 output arcs. Iteration of making equivalence partition is defined
5683 by ODD_ITERATION_FLAG. */
5684static int
3d7aafde 5685state_is_differed (state_t state, state_t another_state,
b6bbd675 5686 int odd_iteration_flag)
fae15c93
VM
5687{
5688 arc_t arc;
b6bbd675
MM
5689 unsigned int sz, si;
5690
5691 gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
5692
5693 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5694 / (sizeof (int) * CHAR_BIT);
5695
5696 for (si = 0; si < sz; si++)
5697 gcc_assert (state->presence_signature[si]
5698 == another_state->presence_signature[si]);
fae15c93 5699
fae15c93
VM
5700 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5701 {
fae15c93
VM
5702 if ((odd_iteration_flag
5703 ? arc->to_state->equiv_class_num_1
5704 : arc->to_state->equiv_class_num_2)
8c94f366 5705 != arc->insn->insn_reserv_decl->equiv_class_num)
fae15c93
VM
5706 return 1;
5707 }
b6bbd675
MM
5708
5709 return 0;
5710}
5711
5712/* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2
5713 and return -1, 0 or 1. This function can be used as predicate for
5714 qsort(). It requires the member presence_signature[] of both
5715 states be filled. */
5716static int
5717compare_states_for_equiv (const void *state_ptr_1,
5718 const void *state_ptr_2)
5719{
5720 state_t s1 = *(state_t *)state_ptr_1;
5721 state_t s2 = *(state_t *)state_ptr_2;
5722 unsigned int sz, si;
5723 if (s1->num_out_arcs < s2->num_out_arcs)
5724 return -1;
5725 else if (s1->num_out_arcs > s2->num_out_arcs)
30028c85 5726 return 1;
b6bbd675
MM
5727
5728 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5729 / (sizeof (int) * CHAR_BIT);
5730
5731 for (si = 0; si < sz; si++)
5732 if (s1->presence_signature[si] < s2->presence_signature[si])
5733 return -1;
5734 else if (s1->presence_signature[si] > s2->presence_signature[si])
5735 return 1;
30028c85 5736 return 0;
fae15c93
VM
5737}
5738
5739/* The function makes initial partition of STATES on equivalent
b6bbd675
MM
5740 classes and saves it into *CLASSES. This function requires the input
5741 to be sorted via compare_states_for_equiv(). */
5742static int
5743init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes)
fae15c93 5744{
1fb49ce7
ZW
5745 size_t i;
5746 state_t prev = 0;
b6bbd675 5747 int class_num = 1;
fae15c93 5748
b6bbd675 5749 *classes = VEC_alloc (state_t,heap, 150);
1fb49ce7 5750 for (i = 0; i < VEC_length (state_t, states); i++)
fae15c93 5751 {
b6bbd675
MM
5752 state_t state = VEC_index (state_t, states, i);
5753 if (prev)
5754 {
5755 if (compare_states_for_equiv (&prev, &state) != 0)
5756 {
5757 VEC_safe_push (state_t,heap, *classes, prev);
5758 class_num++;
5759 prev = NULL;
5760 }
5761 }
5762 state->equiv_class_num_1 = class_num;
5763 state->next_equiv_class_state = prev;
5764 prev = state;
fae15c93 5765 }
b6bbd675
MM
5766 if (prev)
5767 VEC_safe_push (state_t,heap, *classes, prev);
5768 return class_num;
fae15c93
VM
5769}
5770
1fb49ce7
ZW
5771/* The function copies pointers to equivalent states from vla FROM
5772 into vla TO. */
5773static void
5774copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
5775{
5776 VEC_free (state_t,heap, *to);
5777 *to = VEC_copy (state_t,heap, from);
5778}
b6bbd675 5779
1fb49ce7
ZW
5780/* The function processes equivalence class given by its first state,
5781 FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
96e13905 5782 are not equivalent states, the function partitions the class
fae15c93
VM
5783 removing nonequivalent states and placing them in
5784 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5785 assigns it to the state equivalence number. If the class has been
deb09eff 5786 partitioned, the function returns nonzero value. */
fae15c93 5787static int
1fb49ce7
ZW
5788partition_equiv_class (state_t first_state, int odd_iteration_flag,
5789 VEC(state_t,heap) **next_iteration_classes,
3d7aafde 5790 int *new_equiv_class_num_ptr)
fae15c93
VM
5791{
5792 state_t new_equiv_class;
5793 int partition_p;
fae15c93
VM
5794 state_t curr_state;
5795 state_t prev_state;
5796 state_t next_state;
fae15c93
VM
5797
5798 partition_p = 0;
1fb49ce7
ZW
5799
5800 while (first_state != NULL)
fae15c93
VM
5801 {
5802 new_equiv_class = NULL;
5803 if (first_state->next_equiv_class_state != NULL)
5804 {
5805 /* There are more one states in the class equivalence. */
b6bbd675 5806 set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
fae15c93
VM
5807 for (prev_state = first_state,
5808 curr_state = first_state->next_equiv_class_state;
5809 curr_state != NULL;
5810 curr_state = next_state)
5811 {
5812 next_state = curr_state->next_equiv_class_state;
b6bbd675 5813 if (state_is_differed (curr_state, first_state,
fae15c93
VM
5814 odd_iteration_flag))
5815 {
5816 /* Remove curr state from the class equivalence. */
5817 prev_state->next_equiv_class_state = next_state;
5818 /* Add curr state to the new class equivalence. */
5819 curr_state->next_equiv_class_state = new_equiv_class;
5820 if (new_equiv_class == NULL)
5821 (*new_equiv_class_num_ptr)++;
5822 if (odd_iteration_flag)
5823 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5824 else
5825 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5826 new_equiv_class = curr_state;
5827 partition_p = 1;
5828 }
5829 else
5830 prev_state = curr_state;
5831 }
5832 clear_arc_insns_equiv_num (first_state);
5833 }
5834 if (new_equiv_class != NULL)
1fb49ce7
ZW
5835 VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class);
5836 first_state = new_equiv_class;
fae15c93
VM
5837 }
5838 return partition_p;
5839}
5840
5841/* The function finds equivalent states of AUTOMATON. */
5842static void
1fb49ce7
ZW
5843evaluate_equiv_classes (automaton_t automaton,
5844 VEC(state_t,heap) **equiv_classes)
fae15c93 5845{
fae15c93
VM
5846 int new_equiv_class_num;
5847 int odd_iteration_flag;
5848 int finish_flag;
1fb49ce7
ZW
5849 VEC (state_t,heap) *next_iteration_classes;
5850 size_t i;
3d7aafde 5851
1fb49ce7 5852 all_achieved_states = VEC_alloc (state_t,heap, 1500);
fae15c93 5853 pass_states (automaton, add_achieved_state);
b6bbd675
MM
5854 pass_states (automaton, cache_presence);
5855 qsort (VEC_address (state_t, all_achieved_states),
5856 VEC_length (state_t, all_achieved_states),
5857 sizeof (state_t), compare_states_for_equiv);
1fb49ce7 5858
b6bbd675
MM
5859 odd_iteration_flag = 0;
5860 new_equiv_class_num = init_equiv_class (all_achieved_states,
5861 &next_iteration_classes);
1fb49ce7 5862
fae15c93
VM
5863 do
5864 {
5865 odd_iteration_flag = !odd_iteration_flag;
5866 finish_flag = 1;
1fb49ce7
ZW
5867 copy_equiv_class (equiv_classes, next_iteration_classes);
5868
fae15c93 5869 /* Transfer equiv numbers for the next iteration. */
1fb49ce7 5870 for (i = 0; i < VEC_length (state_t, all_achieved_states); i++)
fae15c93 5871 if (odd_iteration_flag)
1fb49ce7
ZW
5872 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2
5873 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1;
fae15c93 5874 else
1fb49ce7
ZW
5875 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1
5876 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2;
5877
5878 for (i = 0; i < VEC_length (state_t, *equiv_classes); i++)
5879 if (partition_equiv_class (VEC_index (state_t, *equiv_classes, i),
5880 odd_iteration_flag,
fae15c93
VM
5881 &next_iteration_classes,
5882 &new_equiv_class_num))
5883 finish_flag = 0;
5884 }
5885 while (!finish_flag);
1fb49ce7
ZW
5886 VEC_free (state_t,heap, next_iteration_classes);
5887 VEC_free (state_t,heap, all_achieved_states);
fae15c93
VM
5888}
5889
5890/* The function merges equivalent states of AUTOMATON. */
5891static void
1fb49ce7 5892merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes)
fae15c93 5893{
fae15c93
VM
5894 state_t curr_state;
5895 state_t new_state;
5896 state_t first_class_state;
5897 alt_state_t alt_states;
30028c85 5898 alt_state_t alt_state, new_alt_state;
fae15c93
VM
5899 arc_t curr_arc;
5900 arc_t next_arc;
1fb49ce7 5901 size_t i;
fae15c93
VM
5902
5903 /* Create states corresponding to equivalence classes containing two
5904 or more states. */
1fb49ce7
ZW
5905 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
5906 {
5907 curr_state = VEC_index (state_t, equiv_classes, i);
5908 if (curr_state->next_equiv_class_state != NULL)
5909 {
5910 /* There are more one states in the class equivalence. */
5911 /* Create new compound state. */
5912 new_state = get_free_state (0, automaton);
5913 alt_states = NULL;
5914 first_class_state = curr_state;
5915 for (curr_state = first_class_state;
5916 curr_state != NULL;
5917 curr_state = curr_state->next_equiv_class_state)
5918 {
5919 curr_state->equiv_class_state = new_state;
5920 if (curr_state->component_states == NULL)
30028c85
VM
5921 {
5922 new_alt_state = get_free_alt_state ();
1fb49ce7 5923 new_alt_state->state = curr_state;
30028c85
VM
5924 new_alt_state->next_alt_state = alt_states;
5925 alt_states = new_alt_state;
5926 }
1fb49ce7
ZW
5927 else
5928 for (alt_state = curr_state->component_states;
5929 alt_state != NULL;
5930 alt_state = alt_state->next_sorted_alt_state)
5931 {
5932 new_alt_state = get_free_alt_state ();
5933 new_alt_state->state = alt_state->state;
5934 new_alt_state->next_alt_state = alt_states;
5935 alt_states = new_alt_state;
5936 }
5937 }
5938 /* Its is important that alt states were sorted before and
5939 after merging to have the same querying results. */
5940 new_state->component_states = uniq_sort_alt_states (alt_states);
5941 }
5942 else
5943 curr_state->equiv_class_state = curr_state;
5944 }
5945
5946 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
5947 {
5948 curr_state = VEC_index (state_t, equiv_classes, i);
5949 if (curr_state->next_equiv_class_state != NULL)
5950 {
5951 first_class_state = curr_state;
5952 /* Create new arcs output from the state corresponding to
5953 equiv class. */
5954 for (curr_arc = first_out_arc (first_class_state);
5955 curr_arc != NULL;
5956 curr_arc = next_out_arc (curr_arc))
5957 add_arc (first_class_state->equiv_class_state,
5958 curr_arc->to_state->equiv_class_state,
8c94f366 5959 curr_arc->insn);
1fb49ce7
ZW
5960 /* Delete output arcs from states of given class equivalence. */
5961 for (curr_state = first_class_state;
5962 curr_state != NULL;
5963 curr_state = curr_state->next_equiv_class_state)
5964 {
5965 if (automaton->start_state == curr_state)
5966 automaton->start_state = curr_state->equiv_class_state;
5967 /* Delete the state and its output arcs. */
5968 for (curr_arc = first_out_arc (curr_state);
5969 curr_arc != NULL;
5970 curr_arc = next_arc)
5971 {
5972 next_arc = next_out_arc (curr_arc);
5973 free_arc (curr_arc);
5974 }
5975 }
5976 }
5977 else
5978 {
5979 /* Change `to_state' of arcs output from the state of given
5980 equivalence class. */
5981 for (curr_arc = first_out_arc (curr_state);
5982 curr_arc != NULL;
5983 curr_arc = next_out_arc (curr_arc))
5984 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
5985 }
5986 }
fae15c93
VM
5987}
5988
5989/* The function sets up new_cycle_p for states if there is arc to the
5990 state marked by advance_cycle_insn_decl. */
5991static void
3d7aafde 5992set_new_cycle_flags (state_t state)
fae15c93
VM
5993{
5994 arc_t arc;
5995
5996 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5997 if (arc->insn->insn_reserv_decl
4005971c 5998 == DECL_INSN_RESERV (advance_cycle_insn_decl))
fae15c93
VM
5999 arc->to_state->new_cycle_p = 1;
6000}
6001
6002/* The top level function for minimization of deterministic
6003 AUTOMATON. */
6004static void
3d7aafde 6005minimize_DFA (automaton_t automaton)
fae15c93 6006{
1fb49ce7 6007 VEC(state_t,heap) *equiv_classes = 0;
fae15c93 6008
fae15c93 6009 evaluate_equiv_classes (automaton, &equiv_classes);
1fb49ce7 6010 merge_states (automaton, equiv_classes);
fae15c93 6011 pass_states (automaton, set_new_cycle_flags);
1fb49ce7
ZW
6012
6013 VEC_free (state_t,heap, equiv_classes);
fae15c93
VM
6014}
6015
6016/* Values of two variables are counted number of states and arcs in an
6017 automaton. */
6018static int curr_counted_states_num;
6019static int curr_counted_arcs_num;
6020
6021/* The function is called by function `pass_states' to count states
6022 and arcs of an automaton. */
6023static void
3d7aafde 6024incr_states_and_arcs_nums (state_t state)
fae15c93
VM
6025{
6026 arc_t arc;
6027
6028 curr_counted_states_num++;
6029 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6030 curr_counted_arcs_num++;
6031}
6032
6033/* The function counts states and arcs of AUTOMATON. */
6034static void
3d7aafde
AJ
6035count_states_and_arcs (automaton_t automaton, int *states_num,
6036 int *arcs_num)
fae15c93
VM
6037{
6038 curr_counted_states_num = 0;
6039 curr_counted_arcs_num = 0;
6040 pass_states (automaton, incr_states_and_arcs_nums);
6041 *states_num = curr_counted_states_num;
6042 *arcs_num = curr_counted_arcs_num;
6043}
6044
6045/* The function builds one DFA AUTOMATON for fast pipeline hazards
6046 recognition after checking and simplifying IR of the
6047 description. */
6048static void
3d7aafde 6049build_automaton (automaton_t automaton)
fae15c93
VM
6050{
6051 int states_num;
6052 int arcs_num;
6053
6054 ticker_on (&NDFA_time);
dfa849f3
VM
6055 if (progress_flag)
6056 {
6057 if (automaton->corresponding_automaton_decl == NULL)
6058 fprintf (stderr, "Create anonymous automaton");
6059 else
6060 fprintf (stderr, "Create automaton `%s'",
6061 automaton->corresponding_automaton_decl->name);
6062 fprintf (stderr, " (1 dot is 100 new states):");
6063 }
fae15c93 6064 make_automaton (automaton);
dfa849f3
VM
6065 if (progress_flag)
6066 fprintf (stderr, " done\n");
fae15c93
VM
6067 ticker_off (&NDFA_time);
6068 count_states_and_arcs (automaton, &states_num, &arcs_num);
6069 automaton->NDFA_states_num = states_num;
6070 automaton->NDFA_arcs_num = arcs_num;
6071 ticker_on (&NDFA_to_DFA_time);
dfa849f3
VM
6072 if (progress_flag)
6073 {
6074 if (automaton->corresponding_automaton_decl == NULL)
6075 fprintf (stderr, "Make anonymous DFA");
6076 else
6077 fprintf (stderr, "Make DFA `%s'",
6078 automaton->corresponding_automaton_decl->name);
6079 fprintf (stderr, " (1 dot is 100 new states):");
6080 }
fae15c93 6081 NDFA_to_DFA (automaton);
dfa849f3
VM
6082 if (progress_flag)
6083 fprintf (stderr, " done\n");
fae15c93
VM
6084 ticker_off (&NDFA_to_DFA_time);
6085 count_states_and_arcs (automaton, &states_num, &arcs_num);
6086 automaton->DFA_states_num = states_num;
6087 automaton->DFA_arcs_num = arcs_num;
6088 if (!no_minimization_flag)
6089 {
6090 ticker_on (&minimize_time);
dfa849f3
VM
6091 if (progress_flag)
6092 {
6093 if (automaton->corresponding_automaton_decl == NULL)
6094 fprintf (stderr, "Minimize anonymous DFA...");
6095 else
6096 fprintf (stderr, "Minimize DFA `%s'...",
6097 automaton->corresponding_automaton_decl->name);
6098 }
fae15c93 6099 minimize_DFA (automaton);
dfa849f3
VM
6100 if (progress_flag)
6101 fprintf (stderr, "done\n");
fae15c93
VM
6102 ticker_off (&minimize_time);
6103 count_states_and_arcs (automaton, &states_num, &arcs_num);
6104 automaton->minimal_DFA_states_num = states_num;
6105 automaton->minimal_DFA_arcs_num = arcs_num;
6106 }
6107}
6108
6109\f
6110
6111/* The page contains code for enumeration of all states of an automaton. */
6112
6113/* Variable used for enumeration of all states of an automaton. Its
6114 value is current number of automaton states. */
6115static int curr_state_order_num;
6116
6117/* The function is called by function `pass_states' for enumerating
6118 states. */
6119static void
3d7aafde 6120set_order_state_num (state_t state)
fae15c93
VM
6121{
6122 state->order_state_num = curr_state_order_num;
6123 curr_state_order_num++;
6124}
6125
6126/* The function enumerates all states of AUTOMATON. */
6127static void
3d7aafde 6128enumerate_states (automaton_t automaton)
fae15c93
VM
6129{
6130 curr_state_order_num = 0;
6131 pass_states (automaton, set_order_state_num);
6132 automaton->achieved_states_num = curr_state_order_num;
6133}
6134
6135\f
6136
6137/* The page contains code for finding equivalent automaton insns
6138 (ainsns). */
6139
6140/* The function inserts AINSN into cyclic list
6141 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6142static ainsn_t
3d7aafde
AJ
6143insert_ainsn_into_equiv_class (ainsn_t ainsn,
6144 ainsn_t cyclic_equiv_class_insn_list)
fae15c93
VM
6145{
6146 if (cyclic_equiv_class_insn_list == NULL)
6147 ainsn->next_equiv_class_insn = ainsn;
6148 else
6149 {
6150 ainsn->next_equiv_class_insn
6151 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6152 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6153 }
6154 return ainsn;
6155}
6156
6157/* The function deletes equiv_class_insn into cyclic list of
6158 equivalent ainsns. */
6159static void
3d7aafde 6160delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
fae15c93
VM
6161{
6162 ainsn_t curr_equiv_class_insn;
6163 ainsn_t prev_equiv_class_insn;
6164
6165 prev_equiv_class_insn = equiv_class_insn;
6166 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6167 curr_equiv_class_insn != equiv_class_insn;
6168 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6169 prev_equiv_class_insn = curr_equiv_class_insn;
6170 if (prev_equiv_class_insn != equiv_class_insn)
6171 prev_equiv_class_insn->next_equiv_class_insn
6172 = equiv_class_insn->next_equiv_class_insn;
6173}
6174
6175/* The function processes AINSN of a state in order to find equivalent
6176 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6177 state. */
6178static void
3d7aafde 6179process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
fae15c93
VM
6180{
6181 ainsn_t next_insn;
6182 ainsn_t curr_insn;
6183 ainsn_t cyclic_insn_list;
6184 arc_t arc;
6185
b2d59f6f 6186 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
fae15c93
VM
6187 curr_insn = ainsn;
6188 /* New class of ainsns which are not equivalent to given ainsn. */
6189 cyclic_insn_list = NULL;
6190 do
6191 {
6192 next_insn = curr_insn->next_equiv_class_insn;
6193 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6194 if (arc == NULL
6195 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6196 != arc->to_state))
6197 {
6198 delete_ainsn_from_equiv_class (curr_insn);
6199 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6200 cyclic_insn_list);
6201 }
6202 curr_insn = next_insn;
6203 }
6204 while (curr_insn != ainsn);
6205}
6206
6207/* The function processes STATE in order to find equivalent ainsns. */
6208static void
3d7aafde 6209process_state_for_insn_equiv_partition (state_t state)
fae15c93
VM
6210{
6211 arc_t arc;
5ed6ace5 6212 arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
fae15c93 6213
fae15c93 6214 /* Process insns of the arcs. */
fae15c93
VM
6215 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6216 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6217 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6218 process_insn_equiv_class (arc->insn, insn_arcs_array);
1fb49ce7
ZW
6219
6220 free (insn_arcs_array);
fae15c93
VM
6221}
6222
6223/* The function searches for equivalent ainsns of AUTOMATON. */
6224static void
3d7aafde 6225set_insn_equiv_classes (automaton_t automaton)
fae15c93
VM
6226{
6227 ainsn_t ainsn;
6228 ainsn_t first_insn;
6229 ainsn_t curr_insn;
6230 ainsn_t cyclic_insn_list;
6231 ainsn_t insn_with_same_reservs;
6232 int equiv_classes_num;
6233
6234 /* All insns are included in one equivalence class. */
6235 cyclic_insn_list = NULL;
6236 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6237 if (ainsn->first_insn_with_same_reservs)
6238 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6239 cyclic_insn_list);
6240 /* Process insns in order to make equivalence partition. */
6241 pass_states (automaton, process_state_for_insn_equiv_partition);
6242 /* Enumerate equiv classes. */
6243 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6244 /* Set undefined value. */
6245 ainsn->insn_equiv_class_num = -1;
6246 equiv_classes_num = 0;
6247 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6248 if (ainsn->insn_equiv_class_num < 0)
6249 {
6250 first_insn = ainsn;
b2d59f6f 6251 gcc_assert (first_insn->first_insn_with_same_reservs);
56ae04af 6252 first_insn->first_ainsn_with_given_equivalence_num = 1;
fae15c93
VM
6253 curr_insn = first_insn;
6254 do
6255 {
6256 for (insn_with_same_reservs = curr_insn;
6257 insn_with_same_reservs != NULL;
6258 insn_with_same_reservs
6259 = insn_with_same_reservs->next_same_reservs_insn)
6260 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6261 curr_insn = curr_insn->next_equiv_class_insn;
6262 }
6263 while (curr_insn != first_insn);
6264 equiv_classes_num++;
6265 }
6266 automaton->insn_equiv_classes_num = equiv_classes_num;
6267}
6268
6269\f
6270
6271/* This page contains code for creating DFA(s) and calls functions
6272 building them. */
6273
6274
6275/* The following value is used to prevent floating point overflow for
6276 estimating an automaton bound. The value should be less DBL_MAX on
6277 the host machine. We use here approximate minimum of maximal
6278 double floating point value required by ANSI C standard. It
6279 will work for non ANSI sun compiler too. */
6280
6281#define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6282
6283/* The function estimate size of the single DFA used by PHR (pipeline
6284 hazards recognizer). */
6285static double
3d7aafde 6286estimate_one_automaton_bound (void)
fae15c93
VM
6287{
6288 decl_t decl;
6289 double one_automaton_estimation_bound;
6290 double root_value;
6291 int i;
6292
6293 one_automaton_estimation_bound = 1.0;
6294 for (i = 0; i < description->decls_num; i++)
6295 {
6296 decl = description->decls [i];
6297 if (decl->mode == dm_unit)
6298 {
30028c85
VM
6299 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6300 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
fae15c93
VM
6301 / automata_num);
6302 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6303 > one_automaton_estimation_bound)
6304 one_automaton_estimation_bound *= root_value;
6305 }
6306 }
6307 return one_automaton_estimation_bound;
6308}
6309
96e13905 6310/* The function compares unit declarations according to their maximal
fae15c93
VM
6311 cycle in reservations. */
6312static int
3d7aafde
AJ
6313compare_max_occ_cycle_nums (const void *unit_decl_1,
6314 const void *unit_decl_2)
fae15c93 6315{
4005971c
VM
6316 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6317 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
fae15c93 6318 return 1;
4005971c
VM
6319 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6320 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
fae15c93
VM
6321 return 0;
6322 else
6323 return -1;
6324}
6325
6326/* The function makes heuristic assigning automata to units. Actually
6327 efficacy of the algorithm has been checked yet??? */
1fb49ce7 6328
fae15c93 6329static void
3d7aafde 6330units_to_automata_heuristic_distr (void)
fae15c93
VM
6331{
6332 double estimation_bound;
fae15c93
VM
6333 int automaton_num;
6334 int rest_units_num;
6335 double bound_value;
1fb49ce7
ZW
6336 unit_decl_t *unit_decls;
6337 int i, j;
fae15c93
VM
6338
6339 if (description->units_num == 0)
6340 return;
6341 estimation_bound = estimate_one_automaton_bound ();
5ed6ace5 6342 unit_decls = XNEWVEC (unit_decl_t, description->units_num);
1fb49ce7
ZW
6343
6344 for (i = 0, j = 0; i < description->decls_num; i++)
6345 if (description->decls[i]->mode == dm_unit)
6346 unit_decls[j++] = DECL_UNIT (description->decls[i]);
6347 gcc_assert (j == description->units_num);
6348
6349 qsort (unit_decls, description->units_num,
6350 sizeof (unit_decl_t), compare_max_occ_cycle_nums);
6351
fae15c93 6352 automaton_num = 0;
1fb49ce7
ZW
6353 bound_value = unit_decls[0]->max_occ_cycle_num;
6354 unit_decls[0]->corresponding_automaton_num = automaton_num;
6355
6356 for (i = 1; i < description->units_num; i++)
6357 {
6358 rest_units_num = description->units_num - i + 1;
b2d59f6f 6359 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
fae15c93
VM
6360 if (automaton_num < automata_num - 1
6361 && ((automata_num - automaton_num - 1 == rest_units_num)
6362 || (bound_value
6363 > (estimation_bound
1fb49ce7 6364 / unit_decls[i]->max_occ_cycle_num))))
fae15c93 6365 {
1fb49ce7 6366 bound_value = unit_decls[i]->max_occ_cycle_num;
fae15c93
VM
6367 automaton_num++;
6368 }
6369 else
1fb49ce7
ZW
6370 bound_value *= unit_decls[i]->max_occ_cycle_num;
6371 unit_decls[i]->corresponding_automaton_num = automaton_num;
fae15c93 6372 }
b2d59f6f 6373 gcc_assert (automaton_num == automata_num - 1);
1fb49ce7 6374 free (unit_decls);
fae15c93
VM
6375}
6376
6377/* The functions creates automaton insns for each automata. Automaton
6378 insn is simply insn for given automaton which makes reservation
6379 only of units of the automaton. */
6380static ainsn_t
3d7aafde 6381create_ainsns (void)
fae15c93
VM
6382{
6383 decl_t decl;
6384 ainsn_t first_ainsn;
6385 ainsn_t curr_ainsn;
6386 ainsn_t prev_ainsn;
6387 int i;
6388
6389 first_ainsn = NULL;
6390 prev_ainsn = NULL;
6391 for (i = 0; i < description->decls_num; i++)
6392 {
6393 decl = description->decls [i];
6394 if (decl->mode == dm_insn_reserv)
6395 {
6396 curr_ainsn = create_node (sizeof (struct ainsn));
4005971c 6397 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
fae15c93
VM
6398 curr_ainsn->important_p = FALSE;
6399 curr_ainsn->next_ainsn = NULL;
6400 if (prev_ainsn == NULL)
6401 first_ainsn = curr_ainsn;
6402 else
6403 prev_ainsn->next_ainsn = curr_ainsn;
6404 prev_ainsn = curr_ainsn;
6405 }
6406 }
6407 return first_ainsn;
6408}
6409
6410/* The function assigns automata to units according to constructions
6411 `define_automaton' in the description. */
6412static void
3d7aafde 6413units_to_automata_distr (void)
fae15c93
VM
6414{
6415 decl_t decl;
6416 int i;
3d7aafde 6417
fae15c93
VM
6418 for (i = 0; i < description->decls_num; i++)
6419 {
6420 decl = description->decls [i];
6421 if (decl->mode == dm_unit)
6422 {
4005971c
VM
6423 if (DECL_UNIT (decl)->automaton_decl == NULL
6424 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
fae15c93
VM
6425 == NULL))
6426 /* Distribute to the first automaton. */
4005971c 6427 DECL_UNIT (decl)->corresponding_automaton_num = 0;
fae15c93 6428 else
4005971c
VM
6429 DECL_UNIT (decl)->corresponding_automaton_num
6430 = (DECL_UNIT (decl)->automaton_decl
fae15c93
VM
6431 ->corresponding_automaton->automaton_order_num);
6432 }
6433 }
6434}
6435
6436/* The function creates DFA(s) for fast pipeline hazards recognition
6437 after checking and simplifying IR of the description. */
6438static void
3d7aafde 6439create_automata (void)
fae15c93
VM
6440{
6441 automaton_t curr_automaton;
6442 automaton_t prev_automaton;
6443 decl_t decl;
6444 int curr_automaton_num;
6445 int i;
6446
6447 if (automata_num != 0)
6448 {
6449 units_to_automata_heuristic_distr ();
6450 for (prev_automaton = NULL, curr_automaton_num = 0;
6451 curr_automaton_num < automata_num;
6452 curr_automaton_num++, prev_automaton = curr_automaton)
6453 {
6454 curr_automaton = create_node (sizeof (struct automaton));
6455 curr_automaton->ainsn_list = create_ainsns ();
6456 curr_automaton->corresponding_automaton_decl = NULL;
6457 curr_automaton->next_automaton = NULL;
6458 curr_automaton->automaton_order_num = curr_automaton_num;
6459 if (prev_automaton == NULL)
6460 description->first_automaton = curr_automaton;
6461 else
6462 prev_automaton->next_automaton = curr_automaton;
6463 }
6464 }
6465 else
6466 {
6467 curr_automaton_num = 0;
6468 prev_automaton = NULL;
6469 for (i = 0; i < description->decls_num; i++)
6470 {
6471 decl = description->decls [i];
6472 if (decl->mode == dm_automaton
4005971c 6473 && DECL_AUTOMATON (decl)->automaton_is_used)
fae15c93
VM
6474 {
6475 curr_automaton = create_node (sizeof (struct automaton));
6476 curr_automaton->ainsn_list = create_ainsns ();
6477 curr_automaton->corresponding_automaton_decl
4005971c 6478 = DECL_AUTOMATON (decl);
fae15c93 6479 curr_automaton->next_automaton = NULL;
4005971c 6480 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
fae15c93
VM
6481 curr_automaton->automaton_order_num = curr_automaton_num;
6482 if (prev_automaton == NULL)
6483 description->first_automaton = curr_automaton;
6484 else
6485 prev_automaton->next_automaton = curr_automaton;
6486 curr_automaton_num++;
6487 prev_automaton = curr_automaton;
6488 }
6489 }
6490 if (curr_automaton_num == 0)
6491 {
6492 curr_automaton = create_node (sizeof (struct automaton));
6493 curr_automaton->ainsn_list = create_ainsns ();
6494 curr_automaton->corresponding_automaton_decl = NULL;
6495 curr_automaton->next_automaton = NULL;
6496 description->first_automaton = curr_automaton;
6497 }
6498 units_to_automata_distr ();
6499 }
6500 NDFA_time = create_ticker ();
6501 ticker_off (&NDFA_time);
6502 NDFA_to_DFA_time = create_ticker ();
6503 ticker_off (&NDFA_to_DFA_time);
6504 minimize_time = create_ticker ();
6505 ticker_off (&minimize_time);
6506 equiv_time = create_ticker ();
6507 ticker_off (&equiv_time);
6508 for (curr_automaton = description->first_automaton;
6509 curr_automaton != NULL;
6510 curr_automaton = curr_automaton->next_automaton)
6511 {
dfa849f3
VM
6512 if (progress_flag)
6513 {
6514 if (curr_automaton->corresponding_automaton_decl == NULL)
6515 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6516 else
6517 fprintf (stderr, "Prepare automaton `%s' creation...",
6518 curr_automaton->corresponding_automaton_decl->name);
6519 }
fae15c93
VM
6520 create_alt_states (curr_automaton);
6521 form_ainsn_with_same_reservs (curr_automaton);
dfa849f3
VM
6522 if (progress_flag)
6523 fprintf (stderr, "done\n");
fae15c93
VM
6524 build_automaton (curr_automaton);
6525 enumerate_states (curr_automaton);
6526 ticker_on (&equiv_time);
6527 set_insn_equiv_classes (curr_automaton);
6528 ticker_off (&equiv_time);
fae15c93
VM
6529 }
6530}
6531
6532\f
6533
6534/* This page contains code for forming string representation of
6535 regexp. The representation is formed on IR obstack. So you should
6536 not work with IR obstack between regexp_representation and
6537 finish_regexp_representation calls. */
6538
6539/* This recursive function forms string representation of regexp
6540 (without tailing '\0'). */
6541static void
3d7aafde 6542form_regexp (regexp_t regexp)
fae15c93
VM
6543{
6544 int i;
3d7aafde 6545
b2d59f6f 6546 switch (regexp->mode)
fae15c93 6547 {
b2d59f6f 6548 case rm_unit: case rm_reserv:
fae15c93 6549 {
b2d59f6f
NS
6550 const char *name = (regexp->mode == rm_unit
6551 ? REGEXP_UNIT (regexp)->name
6552 : REGEXP_RESERV (regexp)->name);
6553
6554 obstack_grow (&irp, name, strlen (name));
6555 break;
fae15c93 6556 }
b2d59f6f
NS
6557
6558 case rm_sequence:
6559 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6560 {
6561 if (i != 0)
6562 obstack_1grow (&irp, ',');
6563 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6564 }
6565 break;
6566
6567 case rm_allof:
fae15c93 6568 obstack_1grow (&irp, '(');
4005971c 6569 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
fae15c93
VM
6570 {
6571 if (i != 0)
6572 obstack_1grow (&irp, '+');
4005971c
VM
6573 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6574 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
fae15c93 6575 obstack_1grow (&irp, '(');
4005971c
VM
6576 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6577 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6578 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
fae15c93
VM
6579 obstack_1grow (&irp, ')');
6580 }
6581 obstack_1grow (&irp, ')');
b2d59f6f
NS
6582 break;
6583
6584 case rm_oneof:
6585 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6586 {
6587 if (i != 0)
6588 obstack_1grow (&irp, '|');
6589 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6590 obstack_1grow (&irp, '(');
6591 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6592 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
fae15c93 6593 obstack_1grow (&irp, ')');
b2d59f6f
NS
6594 }
6595 break;
6596
6597 case rm_repeat:
6598 {
6599 char digits [30];
6600
6601 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6602 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6603 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6604 obstack_1grow (&irp, '(');
6605 form_regexp (REGEXP_REPEAT (regexp)->regexp);
6606 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6607 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6608 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6609 obstack_1grow (&irp, ')');
6610 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6611 obstack_grow (&irp, digits, strlen (digits));
6612 break;
fae15c93 6613 }
b2d59f6f
NS
6614
6615 case rm_nothing:
6616 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6617 break;
6618
6619 default:
6620 gcc_unreachable ();
6621 }
fae15c93
VM
6622}
6623
6624/* The function returns string representation of REGEXP on IR
6625 obstack. */
6626static const char *
3d7aafde 6627regexp_representation (regexp_t regexp)
fae15c93
VM
6628{
6629 form_regexp (regexp);
6630 obstack_1grow (&irp, '\0');
6631 return obstack_base (&irp);
6632}
6633
6634/* The function frees memory allocated for last formed string
6635 representation of regexp. */
6636static void
3d7aafde 6637finish_regexp_representation (void)
fae15c93
VM
6638{
6639 int length = obstack_object_size (&irp);
3d7aafde 6640
fae15c93
VM
6641 obstack_blank_fast (&irp, -length);
6642}
6643
6644\f
6645
6646/* This page contains code for output PHR (pipeline hazards recognizer). */
6647
6648/* The function outputs minimal C type which is sufficient for
6649 representation numbers in range min_range_value and
6650 max_range_value. Because host machine and build machine may be
6651 different, we use here minimal values required by ANSI C standard
6652 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6653 approximation. */
6654
6655static void
3d7aafde
AJ
6656output_range_type (FILE *f, long int min_range_value,
6657 long int max_range_value)
fae15c93
VM
6658{
6659 if (min_range_value >= 0 && max_range_value <= 255)
6660 fprintf (f, "unsigned char");
6661 else if (min_range_value >= -127 && max_range_value <= 127)
6662 fprintf (f, "signed char");
6663 else if (min_range_value >= 0 && max_range_value <= 65535)
6664 fprintf (f, "unsigned short");
6665 else if (min_range_value >= -32767 && max_range_value <= 32767)
6666 fprintf (f, "short");
6667 else
6668 fprintf (f, "int");
6669}
6670
1fb49ce7 6671/* The function outputs all initialization values of VECT. */
fae15c93 6672static void
1fb49ce7 6673output_vect (vla_hwint_t vect)
fae15c93
VM
6674{
6675 int els_on_line;
1fb49ce7
ZW
6676 size_t vect_length = VEC_length (vect_el_t, vect);
6677 size_t i;
fae15c93
VM
6678
6679 els_on_line = 1;
6680 if (vect_length == 0)
1fb49ce7 6681 fputs ("0 /* This is dummy el because the vect is empty */", output_file);
fae15c93 6682 else
1fb49ce7
ZW
6683 for (i = 0; i < vect_length; i++)
6684 {
6685 fprintf (output_file, "%5ld", (long) VEC_index (vect_el_t, vect, i));
6686 if (els_on_line == 10)
6687 {
6688 els_on_line = 0;
6689 fputs (",\n", output_file);
6690 }
6691 else if (i < vect_length-1)
6692 fputs (", ", output_file);
6693 els_on_line++;
6694 }
fae15c93
VM
6695}
6696
6697/* The following is name of the structure which represents DFA(s) for
6698 PHR. */
6699#define CHIP_NAME "DFA_chip"
6700
6701/* The following is name of member which represents state of a DFA for
6702 PHR. */
6703static void
3d7aafde 6704output_chip_member_name (FILE *f, automaton_t automaton)
fae15c93
VM
6705{
6706 if (automaton->corresponding_automaton_decl == NULL)
6707 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6708 else
6709 fprintf (f, "%s_automaton_state",
6710 automaton->corresponding_automaton_decl->name);
6711}
6712
6713/* The following is name of temporary variable which stores state of a
6714 DFA for PHR. */
6715static void
3d7aafde 6716output_temp_chip_member_name (FILE *f, automaton_t automaton)
fae15c93
VM
6717{
6718 fprintf (f, "_");
6719 output_chip_member_name (f, automaton);
6720}
6721
6722/* This is name of macro value which is code of pseudo_insn
6723 representing advancing cpu cycle. Its value is used as internal
6724 code unknown insn. */
6725#define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6726
6727/* Output name of translate vector for given automaton. */
6728static void
3d7aafde 6729output_translate_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6730{
6731 if (automaton->corresponding_automaton_decl == NULL)
6732 fprintf (f, "translate_%d", automaton->automaton_order_num);
6733 else
6734 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6735}
6736
6737/* Output name for simple transition table representation. */
6738static void
3d7aafde 6739output_trans_full_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6740{
6741 if (automaton->corresponding_automaton_decl == NULL)
6742 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6743 else
6744 fprintf (f, "%s_transitions",
6745 automaton->corresponding_automaton_decl->name);
6746}
6747
6748/* Output name of comb vector of the transition table for given
6749 automaton. */
6750static void
3d7aafde 6751output_trans_comb_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6752{
6753 if (automaton->corresponding_automaton_decl == NULL)
6754 fprintf (f, "transitions_%d", automaton->automaton_order_num);
6755 else
6756 fprintf (f, "%s_transitions",
6757 automaton->corresponding_automaton_decl->name);
6758}
6759
6760/* Output name of check vector of the transition table for given
6761 automaton. */
6762static void
3d7aafde 6763output_trans_check_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6764{
6765 if (automaton->corresponding_automaton_decl == NULL)
6766 fprintf (f, "check_%d", automaton->automaton_order_num);
6767 else
6768 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6769}
6770
6771/* Output name of base vector of the transition table for given
6772 automaton. */
6773static void
3d7aafde 6774output_trans_base_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6775{
6776 if (automaton->corresponding_automaton_decl == NULL)
6777 fprintf (f, "base_%d", automaton->automaton_order_num);
6778 else
6779 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6780}
6781
fae15c93
VM
6782/* Output name of simple min issue delay table representation. */
6783static void
3d7aafde 6784output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6785{
6786 if (automaton->corresponding_automaton_decl == NULL)
6787 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6788 else
6789 fprintf (f, "%s_min_issue_delay",
6790 automaton->corresponding_automaton_decl->name);
6791}
6792
6793/* Output name of deadlock vector for given automaton. */
6794static void
3d7aafde 6795output_dead_lock_vect_name (FILE *f, automaton_t automaton)
fae15c93
VM
6796{
6797 if (automaton->corresponding_automaton_decl == NULL)
6798 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6799 else
6800 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6801}
6802
6803/* Output name of reserved units table for AUTOMATON into file F. */
6804static void
3d7aafde 6805output_reserved_units_table_name (FILE *f, automaton_t automaton)
fae15c93
VM
6806{
6807 if (automaton->corresponding_automaton_decl == NULL)
6808 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6809 else
6810 fprintf (f, "%s_reserved_units",
6811 automaton->corresponding_automaton_decl->name);
6812}
6813
fae15c93
VM
6814/* Name of the PHR interface macro. */
6815#define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6816
6817/* Names of an internal functions: */
6818#define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6819
6820/* This is external type of DFA(s) state. */
6821#define STATE_TYPE_NAME "state_t"
6822
6823#define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6824
fae15c93
VM
6825#define INTERNAL_RESET_FUNC_NAME "internal_reset"
6826
6827#define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6828
6829#define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6830
6831/* Name of cache of insn dfa codes. */
6832#define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6833
deb09eff 6834/* Name of length of cache of insn dfa codes. */
fae15c93
VM
6835#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6836
6837/* Names of the PHR interface functions: */
6838#define SIZE_FUNC_NAME "state_size"
6839
6840#define TRANSITION_FUNC_NAME "state_transition"
6841
fae15c93
VM
6842#define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6843
6844#define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6845
6846#define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6847
6848#define RESET_FUNC_NAME "state_reset"
6849
6850#define INSN_LATENCY_FUNC_NAME "insn_latency"
6851
6852#define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6853
6854#define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6855
6856#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6857
30028c85
VM
6858#define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
6859
496d7bb0
MK
6860#define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
6861
fae15c93
VM
6862#define DFA_START_FUNC_NAME "dfa_start"
6863
6864#define DFA_FINISH_FUNC_NAME "dfa_finish"
6865
6866/* Names of parameters of the PHR interface functions. */
6867#define STATE_NAME "state"
6868
6869#define INSN_PARAMETER_NAME "insn"
6870
6871#define INSN2_PARAMETER_NAME "insn2"
6872
6873#define CHIP_PARAMETER_NAME "chip"
6874
6875#define FILE_PARAMETER_NAME "f"
6876
6877#define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6878
6879#define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6880
6881/* Names of the variables whose values are internal insn code of rtx
6882 insn. */
6883#define INTERNAL_INSN_CODE_NAME "insn_code"
6884
6885#define INTERNAL_INSN2_CODE_NAME "insn2_code"
6886
6887/* Names of temporary variables in some functions. */
6888#define TEMPORARY_VARIABLE_NAME "temp"
6889
6890#define I_VARIABLE_NAME "i"
6891
6892/* Name of result variable in some functions. */
6893#define RESULT_VARIABLE_NAME "res"
6894
fae15c93
VM
6895/* Name of function (attribute) to translate insn into internal insn
6896 code. */
6897#define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6898
6899/* Name of function (attribute) to translate insn into internal insn
6900 code with caching. */
6901#define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6902
fae15c93
VM
6903/* Output C type which is used for representation of codes of states
6904 of AUTOMATON. */
6905static void
3d7aafde 6906output_state_member_type (FILE *f, automaton_t automaton)
fae15c93
VM
6907{
6908 output_range_type (f, 0, automaton->achieved_states_num);
6909}
6910
6911/* Output definition of the structure representing current DFA(s)
6912 state(s). */
6913static void
3d7aafde 6914output_chip_definitions (void)
fae15c93
VM
6915{
6916 automaton_t automaton;
6917
6918 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
6919 for (automaton = description->first_automaton;
6920 automaton != NULL;
6921 automaton = automaton->next_automaton)
6922 {
6923 fprintf (output_file, " ");
6924 output_state_member_type (output_file, automaton);
6925 fprintf (output_file, " ");
6926 output_chip_member_name (output_file, automaton);
6927 fprintf (output_file, ";\n");
6928 }
6929 fprintf (output_file, "};\n\n");
6930#if 0
6931 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
6932#endif
6933}
6934
6935
6936/* The function outputs translate vector of internal insn code into
6937 insn equivalence class number. The equivalence class number is
96e13905 6938 used to access to table and vectors representing DFA(s). */
fae15c93 6939static void
3d7aafde 6940output_translate_vect (automaton_t automaton)
fae15c93
VM
6941{
6942 ainsn_t ainsn;
6943 int insn_value;
6944 vla_hwint_t translate_vect;
6945
1fb49ce7
ZW
6946 translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num);
6947
2fcb395c 6948 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
fae15c93 6949 /* Undefined value */
1fb49ce7
ZW
6950 VEC_quick_push (vect_el_t, translate_vect,
6951 automaton->insn_equiv_classes_num);
6952
fae15c93 6953 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
1fb49ce7
ZW
6954 VEC_replace (vect_el_t, translate_vect,
6955 ainsn->insn_reserv_decl->insn_num,
6956 ainsn->insn_equiv_class_num);
6957
fae15c93
VM
6958 fprintf (output_file,
6959 "/* Vector translating external insn codes to internal ones.*/\n");
6960 fprintf (output_file, "static const ");
6961 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
6962 fprintf (output_file, " ");
6963 output_translate_vect_name (output_file, automaton);
2bf087c0 6964 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
1fb49ce7 6965 output_vect (translate_vect);
fae15c93 6966 fprintf (output_file, "};\n\n");
1fb49ce7 6967 VEC_free (vect_el_t,heap, translate_vect);
fae15c93
VM
6968}
6969
6970/* The value in a table state x ainsn -> something which represents
6971 undefined value. */
6972static int undefined_vect_el_value;
6973
6974/* The following function returns nonzero value if the best
6975 representation of the table is comb vector. */
6976static int
3d7aafde 6977comb_vect_p (state_ainsn_table_t tab)
fae15c93 6978{
1fb49ce7
ZW
6979 return (2 * VEC_length (vect_el_t, tab->full_vect)
6980 > 5 * VEC_length (vect_el_t, tab->comb_vect));
fae15c93
VM
6981}
6982
6983/* The following function creates new table for AUTOMATON. */
6984static state_ainsn_table_t
3d7aafde 6985create_state_ainsn_table (automaton_t automaton)
fae15c93
VM
6986{
6987 state_ainsn_table_t tab;
6988 int full_vect_length;
6989 int i;
6990
6991 tab = create_node (sizeof (struct state_ainsn_table));
6992 tab->automaton = automaton;
1fb49ce7
ZW
6993
6994 tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000);
6995 tab->check_vect = VEC_alloc (vect_el_t,heap, 10000);
6996
6997 tab->base_vect = 0;
6998 VEC_safe_grow (vect_el_t,heap, tab->base_vect,
6999 automaton->achieved_states_num);
7000
fae15c93
VM
7001 full_vect_length = (automaton->insn_equiv_classes_num
7002 * automaton->achieved_states_num);
1fb49ce7 7003 tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length);
fae15c93 7004 for (i = 0; i < full_vect_length; i++)
1fb49ce7
ZW
7005 VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
7006
fae15c93
VM
7007 tab->min_base_vect_el_value = 0;
7008 tab->max_base_vect_el_value = 0;
7009 tab->min_comb_vect_el_value = 0;
7010 tab->max_comb_vect_el_value = 0;
7011 return tab;
7012}
7013
7014/* The following function outputs the best C representation of the
7015 table TAB of given TABLE_NAME. */
7016static void
1fb49ce7 7017output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
3d7aafde
AJ
7018 void (*output_full_vect_name_func) (FILE *, automaton_t),
7019 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7020 void (*output_check_vect_name_func) (FILE *, automaton_t),
7021 void (*output_base_vect_name_func) (FILE *, automaton_t))
fae15c93
VM
7022{
7023 if (!comb_vect_p (tab))
7024 {
7025 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7026 fprintf (output_file, "static const ");
7027 output_range_type (output_file, tab->min_comb_vect_el_value,
7028 tab->max_comb_vect_el_value);
7029 fprintf (output_file, " ");
7030 (*output_full_vect_name_func) (output_file, tab->automaton);
2bf087c0 7031 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
1fb49ce7 7032 output_vect (tab->full_vect);
fae15c93
VM
7033 fprintf (output_file, "};\n\n");
7034 }
7035 else
7036 {
7037 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7038 fprintf (output_file, "static const ");
7039 output_range_type (output_file, tab->min_comb_vect_el_value,
7040 tab->max_comb_vect_el_value);
7041 fprintf (output_file, " ");
7042 (*output_comb_vect_name_func) (output_file, tab->automaton);
2bf087c0 7043 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
1fb49ce7 7044 output_vect (tab->comb_vect);
fae15c93
VM
7045 fprintf (output_file, "};\n\n");
7046 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7047 fprintf (output_file, "static const ");
7048 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7049 fprintf (output_file, " ");
7050 (*output_check_vect_name_func) (output_file, tab->automaton);
7051 fprintf (output_file, "[] = {\n");
1fb49ce7 7052 output_vect (tab->check_vect);
fae15c93
VM
7053 fprintf (output_file, "};\n\n");
7054 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7055 fprintf (output_file, "static const ");
7056 output_range_type (output_file, tab->min_base_vect_el_value,
7057 tab->max_base_vect_el_value);
7058 fprintf (output_file, " ");
7059 (*output_base_vect_name_func) (output_file, tab->automaton);
7060 fprintf (output_file, "[] = {\n");
1fb49ce7 7061 output_vect (tab->base_vect);
fae15c93
VM
7062 fprintf (output_file, "};\n\n");
7063 }
7064}
7065
1fb49ce7
ZW
7066/* The following function adds vector VECT to table TAB as its line
7067 with number VECT_NUM. */
fae15c93 7068static void
1fb49ce7 7069add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
fae15c93 7070{
1fb49ce7
ZW
7071 int vect_length;
7072 size_t real_vect_length;
fae15c93
VM
7073 int comb_vect_index;
7074 int comb_vect_els_num;
7075 int vect_index;
7076 int first_unempty_vect_index;
7077 int additional_els_num;
7078 int no_state_value;
7079 vect_el_t vect_el;
7080 int i;
00ca8311 7081 unsigned long vect_mask, comb_vect_mask;
fae15c93 7082
1fb49ce7 7083 vect_length = VEC_length (vect_el_t, vect);
b2d59f6f 7084 gcc_assert (vect_length);
1fb49ce7 7085 gcc_assert (VEC_last (vect_el_t, vect) != undefined_vect_el_value);
fae15c93 7086 real_vect_length = tab->automaton->insn_equiv_classes_num;
fae15c93 7087 /* Form full vector in the table: */
1fb49ce7
ZW
7088 {
7089 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
7090 if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
7091 VEC_safe_grow (vect_el_t,heap, tab->full_vect,
7092 full_base + vect_length);
7093 for (i = 0; i < vect_length; i++)
7094 VEC_replace (vect_el_t, tab->full_vect, full_base + i,
7095 VEC_index (vect_el_t, vect, i));
7096 }
fae15c93 7097 /* Form comb vector in the table: */
1fb49ce7
ZW
7098 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7099 == VEC_length (vect_el_t, tab->check_vect));
7100
7101 comb_vect_els_num = VEC_length (vect_el_t, tab->comb_vect);
fae15c93
VM
7102 for (first_unempty_vect_index = 0;
7103 first_unempty_vect_index < vect_length;
7104 first_unempty_vect_index++)
1fb49ce7
ZW
7105 if (VEC_index (vect_el_t, vect, first_unempty_vect_index)
7106 != undefined_vect_el_value)
fae15c93 7107 break;
00ca8311 7108
fae15c93 7109 /* Search for the place in comb vect for the inserted vect. */
00ca8311
SB
7110
7111 /* Slow case. */
7112 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7113 {
7114 for (comb_vect_index = 0;
7115 comb_vect_index < comb_vect_els_num;
7116 comb_vect_index++)
7117 {
7118 for (vect_index = first_unempty_vect_index;
7119 vect_index < vect_length
7120 && vect_index + comb_vect_index < comb_vect_els_num;
7121 vect_index++)
1fb49ce7
ZW
7122 if (VEC_index (vect_el_t, vect, vect_index)
7123 != undefined_vect_el_value
7124 && (VEC_index (vect_el_t, tab->comb_vect,
7125 vect_index + comb_vect_index)
00ca8311
SB
7126 != undefined_vect_el_value))
7127 break;
7128 if (vect_index >= vect_length
7129 || vect_index + comb_vect_index >= comb_vect_els_num)
7130 break;
7131 }
7132 goto found;
fae15c93 7133 }
00ca8311
SB
7134
7135 /* Fast case. */
7136 vect_mask = 0;
7137 for (vect_index = first_unempty_vect_index;
7138 vect_index < vect_length;
7139 vect_index++)
7140 {
7141 vect_mask = vect_mask << 1;
1fb49ce7 7142 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
00ca8311
SB
7143 vect_mask |= 1;
7144 }
7145
7146 /* Search for the place in comb vect for the inserted vect. */
7147 comb_vect_index = 0;
7148 if (comb_vect_els_num == 0)
7149 goto found;
7150
7151 comb_vect_mask = 0;
7152 for (vect_index = first_unempty_vect_index;
7153 vect_index < vect_length && vect_index < comb_vect_els_num;
7154 vect_index++)
7155 {
7156 comb_vect_mask <<= 1;
7157 if (vect_index + comb_vect_index < comb_vect_els_num
1fb49ce7 7158 && VEC_index (vect_el_t, tab->comb_vect, vect_index + comb_vect_index)
00ca8311
SB
7159 != undefined_vect_el_value)
7160 comb_vect_mask |= 1;
7161 }
7162 if ((vect_mask & comb_vect_mask) == 0)
7163 goto found;
7164
7165 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7166 comb_vect_index++, i++)
7167 {
7168 comb_vect_mask = (comb_vect_mask << 1) | 1;
1fb49ce7
ZW
7169 comb_vect_mask ^= (VEC_index (vect_el_t, tab->comb_vect, i)
7170 == undefined_vect_el_value);
00ca8311
SB
7171 if ((vect_mask & comb_vect_mask) == 0)
7172 goto found;
7173 }
7174 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7175 {
7176 comb_vect_mask <<= 1;
7177 if ((vect_mask & comb_vect_mask) == 0)
7178 goto found;
7179 }
7180
b2d59f6f 7181 found:
fae15c93
VM
7182 /* Slot was found. */
7183 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7184 if (additional_els_num < 0)
7185 additional_els_num = 0;
7186 /* Expand comb and check vectors. */
7187 vect_el = undefined_vect_el_value;
7188 no_state_value = tab->automaton->achieved_states_num;
7189 while (additional_els_num > 0)
7190 {
1fb49ce7
ZW
7191 VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el);
7192 VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value);
fae15c93
VM
7193 additional_els_num--;
7194 }
1fb49ce7
ZW
7195 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7196 >= comb_vect_index + real_vect_length);
fae15c93
VM
7197 /* Fill comb and check vectors. */
7198 for (vect_index = 0; vect_index < vect_length; vect_index++)
1fb49ce7 7199 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
fae15c93 7200 {
1fb49ce7
ZW
7201 vect_el_t x = VEC_index (vect_el_t, vect, vect_index);
7202 gcc_assert (VEC_index (vect_el_t, tab->comb_vect,
7203 comb_vect_index + vect_index)
b2d59f6f 7204 == undefined_vect_el_value);
1fb49ce7
ZW
7205 gcc_assert (x >= 0);
7206 if (tab->max_comb_vect_el_value < x)
7207 tab->max_comb_vect_el_value = x;
7208 if (tab->min_comb_vect_el_value > x)
7209 tab->min_comb_vect_el_value = x;
7210 VEC_replace (vect_el_t, tab->comb_vect,
7211 comb_vect_index + vect_index, x);
7212 VEC_replace (vect_el_t, tab->check_vect,
7213 comb_vect_index + vect_index, vect_num);
fae15c93 7214 }
74719742
VM
7215 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7216 tab->max_comb_vect_el_value = undefined_vect_el_value;
7217 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7218 tab->min_comb_vect_el_value = undefined_vect_el_value;
fae15c93
VM
7219 if (tab->max_base_vect_el_value < comb_vect_index)
7220 tab->max_base_vect_el_value = comb_vect_index;
7221 if (tab->min_base_vect_el_value > comb_vect_index)
7222 tab->min_base_vect_el_value = comb_vect_index;
1fb49ce7
ZW
7223
7224 VEC_replace (vect_el_t, tab->base_vect, vect_num, comb_vect_index);
fae15c93
VM
7225}
7226
7227/* Return number of out arcs of STATE. */
7228static int
3d7aafde 7229out_state_arcs_num (state_t state)
fae15c93
VM
7230{
7231 int result;
7232 arc_t arc;
7233
7234 result = 0;
7235 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7236 {
b2d59f6f 7237 gcc_assert (arc->insn);
56ae04af 7238 if (arc->insn->first_ainsn_with_given_equivalence_num)
fae15c93
VM
7239 result++;
7240 }
7241 return result;
7242}
7243
7244/* Compare number of possible transitions from the states. */
7245static int
3d7aafde
AJ
7246compare_transition_els_num (const void *state_ptr_1,
7247 const void *state_ptr_2)
fae15c93
VM
7248{
7249 int transition_els_num_1;
7250 int transition_els_num_2;
7251
7252 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7253 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7254 if (transition_els_num_1 < transition_els_num_2)
7255 return 1;
7256 else if (transition_els_num_1 == transition_els_num_2)
7257 return 0;
7258 else
7259 return -1;
7260}
7261
7262/* The function adds element EL_VALUE to vector VECT for a table state
7263 x AINSN. */
7264static void
3d7aafde 7265add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
fae15c93
VM
7266{
7267 int equiv_class_num;
7268 int vect_index;
7269
b2d59f6f 7270 gcc_assert (ainsn);
fae15c93 7271 equiv_class_num = ainsn->insn_equiv_class_num;
1fb49ce7 7272 for (vect_index = VEC_length (vect_el_t, *vect);
fae15c93
VM
7273 vect_index <= equiv_class_num;
7274 vect_index++)
1fb49ce7
ZW
7275 VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value);
7276 VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
fae15c93
VM
7277}
7278
7279/* This is for forming vector of states of an automaton. */
1fb49ce7 7280static VEC(state_t,heap) *output_states_vect;
fae15c93
VM
7281
7282/* The function is called by function pass_states. The function adds
7283 STATE to `output_states_vect'. */
7284static void
3d7aafde 7285add_states_vect_el (state_t state)
fae15c93 7286{
1fb49ce7 7287 VEC_safe_push (state_t,heap, output_states_vect, state);
fae15c93
VM
7288}
7289
7290/* Form and output vectors (comb, check, base or full vector)
7291 representing transition table of AUTOMATON. */
7292static void
3d7aafde 7293output_trans_table (automaton_t automaton)
fae15c93 7294{
1fb49ce7 7295 size_t i;
fae15c93 7296 arc_t arc;
1fb49ce7 7297 vla_hwint_t transition_vect = 0;
fae15c93
VM
7298
7299 undefined_vect_el_value = automaton->achieved_states_num;
7300 automaton->trans_table = create_state_ainsn_table (automaton);
7301 /* Create vect of pointers to states ordered by num of transitions
7302 from the state (state with the maximum num is the first). */
1fb49ce7 7303 output_states_vect = 0;
fae15c93 7304 pass_states (automaton, add_states_vect_el);
1fb49ce7
ZW
7305 qsort (VEC_address (state_t, output_states_vect),
7306 VEC_length (state_t, output_states_vect),
fae15c93 7307 sizeof (state_t), compare_transition_els_num);
1fb49ce7
ZW
7308
7309 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
fae15c93 7310 {
1fb49ce7
ZW
7311 VEC_truncate (vect_el_t, transition_vect, 0);
7312 for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
fae15c93
VM
7313 arc != NULL;
7314 arc = next_out_arc (arc))
7315 {
b2d59f6f 7316 gcc_assert (arc->insn);
56ae04af 7317 if (arc->insn->first_ainsn_with_given_equivalence_num)
fae15c93
VM
7318 add_vect_el (&transition_vect, arc->insn,
7319 arc->to_state->order_state_num);
7320 }
1fb49ce7
ZW
7321 add_vect (automaton->trans_table,
7322 VEC_index (state_t, output_states_vect, i)->order_state_num,
7323 transition_vect);
fae15c93
VM
7324 }
7325 output_state_ainsn_table
1fb49ce7 7326 (automaton->trans_table, "state transitions",
fae15c93
VM
7327 output_trans_full_vect_name, output_trans_comb_vect_name,
7328 output_trans_check_vect_name, output_trans_base_vect_name);
1fb49ce7
ZW
7329
7330 VEC_free (state_t,heap, output_states_vect);
7331 VEC_free (vect_el_t,heap, transition_vect);
fae15c93
VM
7332}
7333
fae15c93
VM
7334/* The current number of passing states to find minimal issue delay
7335 value for an ainsn and state. */
7336static int curr_state_pass_num;
7337
fae15c93 7338/* This recursive function passes states to find minimal issue delay
0b2fb0d7
VM
7339 value for AINSN. The state being visited is STATE. The function
7340 returns minimal issue delay value for AINSN in STATE or -1 if we
7341 enter into a loop. */
7342static int
3d7aafde 7343min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
fae15c93
VM
7344{
7345 arc_t arc;
7346 int min_insn_issue_delay, insn_issue_delay;
7347
0b2fb0d7
VM
7348 if (state->state_pass_num == curr_state_pass_num
7349 || state->min_insn_issue_delay != -1)
7350 /* We've entered into a loop or already have the correct value for
deb09eff 7351 given state and ainsn. */
0b2fb0d7 7352 return state->min_insn_issue_delay;
fae15c93 7353 state->state_pass_num = curr_state_pass_num;
0b2fb0d7 7354 min_insn_issue_delay = -1;
fae15c93
VM
7355 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7356 if (arc->insn == ainsn)
7357 {
7358 min_insn_issue_delay = 0;
7359 break;
7360 }
7361 else
7362 {
0b2fb0d7
VM
7363 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7364 if (insn_issue_delay != -1)
fae15c93 7365 {
0b2fb0d7 7366 if (arc->insn->insn_reserv_decl
4005971c 7367 == DECL_INSN_RESERV (advance_cycle_insn_decl))
0b2fb0d7 7368 insn_issue_delay++;
fae15c93
VM
7369 if (min_insn_issue_delay == -1
7370 || min_insn_issue_delay > insn_issue_delay)
0b2fb0d7
VM
7371 {
7372 min_insn_issue_delay = insn_issue_delay;
7373 if (insn_issue_delay == 0)
7374 break;
7375 }
fae15c93
VM
7376 }
7377 }
0b2fb0d7 7378 return min_insn_issue_delay;
fae15c93
VM
7379}
7380
7381/* The function searches minimal issue delay value for AINSN in STATE.
0b2fb0d7
VM
7382 The function can return negative value if we can not issue AINSN. We
7383 will report about it later. */
fae15c93 7384static int
3d7aafde 7385min_issue_delay (state_t state, ainsn_t ainsn)
fae15c93
VM
7386{
7387 curr_state_pass_num++;
0b2fb0d7 7388 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
fae15c93
VM
7389 return state->min_insn_issue_delay;
7390}
7391
7392/* The function initiates code for finding minimal issue delay values.
7393 It should be called only once. */
7394static void
3d7aafde 7395initiate_min_issue_delay_pass_states (void)
fae15c93
VM
7396{
7397 curr_state_pass_num = 0;
7398}
7399
7400/* Form and output vectors representing minimal issue delay table of
7401 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7402 the ainsn. */
7403static void
3d7aafde 7404output_min_issue_delay_table (automaton_t automaton)
fae15c93
VM
7405{
7406 vla_hwint_t min_issue_delay_vect;
7407 vla_hwint_t compressed_min_issue_delay_vect;
7408 vect_el_t min_delay;
7409 ainsn_t ainsn;
1fb49ce7
ZW
7410 size_t i, min_issue_delay_len;
7411 size_t compressed_min_issue_delay_len;
7412 size_t cfactor;
fae15c93
VM
7413
7414 /* Create vect of pointers to states ordered by num of transitions
7415 from the state (state with the maximum num is the first). */
1fb49ce7 7416 output_states_vect = 0;
fae15c93 7417 pass_states (automaton, add_states_vect_el);
1fb49ce7
ZW
7418
7419 min_issue_delay_len = (VEC_length (state_t, output_states_vect)
7420 * automaton->insn_equiv_classes_num);
7421 min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len);
7422 for (i = 0; i < min_issue_delay_len; i++)
7423 VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
7424
fae15c93 7425 automaton->max_min_delay = 0;
0b2fb0d7 7426 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
56ae04af 7427 if (ainsn->first_ainsn_with_given_equivalence_num)
0b2fb0d7 7428 {
1fb49ce7
ZW
7429 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7430 VEC_index (state_t, output_states_vect, i)->min_insn_issue_delay = -1;
7431 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
0b2fb0d7 7432 {
1fb49ce7
ZW
7433 state_t s = VEC_index (state_t, output_states_vect, i);
7434 min_delay = min_issue_delay (s, ainsn);
fae15c93
VM
7435 if (automaton->max_min_delay < min_delay)
7436 automaton->max_min_delay = min_delay;
1fb49ce7
ZW
7437 VEC_replace (vect_el_t, min_issue_delay_vect,
7438 s->order_state_num
7439 * automaton->insn_equiv_classes_num
7440 + ainsn->insn_equiv_class_num,
7441 min_delay);
fae15c93 7442 }
0b2fb0d7 7443 }
30028c85 7444 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
fae15c93
VM
7445 fprintf (output_file, "static const ");
7446 output_range_type (output_file, 0, automaton->max_min_delay);
7447 fprintf (output_file, " ");
7448 output_min_issue_delay_vect_name (output_file, automaton);
2bf087c0 7449 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
f9da5064 7450 /* Compress the vector. */
fae15c93 7451 if (automaton->max_min_delay < 2)
1fb49ce7 7452 cfactor = 8;
fae15c93 7453 else if (automaton->max_min_delay < 4)
1fb49ce7 7454 cfactor = 4;
fae15c93 7455 else if (automaton->max_min_delay < 16)
1fb49ce7 7456 cfactor = 2;
fae15c93 7457 else
1fb49ce7
ZW
7458 cfactor = 1;
7459 automaton->min_issue_delay_table_compression_factor = cfactor;
7460
7461 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
7462 compressed_min_issue_delay_vect
7463 = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len);
7464
7465 for (i = 0; i < compressed_min_issue_delay_len; i++)
7466 VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
7467
7468 for (i = 0; i < min_issue_delay_len; i++)
7469 {
7470 size_t ci = i / cfactor;
7471 vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, i);
7472 vect_el_t cx = VEC_index (vect_el_t, compressed_min_issue_delay_vect, ci);
7473
7474 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
7475 VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx);
7476 }
7477 output_vect (compressed_min_issue_delay_vect);
fae15c93 7478 fprintf (output_file, "};\n\n");
1fb49ce7
ZW
7479 VEC_free (state_t,heap, output_states_vect);
7480 VEC_free (vect_el_t,heap, min_issue_delay_vect);
7481 VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect);
fae15c93
VM
7482}
7483
fae15c93
VM
7484/* Form and output vector representing the locked states of
7485 AUTOMATON. */
7486static void
3d7aafde 7487output_dead_lock_vect (automaton_t automaton)
fae15c93 7488{
1fb49ce7 7489 size_t i;
fae15c93 7490 arc_t arc;
1fb49ce7 7491 vla_hwint_t dead_lock_vect = 0;
fae15c93
VM
7492
7493 /* Create vect of pointers to states ordered by num of
7494 transitions from the state (state with the maximum num is the
7495 first). */
5f2f0edd 7496 automaton->locked_states = 0;
1fb49ce7 7497 output_states_vect = 0;
fae15c93 7498 pass_states (automaton, add_states_vect_el);
1fb49ce7
ZW
7499
7500 VEC_safe_grow (vect_el_t,heap, dead_lock_vect,
7501 VEC_length (state_t, output_states_vect));
7502 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
fae15c93 7503 {
1fb49ce7
ZW
7504 state_t s = VEC_index (state_t, output_states_vect, i);
7505 arc = first_out_arc (s);
b2d59f6f 7506 gcc_assert (arc);
5f2f0edd
ZW
7507 if (next_out_arc (arc) == NULL
7508 && (arc->insn->insn_reserv_decl
7509 == DECL_INSN_RESERV (advance_cycle_insn_decl)))
7510 {
7511 VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 1);
7512 automaton->locked_states++;
7513 }
7514 else
7515 VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 0);
fae15c93 7516 }
5f2f0edd
ZW
7517 if (automaton->locked_states == 0)
7518 return;
7519
fae15c93
VM
7520 fprintf (output_file, "/* Vector for locked state flags. */\n");
7521 fprintf (output_file, "static const ");
7522 output_range_type (output_file, 0, 1);
7523 fprintf (output_file, " ");
7524 output_dead_lock_vect_name (output_file, automaton);
7525 fprintf (output_file, "[] = {\n");
1fb49ce7 7526 output_vect (dead_lock_vect);
fae15c93 7527 fprintf (output_file, "};\n\n");
1fb49ce7
ZW
7528 VEC_free (state_t,heap, output_states_vect);
7529 VEC_free (vect_el_t,heap, dead_lock_vect);
fae15c93
VM
7530}
7531
7532/* Form and output vector representing reserved units of the states of
7533 AUTOMATON. */
7534static void
3d7aafde 7535output_reserved_units_table (automaton_t automaton)
fae15c93 7536{
1fb49ce7
ZW
7537 vla_hwint_t reserved_units_table = 0;
7538 int state_byte_size;
7539 int reserved_units_size;
7540 size_t n;
fae15c93
VM
7541 int i;
7542
63e2552f
ZW
7543 if (description->query_units_num == 0)
7544 return;
7545
fae15c93 7546 /* Create vect of pointers to states. */
1fb49ce7 7547 output_states_vect = 0;
fae15c93
VM
7548 pass_states (automaton, add_states_vect_el);
7549 /* Create vector. */
fae15c93 7550 state_byte_size = (description->query_units_num + 7) / 8;
1fb49ce7
ZW
7551 reserved_units_size = (VEC_length (state_t, output_states_vect)
7552 * state_byte_size);
7553
7554 reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size);
7555
7556 for (i = 0; i < reserved_units_size; i++)
7557 VEC_quick_push (vect_el_t, reserved_units_table, 0);
7558 for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
fae15c93 7559 {
1fb49ce7 7560 state_t s = VEC_index (state_t, output_states_vect, n);
fae15c93 7561 for (i = 0; i < description->units_num; i++)
30028c85 7562 if (units_array [i]->query_p
1fb49ce7
ZW
7563 && first_cycle_unit_presence (s, i))
7564 {
7565 int ri = (s->order_state_num * state_byte_size
7566 + units_array [i]->query_num / 8);
7567 vect_el_t x = VEC_index (vect_el_t, reserved_units_table, ri);
7568
7569 x += 1 << (units_array [i]->query_num % 8);
7570 VEC_replace (vect_el_t, reserved_units_table, ri, x);
7571 }
fae15c93 7572 }
8c94f366 7573 fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
fae15c93
VM
7574 fprintf (output_file, "/* Vector for reserved units of states. */\n");
7575 fprintf (output_file, "static const ");
7576 output_range_type (output_file, 0, 255);
7577 fprintf (output_file, " ");
7578 output_reserved_units_table_name (output_file, automaton);
7579 fprintf (output_file, "[] = {\n");
1fb49ce7 7580 output_vect (reserved_units_table);
63e2552f 7581 fprintf (output_file, "};\n#endif /* #if %s */\n\n",
8c94f366 7582 CPU_UNITS_QUERY_MACRO_NAME);
1fb49ce7
ZW
7583
7584 VEC_free (state_t,heap, output_states_vect);
7585 VEC_free (vect_el_t,heap, reserved_units_table);
fae15c93
VM
7586}
7587
7588/* The function outputs all tables representing DFA(s) used for fast
7589 pipeline hazards recognition. */
7590static void
3d7aafde 7591output_tables (void)
fae15c93
VM
7592{
7593 automaton_t automaton;
7594
fae15c93
VM
7595 initiate_min_issue_delay_pass_states ();
7596 for (automaton = description->first_automaton;
7597 automaton != NULL;
7598 automaton = automaton->next_automaton)
7599 {
7600 output_translate_vect (automaton);
7601 output_trans_table (automaton);
fae15c93
VM
7602 output_min_issue_delay_table (automaton);
7603 output_dead_lock_vect (automaton);
30028c85 7604 output_reserved_units_table (automaton);
fae15c93
VM
7605 }
7606 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
4005971c 7607 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
fae15c93
VM
7608}
7609
7610/* The function outputs definition and value of PHR interface variable
99ed68ea
VM
7611 `max_insn_queue_index'. Its value is not less than maximal queue
7612 length needed for the insn scheduler. */
fae15c93 7613static void
3d7aafde 7614output_max_insn_queue_index_def (void)
fae15c93 7615{
99ed68ea
VM
7616 int i, max, latency;
7617 decl_t decl;
fae15c93 7618
99ed68ea
VM
7619 max = description->max_insn_reserv_cycles;
7620 for (i = 0; i < description->decls_num; i++)
7621 {
7622 decl = description->decls [i];
7623 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
7624 {
7625 latency = DECL_INSN_RESERV (decl)->default_latency;
7626 if (latency > max)
7627 max = latency;
7628 }
7629 else if (decl->mode == dm_bypass)
7630 {
7631 latency = DECL_BYPASS (decl)->latency;
7632 if (latency > max)
7633 max = latency;
7634 }
7635 }
7636 for (i = 0; (1 << i) <= max; i++)
fae15c93 7637 ;
b2d59f6f 7638 gcc_assert (i >= 0);
5f2f0edd
ZW
7639 fprintf (output_file, "\nconst int max_insn_queue_index = %d;\n\n",
7640 (1 << i) - 1);
fae15c93
VM
7641}
7642
fbe5a4a6 7643/* The function outputs switch cases for insn reservations using
fae15c93
VM
7644 function *output_automata_list_code. */
7645static void
3d7aafde
AJ
7646output_insn_code_cases (void (*output_automata_list_code)
7647 (automata_list_el_t))
fae15c93 7648{
4005971c 7649 decl_t decl, decl2;
fae15c93
VM
7650 int i, j;
7651
7652 for (i = 0; i < description->decls_num; i++)
7653 {
7654 decl = description->decls [i];
7655 if (decl->mode == dm_insn_reserv)
4005971c 7656 DECL_INSN_RESERV (decl)->processed_p = FALSE;
fae15c93
VM
7657 }
7658 for (i = 0; i < description->decls_num; i++)
7659 {
7660 decl = description->decls [i];
4005971c
VM
7661 if (decl->mode == dm_insn_reserv
7662 && !DECL_INSN_RESERV (decl)->processed_p)
fae15c93
VM
7663 {
7664 for (j = i; j < description->decls_num; j++)
7665 {
4005971c
VM
7666 decl2 = description->decls [j];
7667 if (decl2->mode == dm_insn_reserv
7668 && (DECL_INSN_RESERV (decl2)->important_automata_list
7669 == DECL_INSN_RESERV (decl)->important_automata_list))
fae15c93 7670 {
4005971c 7671 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
fae15c93 7672 fprintf (output_file, " case %d: /* %s */\n",
4005971c
VM
7673 DECL_INSN_RESERV (decl2)->insn_num,
7674 DECL_INSN_RESERV (decl2)->name);
fae15c93
VM
7675 }
7676 }
7677 (*output_automata_list_code)
4005971c 7678 (DECL_INSN_RESERV (decl)->important_automata_list);
fae15c93
VM
7679 }
7680 }
7681}
7682
7683
7684/* The function outputs a code for evaluation of a minimal delay of
7685 issue of insns which have reservations in given AUTOMATA_LIST. */
7686static void
3d7aafde 7687output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
fae15c93
VM
7688{
7689 automata_list_el_t el;
7690 automaton_t automaton;
7691
7692 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7693 {
7694 automaton = el->automaton;
7695 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7696 output_min_issue_delay_vect_name (output_file, automaton);
7697 fprintf (output_file,
7698 (automaton->min_issue_delay_table_compression_factor != 1
7699 ? " [(" : " ["));
7700 output_translate_vect_name (output_file, automaton);
7701 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7702 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7703 output_chip_member_name (output_file, automaton);
7704 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7705 if (automaton->min_issue_delay_table_compression_factor == 1)
7706 fprintf (output_file, "];\n");
7707 else
7708 {
7709 fprintf (output_file, ") / %d];\n",
7710 automaton->min_issue_delay_table_compression_factor);
7711 fprintf (output_file, " %s = (%s >> (8 - (",
7712 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7713 output_translate_vect_name (output_file, automaton);
7714 fprintf
7715 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
7716 INTERNAL_INSN_CODE_NAME,
7717 automaton->min_issue_delay_table_compression_factor,
7718 8 / automaton->min_issue_delay_table_compression_factor,
7719 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7720 - 1);
7721 }
7722 if (el == automata_list)
7723 fprintf (output_file, " %s = %s;\n",
7724 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7725 else
7726 {
7727 fprintf (output_file, " if (%s > %s)\n",
7728 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7729 fprintf (output_file, " %s = %s;\n",
7730 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7731 }
7732 }
7733 fprintf (output_file, " break;\n\n");
7734}
7735
7736/* Output function `internal_min_issue_delay'. */
7737static void
3d7aafde 7738output_internal_min_issue_delay_func (void)
fae15c93 7739{
fae15c93 7740 fprintf (output_file,
6906ba40 7741 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
fae15c93 7742 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
6906ba40 7743 CHIP_NAME, CHIP_PARAMETER_NAME);
2bf087c0 7744 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
fae15c93
VM
7745 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7746 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7747 output_insn_code_cases (output_automata_list_min_issue_delay_code);
7748 fprintf (output_file,
7749 "\n default:\n %s = -1;\n break;\n }\n",
7750 RESULT_VARIABLE_NAME);
7751 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
7752 fprintf (output_file, "}\n\n");
7753}
7754
7755/* The function outputs a code changing state after issue of insns
7756 which have reservations in given AUTOMATA_LIST. */
7757static void
3d7aafde 7758output_automata_list_transition_code (automata_list_el_t automata_list)
fae15c93
VM
7759{
7760 automata_list_el_t el, next_el;
7761
7762 fprintf (output_file, " {\n");
7763 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7764 for (el = automata_list;; el = next_el)
7765 {
7766 next_el = el->next_automata_list_el;
7767 if (next_el == NULL)
7768 break;
7769 fprintf (output_file, " ");
7770 output_state_member_type (output_file, el->automaton);
7771 fprintf (output_file, " ");
7772 output_temp_chip_member_name (output_file, el->automaton);
7773 fprintf (output_file, ";\n");
7774 }
7775 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7776 if (comb_vect_p (el->automaton->trans_table))
7777 {
7778 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7779 output_trans_base_vect_name (output_file, el->automaton);
7780 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7781 output_chip_member_name (output_file, el->automaton);
7782 fprintf (output_file, "] + ");
7783 output_translate_vect_name (output_file, el->automaton);
7784 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7785 fprintf (output_file, " if (");
7786 output_trans_check_vect_name (output_file, el->automaton);
7787 fprintf (output_file, " [%s] != %s->",
7788 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7789 output_chip_member_name (output_file, el->automaton);
7790 fprintf (output_file, ")\n");
7791 fprintf (output_file, " return %s (%s, %s);\n",
7792 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7793 CHIP_PARAMETER_NAME);
7794 fprintf (output_file, " else\n");
7795 fprintf (output_file, " ");
7796 if (el->next_automata_list_el != NULL)
7797 output_temp_chip_member_name (output_file, el->automaton);
7798 else
7799 {
7800 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7801 output_chip_member_name (output_file, el->automaton);
7802 }
7803 fprintf (output_file, " = ");
7804 output_trans_comb_vect_name (output_file, el->automaton);
7805 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7806 }
7807 else
7808 {
7809 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7810 output_trans_full_vect_name (output_file, el->automaton);
7811 fprintf (output_file, " [");
7812 output_translate_vect_name (output_file, el->automaton);
7813 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7814 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7815 output_chip_member_name (output_file, el->automaton);
7816 fprintf (output_file, " * %d];\n",
7817 el->automaton->insn_equiv_classes_num);
7818 fprintf (output_file, " if (%s >= %d)\n",
7819 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7820 fprintf (output_file, " return %s (%s, %s);\n",
7821 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7822 CHIP_PARAMETER_NAME);
7823 fprintf (output_file, " else\n ");
7824 if (el->next_automata_list_el != NULL)
7825 output_temp_chip_member_name (output_file, el->automaton);
7826 else
7827 {
7828 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7829 output_chip_member_name (output_file, el->automaton);
7830 }
7831 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7832 }
7833 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7834 for (el = automata_list;; el = next_el)
7835 {
7836 next_el = el->next_automata_list_el;
7837 if (next_el == NULL)
7838 break;
7839 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
7840 output_chip_member_name (output_file, el->automaton);
7841 fprintf (output_file, " = ");
7842 output_temp_chip_member_name (output_file, el->automaton);
7843 fprintf (output_file, ";\n");
7844 }
7845 fprintf (output_file, " return -1;\n");
7846 fprintf (output_file, " }\n");
7847}
7848
7849/* Output function `internal_state_transition'. */
7850static void
3d7aafde 7851output_internal_trans_func (void)
fae15c93 7852{
fae15c93 7853 fprintf (output_file,
6906ba40 7854 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
fae15c93 7855 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
fae15c93 7856 CHIP_NAME, CHIP_PARAMETER_NAME);
e2ff6cee 7857 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
fae15c93
VM
7858 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
7859 output_insn_code_cases (output_automata_list_transition_code);
7860 fprintf (output_file, "\n default:\n return -1;\n }\n");
7861 fprintf (output_file, "}\n\n");
7862}
7863
7864/* Output code
7865
7866 if (insn != 0)
7867 {
7868 insn_code = dfa_insn_code (insn);
7869 if (insn_code > DFA__ADVANCE_CYCLE)
7870 return code;
7871 }
7872 else
7873 insn_code = DFA__ADVANCE_CYCLE;
7874
7875 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7876 code denotes CODE. */
7877static void
3d7aafde
AJ
7878output_internal_insn_code_evaluation (const char *insn_name,
7879 const char *insn_code_name,
7880 int code)
fae15c93
VM
7881{
7882 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
7883 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
7884 DFA_INSN_CODE_FUNC_NAME, insn_name);
7885 fprintf (output_file, " if (%s > %s)\n return %d;\n",
7886 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
7887 fprintf (output_file, " }\n else\n %s = %s;\n\n",
7888 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
7889}
7890
7891
a543eb5e
ZW
7892/* This function outputs `dfa_insn_code' and its helper function
7893 `dfa_insn_code_enlarge'. */
fae15c93 7894static void
3d7aafde 7895output_dfa_insn_code_func (void)
fae15c93 7896{
a543eb5e
ZW
7897 /* Emacs c-mode gets really confused if there's a { or } in column 0
7898 inside a string, so don't do that. */
7899 fprintf (output_file, "\
a543eb5e 7900static void\n\
6906ba40
KG
7901dfa_insn_code_enlarge (int uid)\n\
7902{\n\
a543eb5e
ZW
7903 int i = %s;\n\
7904 %s = 2 * uid;\n\
7905 %s = xrealloc (%s,\n\
7906 %s * sizeof(int));\n\
7907 for (; i < %s; i++)\n\
7908 %s[i] = -1;\n}\n\n",
3d7aafde
AJ
7909 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7910 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7911 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
7912 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7913 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
7914 DFA_INSN_CODES_VARIABLE_NAME);
a543eb5e 7915 fprintf (output_file, "\
6906ba40
KG
7916static inline int\n%s (rtx %s)\n\
7917{\n\
7918 int uid = INSN_UID (%s);\n\
7919 int %s;\n\n",
7920 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
7921 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
a543eb5e
ZW
7922
7923 fprintf (output_file,
7924 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
7925 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
7926 fprintf (output_file, " %s = %s[uid];\n",
7927 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
7928 fprintf (output_file, "\
7929 if (%s < 0)\n\
7930 {\n\
7931 %s = %s (%s);\n\
7932 %s[uid] = %s;\n\
7933 }\n",
7934 INTERNAL_INSN_CODE_NAME,
7935 INTERNAL_INSN_CODE_NAME,
7936 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
7937 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
7938 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
fae15c93
VM
7939}
7940
7941/* The function outputs PHR interface function `state_transition'. */
7942static void
3d7aafde 7943output_trans_func (void)
fae15c93 7944{
6906ba40
KG
7945 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
7946 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
7947 INSN_PARAMETER_NAME);
fae15c93
VM
7948 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7949 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
7950 INTERNAL_INSN_CODE_NAME, -1);
7951 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
7952 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
7953}
7954
fae15c93
VM
7955/* Output function `min_issue_delay'. */
7956static void
3d7aafde 7957output_min_issue_delay_func (void)
fae15c93 7958{
6906ba40
KG
7959 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
7960 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
7961 INSN_PARAMETER_NAME);
fae15c93
VM
7962 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
7963 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
7964 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
7965 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
7966 fprintf (output_file, " if (%s > %s)\n return 0;\n",
7967 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
7968 fprintf (output_file, " }\n else\n %s = %s;\n",
7969 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
7970 fprintf (output_file, "\n return %s (%s, %s);\n",
3d7aafde 7971 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
fae15c93
VM
7972 STATE_NAME);
7973 fprintf (output_file, "}\n\n");
7974}
7975
7976/* Output function `internal_dead_lock'. */
7977static void
3d7aafde 7978output_internal_dead_lock_func (void)
fae15c93
VM
7979{
7980 automaton_t automaton;
7981
5f2f0edd 7982 fprintf (output_file, "static int\n%s (struct %s *ARG_UNUSED (%s))\n",
6906ba40 7983 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
fae15c93
VM
7984 fprintf (output_file, "{\n");
7985 for (automaton = description->first_automaton;
7986 automaton != NULL;
7987 automaton = automaton->next_automaton)
5f2f0edd
ZW
7988 if (automaton->locked_states)
7989 {
7990 fprintf (output_file, " if (");
7991 output_dead_lock_vect_name (output_file, automaton);
7992 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7993 output_chip_member_name (output_file, automaton);
7994 fprintf (output_file, "])\n return 1/* TRUE */;\n");
7995 }
fae15c93
VM
7996 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
7997}
7998
7999/* The function outputs PHR interface function `state_dead_lock_p'. */
8000static void
3d7aafde 8001output_dead_lock_func (void)
fae15c93 8002{
6906ba40
KG
8003 fprintf (output_file, "int\n%s (%s %s)\n",
8004 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
fae15c93
VM
8005 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8006 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8007}
8008
8009/* Output function `internal_reset'. */
8010static void
3d7aafde 8011output_internal_reset_func (void)
fae15c93 8012{
ec049fdb 8013 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
6906ba40 8014 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
fae15c93
VM
8015 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8016 CHIP_PARAMETER_NAME, CHIP_NAME);
8017}
8018
8019/* The function outputs PHR interface function `state_size'. */
8020static void
3d7aafde 8021output_size_func (void)
fae15c93 8022{
6906ba40 8023 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
fae15c93
VM
8024 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8025}
8026
8027/* The function outputs PHR interface function `state_reset'. */
8028static void
3d7aafde 8029output_reset_func (void)
fae15c93 8030{
6906ba40
KG
8031 fprintf (output_file, "void\n%s (%s %s)\n",
8032 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
fae15c93
VM
8033 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8034 STATE_NAME);
8035}
8036
8037/* Output function `min_insn_conflict_delay'. */
8038static void
3d7aafde 8039output_min_insn_conflict_delay_func (void)
fae15c93
VM
8040{
8041 fprintf (output_file,
6906ba40
KG
8042 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8043 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8044 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
b2d59f6f 8045 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
fae15c93
VM
8046 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8047 INTERNAL_INSN2_CODE_NAME);
8048 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8049 INTERNAL_INSN_CODE_NAME, 0);
8050 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8051 INTERNAL_INSN2_CODE_NAME, 0);
8052 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8053 CHIP_NAME, STATE_NAME, CHIP_NAME);
8054 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
b2d59f6f 8055 fprintf (output_file, " transition = %s (%s, &%s);\n",
fae15c93 8056 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
b2d59f6f 8057 fprintf (output_file, " gcc_assert (transition <= 0);\n");
fae15c93
VM
8058 fprintf (output_file, " return %s (%s, &%s);\n",
8059 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8060 CHIP_NAME);
8061 fprintf (output_file, "}\n\n");
8062}
8063
8064/* Output function `internal_insn_latency'. */
8065static void
3d7aafde 8066output_internal_insn_latency_func (void)
fae15c93
VM
8067{
8068 decl_t decl;
8069 struct bypass_decl *bypass;
a543eb5e
ZW
8070 int i, j, col;
8071 const char *tabletype = "unsigned char";
fae15c93 8072
a543eb5e
ZW
8073 /* Find the smallest integer type that can hold all the default
8074 latency values. */
8075 for (i = 0; i < description->decls_num; i++)
8076 if (description->decls[i]->mode == dm_insn_reserv)
8077 {
8078 decl = description->decls[i];
8079 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
e0a21ab9 8080 && tabletype[0] != 'i') /* Don't shrink it. */
a543eb5e
ZW
8081 tabletype = "unsigned short";
8082 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8083 tabletype = "int";
8084 }
3d7aafde 8085
6906ba40 8086 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
fae15c93
VM
8087 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8088 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8089 INSN2_PARAMETER_NAME);
6906ba40 8090 fprintf (output_file, "{\n");
a543eb5e 8091
c24b8026
ZW
8092 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8093 {
8094 fputs (" return 0;\n}\n\n", output_file);
8095 return;
8096 }
8097
a543eb5e
ZW
8098 fprintf (output_file, " static const %s default_latencies[] =\n {",
8099 tabletype);
8100
8101 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8102 if (description->decls[i]->mode == dm_insn_reserv
8103 && description->decls[i] != advance_cycle_insn_decl)
8104 {
8105 if ((col = (col+1) % 8) == 0)
8106 fputs ("\n ", output_file);
8107 decl = description->decls[i];
b2d59f6f 8108 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
a543eb5e
ZW
8109 fprintf (output_file, "% 4d,",
8110 DECL_INSN_RESERV (decl)->default_latency);
8111 }
b2d59f6f 8112 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
a543eb5e
ZW
8113 fputs ("\n };\n", output_file);
8114
8115 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8116 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8117 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8118
8119 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
fae15c93 8120 for (i = 0; i < description->decls_num; i++)
a543eb5e
ZW
8121 if (description->decls[i]->mode == dm_insn_reserv
8122 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8123 {
8124 decl = description->decls [i];
8125 fprintf (output_file,
8126 " case %d:\n switch (%s)\n {\n",
8127 DECL_INSN_RESERV (decl)->insn_num,
8128 INTERNAL_INSN2_CODE_NAME);
8129 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8130 bypass != NULL;
8131 bypass = bypass->next)
8132 {
b2d59f6f
NS
8133 gcc_assert (bypass->in_insn_reserv->insn_num
8134 != (DECL_INSN_RESERV
8135 (advance_cycle_insn_decl)->insn_num));
a543eb5e
ZW
8136 fprintf (output_file, " case %d:\n",
8137 bypass->in_insn_reserv->insn_num);
8138 if (bypass->bypass_guard_name == NULL)
8139 fprintf (output_file, " return %d;\n",
8140 bypass->latency);
8141 else
8142 {
8143 fprintf (output_file,
4f9365e2 8144 " if (%s (%s, %s))\n",
a543eb5e
ZW
8145 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8146 INSN2_PARAMETER_NAME);
8147 fprintf (output_file,
8148 " return %d;\n break;\n",
8149 bypass->latency);
8150 }
8151 }
490c57bb 8152 fputs (" }\n break;\n", output_file);
a543eb5e
ZW
8153 }
8154
8155 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8156 INTERNAL_INSN_CODE_NAME);
fae15c93
VM
8157}
8158
8159/* The function outputs PHR interface function `insn_latency'. */
8160static void
3d7aafde 8161output_insn_latency_func (void)
fae15c93 8162{
6906ba40
KG
8163 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8164 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fae15c93
VM
8165 fprintf (output_file, "{\n int %s, %s;\n",
8166 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8167 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8168 INTERNAL_INSN_CODE_NAME, 0);
8169 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8170 INTERNAL_INSN2_CODE_NAME, 0);
8171 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8172 INTERNAL_INSN_LATENCY_FUNC_NAME,
8173 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8174 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8175}
8176
8177/* The function outputs PHR interface function `print_reservation'. */
8178static void
3d7aafde 8179output_print_reservation_func (void)
fae15c93
VM
8180{
8181 decl_t decl;
a543eb5e 8182 int i, j;
fae15c93 8183
c24b8026 8184 fprintf (output_file,
6906ba40 8185 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
fae15c93 8186 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
fae15c93 8187 INSN_PARAMETER_NAME);
a543eb5e 8188
c24b8026
ZW
8189 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8190 {
8191 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8192 NOTHING_NAME, FILE_PARAMETER_NAME);
8193 return;
8194 }
8195
8196
a543eb5e
ZW
8197 fputs (" static const char *const reservation_names[] =\n {",
8198 output_file);
8199
8200 for (i = 0, j = 0; i < description->decls_num; i++)
fae15c93
VM
8201 {
8202 decl = description->decls [i];
8203 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8204 {
b2d59f6f
NS
8205 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8206 j++;
8207
a543eb5e
ZW
8208 fprintf (output_file, "\n \"%s\",",
8209 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8210 finish_regexp_representation ();
8211 }
fae15c93 8212 }
b2d59f6f 8213 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
3d7aafde 8214
a543eb5e
ZW
8215 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8216 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8217
8218 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8219 INSN_PARAMETER_NAME,
8220 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8221 fprintf (output_file, " else\n\
8222 {\n\
8223 %s = %s (%s);\n\
8224 if (%s > %s)\n\
8225 %s = %s;\n\
8226 }\n",
8227 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8228 INSN_PARAMETER_NAME,
8229 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8230 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8231
8232 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8233 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
fae15c93
VM
8234}
8235
8236/* The following function is used to sort unit declaration by their
8237 names. */
8238static int
3d7aafde 8239units_cmp (const void *unit1, const void *unit2)
fae15c93 8240{
deb09eff
VM
8241 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8242 const unit_decl_t u2 = *(unit_decl_t *) unit2;
fae15c93
VM
8243
8244 return strcmp (u1->name, u2->name);
8245}
8246
8247/* The following macro value is name of struct containing unit name
8248 and unit code. */
8249#define NAME_CODE_STRUCT_NAME "name_code"
8250
8251/* The following macro value is name of table of struct name_code. */
8252#define NAME_CODE_TABLE_NAME "name_code_table"
8253
8254/* The following macro values are member names for struct name_code. */
8255#define NAME_MEMBER_NAME "name"
8256#define CODE_MEMBER_NAME "code"
8257
8258/* The following macro values are local variable names for function
8259 `get_cpu_unit_code'. */
8260#define CMP_VARIABLE_NAME "cmp"
8261#define LOW_VARIABLE_NAME "l"
8262#define MIDDLE_VARIABLE_NAME "m"
8263#define HIGH_VARIABLE_NAME "h"
8264
8265/* The following function outputs function to obtain internal cpu unit
8266 code by the cpu unit name. */
8267static void
3d7aafde 8268output_get_cpu_unit_code_func (void)
fae15c93
VM
8269{
8270 int i;
deb09eff 8271 unit_decl_t *units;
3d7aafde 8272
9fd64c63
JM
8273 fprintf (output_file, "int\n%s (const char *%s)\n",
8274 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
fae15c93
VM
8275 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8276 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8277 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8278 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8279 fprintf (output_file, " static struct %s %s [] =\n {\n",
8280 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
703ad42b 8281 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
deb09eff
VM
8282 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8283 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
fae15c93
VM
8284 for (i = 0; i < description->units_num; i++)
8285 if (units [i]->query_p)
8286 fprintf (output_file, " {\"%s\", %d},\n",
8287 units[i]->name, units[i]->query_num);
8288 fprintf (output_file, " };\n\n");
8289 fprintf (output_file, " /* The following is binary search: */\n");
8290 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8291 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8292 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8293 fprintf (output_file, " while (%s <= %s)\n {\n",
8294 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8295 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8296 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8297 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8298 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8299 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8300 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8301 fprintf (output_file, " %s = %s - 1;\n",
8302 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8303 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8304 fprintf (output_file, " %s = %s + 1;\n",
8305 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8306 fprintf (output_file, " else\n");
8307 fprintf (output_file, " return %s [%s].%s;\n }\n",
8308 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8309 fprintf (output_file, " return -1;\n}\n\n");
8310 free (units);
8311}
8312
8313/* The following function outputs function to check reservation of cpu
8314 unit (its internal code will be passed as the function argument) in
8315 given cpu state. */
8316static void
3d7aafde 8317output_cpu_unit_reservation_p (void)
fae15c93
VM
8318{
8319 automaton_t automaton;
8320
9fd64c63
JM
8321 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
8322 CPU_UNIT_RESERVATION_P_FUNC_NAME,
8323 STATE_TYPE_NAME, STATE_NAME,
fae15c93 8324 CPU_CODE_PARAMETER_NAME);
b2d59f6f 8325 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
fae15c93
VM
8326 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8327 description->query_units_num);
63e2552f
ZW
8328 if (description->query_units_num > 0)
8329 for (automaton = description->first_automaton;
8330 automaton != NULL;
8331 automaton = automaton->next_automaton)
8332 {
8333 fprintf (output_file, " if ((");
8334 output_reserved_units_table_name (output_file, automaton);
8335 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8336 output_chip_member_name (output_file, automaton);
8337 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8338 (description->query_units_num + 7) / 8,
8339 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8340 fprintf (output_file, " return 1;\n");
8341 }
fae15c93
VM
8342 fprintf (output_file, " return 0;\n}\n\n");
8343}
8344
496d7bb0
MK
8345/* The function outputs PHR interface functions `dfa_clean_insn_cache'
8346 and 'dfa_clear_single_insn_cache'. */
fae15c93 8347static void
3d7aafde 8348output_dfa_clean_insn_cache_func (void)
fae15c93
VM
8349{
8350 fprintf (output_file,
6906ba40 8351 "void\n%s (void)\n{\n int %s;\n\n",
30028c85 8352 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
fae15c93
VM
8353 fprintf (output_file,
8354 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8355 I_VARIABLE_NAME, I_VARIABLE_NAME,
8356 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8357 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
496d7bb0
MK
8358
8359 fprintf (output_file,
8360 "void\n%s (rtx %s)\n{\n int %s;\n\n",
8361 DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
8362 I_VARIABLE_NAME);
8363 fprintf (output_file,
8364 " %s = INSN_UID (%s);\n if (%s < %s)\n %s [%s] = -1;\n}\n\n",
8365 I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME,
8366 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8367 I_VARIABLE_NAME);
fae15c93
VM
8368}
8369
30028c85
VM
8370/* The function outputs PHR interface function `dfa_start'. */
8371static void
3d7aafde 8372output_dfa_start_func (void)
30028c85
VM
8373{
8374 fprintf (output_file,
6906ba40 8375 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
30028c85 8376 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
703ad42b 8377 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
30028c85
VM
8378 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8379 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8380}
8381
fae15c93
VM
8382/* The function outputs PHR interface function `dfa_finish'. */
8383static void
3d7aafde 8384output_dfa_finish_func (void)
fae15c93 8385{
6906ba40 8386 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
fae15c93
VM
8387 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8388}
8389
8390\f
8391
8392/* The page contains code for output description file (readable
8393 representation of original description and generated DFA(s). */
8394
8395/* The function outputs string representation of IR reservation. */
8396static void
3d7aafde 8397output_regexp (regexp_t regexp)
fae15c93
VM
8398{
8399 fprintf (output_description_file, "%s", regexp_representation (regexp));
8400 finish_regexp_representation ();
8401}
8402
8403/* Output names of units in LIST separated by comma. */
8404static void
3d7aafde 8405output_unit_set_el_list (unit_set_el_t list)
fae15c93
VM
8406{
8407 unit_set_el_t el;
8408
8409 for (el = list; el != NULL; el = el->next_unit_set_el)
8410 {
8411 if (el != list)
30028c85 8412 fprintf (output_description_file, ", ");
fae15c93
VM
8413 fprintf (output_description_file, "%s", el->unit_decl->name);
8414 }
8415}
8416
30028c85
VM
8417/* Output patterns in LIST separated by comma. */
8418static void
3d7aafde 8419output_pattern_set_el_list (pattern_set_el_t list)
30028c85
VM
8420{
8421 pattern_set_el_t el;
8422 int i;
8423
8424 for (el = list; el != NULL; el = el->next_pattern_set_el)
8425 {
8426 if (el != list)
8427 fprintf (output_description_file, ", ");
8428 for (i = 0; i < el->units_num; i++)
8429 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
8430 el->unit_decls [i]->name);
8431 }
8432}
8433
fae15c93
VM
8434/* The function outputs string representation of IR define_reservation
8435 and define_insn_reservation. */
8436static void
3d7aafde 8437output_description (void)
fae15c93
VM
8438{
8439 decl_t decl;
8440 int i;
8441
8442 for (i = 0; i < description->decls_num; i++)
8443 {
8444 decl = description->decls [i];
8445 if (decl->mode == dm_unit)
8446 {
4005971c 8447 if (DECL_UNIT (decl)->excl_list != NULL)
fae15c93
VM
8448 {
8449 fprintf (output_description_file, "unit %s exlusion_set: ",
4005971c
VM
8450 DECL_UNIT (decl)->name);
8451 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
fae15c93
VM
8452 fprintf (output_description_file, "\n");
8453 }
4005971c 8454 if (DECL_UNIT (decl)->presence_list != NULL)
fae15c93
VM
8455 {
8456 fprintf (output_description_file, "unit %s presence_set: ",
4005971c 8457 DECL_UNIT (decl)->name);
30028c85 8458 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
fae15c93
VM
8459 fprintf (output_description_file, "\n");
8460 }
30028c85
VM
8461 if (DECL_UNIT (decl)->final_presence_list != NULL)
8462 {
8463 fprintf (output_description_file, "unit %s final_presence_set: ",
8464 DECL_UNIT (decl)->name);
8465 output_pattern_set_el_list
8466 (DECL_UNIT (decl)->final_presence_list);
3d7aafde
AJ
8467 fprintf (output_description_file, "\n");
8468 }
4005971c 8469 if (DECL_UNIT (decl)->absence_list != NULL)
fae15c93
VM
8470 {
8471 fprintf (output_description_file, "unit %s absence_set: ",
4005971c 8472 DECL_UNIT (decl)->name);
30028c85 8473 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
fae15c93
VM
8474 fprintf (output_description_file, "\n");
8475 }
30028c85
VM
8476 if (DECL_UNIT (decl)->final_absence_list != NULL)
8477 {
8478 fprintf (output_description_file, "unit %s final_absence_set: ",
8479 DECL_UNIT (decl)->name);
8480 output_pattern_set_el_list
8481 (DECL_UNIT (decl)->final_absence_list);
3d7aafde
AJ
8482 fprintf (output_description_file, "\n");
8483 }
fae15c93
VM
8484 }
8485 }
8486 fprintf (output_description_file, "\n");
8487 for (i = 0; i < description->decls_num; i++)
8488 {
8489 decl = description->decls [i];
8490 if (decl->mode == dm_reserv)
8491 {
c1625e69
KG
8492 fprintf (output_description_file, "reservation %s: ",
8493 DECL_RESERV (decl)->name);
4005971c 8494 output_regexp (DECL_RESERV (decl)->regexp);
fae15c93
VM
8495 fprintf (output_description_file, "\n");
8496 }
8497 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8498 {
8499 fprintf (output_description_file, "insn reservation %s ",
4005971c
VM
8500 DECL_INSN_RESERV (decl)->name);
8501 print_rtl (output_description_file,
8502 DECL_INSN_RESERV (decl)->condexp);
fae15c93 8503 fprintf (output_description_file, ": ");
4005971c 8504 output_regexp (DECL_INSN_RESERV (decl)->regexp);
fae15c93
VM
8505 fprintf (output_description_file, "\n");
8506 }
8507 else if (decl->mode == dm_bypass)
8508 fprintf (output_description_file, "bypass %d %s %s\n",
4005971c
VM
8509 DECL_BYPASS (decl)->latency,
8510 DECL_BYPASS (decl)->out_insn_name,
8511 DECL_BYPASS (decl)->in_insn_name);
fae15c93
VM
8512 }
8513 fprintf (output_description_file, "\n\f\n");
8514}
8515
8516/* The function outputs name of AUTOMATON. */
8517static void
3d7aafde 8518output_automaton_name (FILE *f, automaton_t automaton)
fae15c93
VM
8519{
8520 if (automaton->corresponding_automaton_decl == NULL)
8521 fprintf (f, "#%d", automaton->automaton_order_num);
8522 else
8523 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8524}
8525
8526/* Maximal length of line for pretty printing into description
8527 file. */
8528#define MAX_LINE_LENGTH 70
8529
8530/* The function outputs units name belonging to AUTOMATON. */
8531static void
3d7aafde 8532output_automaton_units (automaton_t automaton)
fae15c93
VM
8533{
8534 decl_t decl;
1fb49ce7 8535 const char *name;
fae15c93
VM
8536 int curr_line_length;
8537 int there_is_an_automaton_unit;
8538 int i;
8539
56ae04af 8540 fprintf (output_description_file, "\n Corresponding units:\n");
fae15c93
VM
8541 fprintf (output_description_file, " ");
8542 curr_line_length = 4;
8543 there_is_an_automaton_unit = 0;
8544 for (i = 0; i < description->decls_num; i++)
8545 {
8546 decl = description->decls [i];
8547 if (decl->mode == dm_unit
4005971c 8548 && (DECL_UNIT (decl)->corresponding_automaton_num
fae15c93
VM
8549 == automaton->automaton_order_num))
8550 {
8551 there_is_an_automaton_unit = 1;
4005971c 8552 name = DECL_UNIT (decl)->name;
fae15c93
VM
8553 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8554 {
8555 curr_line_length = strlen (name) + 4;
8556 fprintf (output_description_file, "\n ");
8557 }
8558 else
8559 {
8560 curr_line_length += strlen (name) + 1;
8561 fprintf (output_description_file, " ");
8562 }
1e29b8d7 8563 fprintf (output_description_file, "%s", name);
fae15c93
VM
8564 }
8565 }
8566 if (!there_is_an_automaton_unit)
8567 fprintf (output_description_file, "<None>");
8568 fprintf (output_description_file, "\n\n");
8569}
8570
8571/* The following variable is used for forming array of all possible cpu unit
8572 reservations described by the current DFA state. */
1fb49ce7 8573static VEC(reserv_sets_t,heap) *state_reservs;
fae15c93
VM
8574
8575/* The function forms `state_reservs' for STATE. */
8576static void
3d7aafde 8577add_state_reservs (state_t state)
fae15c93
VM
8578{
8579 alt_state_t curr_alt_state;
fae15c93
VM
8580
8581 if (state->component_states != NULL)
8582 for (curr_alt_state = state->component_states;
8583 curr_alt_state != NULL;
8584 curr_alt_state = curr_alt_state->next_sorted_alt_state)
8585 add_state_reservs (curr_alt_state->state);
8586 else
1fb49ce7 8587 VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs);
fae15c93
VM
8588}
8589
96e13905 8590/* The function outputs readable representation of all out arcs of
fae15c93
VM
8591 STATE. */
8592static void
3d7aafde 8593output_state_arcs (state_t state)
fae15c93
VM
8594{
8595 arc_t arc;
8596 ainsn_t ainsn;
1fb49ce7 8597 const char *insn_name;
fae15c93
VM
8598 int curr_line_length;
8599
8600 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8601 {
8602 ainsn = arc->insn;
b2d59f6f 8603 gcc_assert (ainsn->first_insn_with_same_reservs);
fae15c93
VM
8604 fprintf (output_description_file, " ");
8605 curr_line_length = 7;
8606 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8607 do
8608 {
8609 insn_name = ainsn->insn_reserv_decl->name;
8610 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8611 {
8612 if (ainsn != arc->insn)
8613 {
8614 fprintf (output_description_file, ",\n ");
8615 curr_line_length = strlen (insn_name) + 6;
8616 }
8617 else
8618 curr_line_length += strlen (insn_name);
8619 }
8620 else
8621 {
8622 curr_line_length += strlen (insn_name);
8623 if (ainsn != arc->insn)
8624 {
8625 curr_line_length += 2;
8626 fprintf (output_description_file, ", ");
8627 }
8628 }
1e29b8d7 8629 fprintf (output_description_file, "%s", insn_name);
fae15c93
VM
8630 ainsn = ainsn->next_same_reservs_insn;
8631 }
8632 while (ainsn != NULL);
8c94f366
ZW
8633 fprintf (output_description_file, " %d \n",
8634 arc->to_state->order_state_num);
fae15c93
VM
8635 }
8636 fprintf (output_description_file, "\n");
8637}
8638
8639/* The following function is used for sorting possible cpu unit
8640 reservation of a DFA state. */
8641static int
3d7aafde 8642state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
fae15c93
VM
8643{
8644 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
8645 *(reserv_sets_t *) reservs_ptr_2);
8646}
8647
8648/* The following function is used for sorting possible cpu unit
8649 reservation of a DFA state. */
8650static void
3d7aafde 8651remove_state_duplicate_reservs (void)
fae15c93 8652{
1fb49ce7 8653 size_t i, j;
fae15c93 8654
1fb49ce7
ZW
8655 for (i = 1, j = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
8656 if (reserv_sets_cmp (VEC_index (reserv_sets_t, state_reservs, j),
8657 VEC_index (reserv_sets_t, state_reservs, i)))
fae15c93 8658 {
1fb49ce7
ZW
8659 j++;
8660 VEC_replace (reserv_sets_t, state_reservs, j,
8661 VEC_index (reserv_sets_t, state_reservs, i));
fae15c93 8662 }
1fb49ce7 8663 VEC_truncate (reserv_sets_t, state_reservs, j + 1);
fae15c93
VM
8664}
8665
8666/* The following function output readable representation of DFA(s)
8667 state used for fast recognition of pipeline hazards. State is
96e13905 8668 described by possible (current and scheduled) cpu unit
fae15c93
VM
8669 reservations. */
8670static void
3d7aafde 8671output_state (state_t state)
fae15c93 8672{
1fb49ce7
ZW
8673 size_t i;
8674
8675 state_reservs = 0;
fae15c93 8676
fae15c93
VM
8677 fprintf (output_description_file, " State #%d", state->order_state_num);
8678 fprintf (output_description_file,
8679 state->new_cycle_p ? " (new cycle)\n" : "\n");
8680 add_state_reservs (state);
1fb49ce7
ZW
8681 qsort (VEC_address (reserv_sets_t, state_reservs),
8682 VEC_length (reserv_sets_t, state_reservs),
fae15c93
VM
8683 sizeof (reserv_sets_t), state_reservs_cmp);
8684 remove_state_duplicate_reservs ();
1fb49ce7 8685 for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++)
fae15c93
VM
8686 {
8687 fprintf (output_description_file, " ");
1fb49ce7
ZW
8688 output_reserv_sets (output_description_file,
8689 VEC_index (reserv_sets_t, state_reservs, i));
fae15c93
VM
8690 fprintf (output_description_file, "\n");
8691 }
8692 fprintf (output_description_file, "\n");
8693 output_state_arcs (state);
1fb49ce7 8694 VEC_free (reserv_sets_t,heap, state_reservs);
fae15c93
VM
8695}
8696
8697/* The following function output readable representation of
8698 DFAs used for fast recognition of pipeline hazards. */
8699static void
3d7aafde 8700output_automaton_descriptions (void)
fae15c93
VM
8701{
8702 automaton_t automaton;
8703
8704 for (automaton = description->first_automaton;
8705 automaton != NULL;
8706 automaton = automaton->next_automaton)
8707 {
8708 fprintf (output_description_file, "\nAutomaton ");
8709 output_automaton_name (output_description_file, automaton);
8710 fprintf (output_description_file, "\n");
8711 output_automaton_units (automaton);
8712 pass_states (automaton, output_state);
8713 }
8714}
8715
8716\f
8717
8718/* The page contains top level function for generation DFA(s) used for
8719 PHR. */
8720
8721/* The function outputs statistics about work of different phases of
8722 DFA generator. */
8723static void
3d7aafde 8724output_statistics (FILE *f)
fae15c93
VM
8725{
8726 automaton_t automaton;
30028c85 8727 int states_num;
fae15c93
VM
8728#ifndef NDEBUG
8729 int transition_comb_vect_els = 0;
8730 int transition_full_vect_els = 0;
fae15c93 8731 int min_issue_delay_vect_els = 0;
5f2f0edd 8732 int locked_states = 0;
fae15c93
VM
8733#endif
8734
8735 for (automaton = description->first_automaton;
8736 automaton != NULL;
8737 automaton = automaton->next_automaton)
8738 {
8739 fprintf (f, "\nAutomaton ");
8740 output_automaton_name (f, automaton);
8741 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
8742 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
8743 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
8744 automaton->DFA_states_num, automaton->DFA_arcs_num);
30028c85 8745 states_num = automaton->DFA_states_num;
fae15c93 8746 if (!no_minimization_flag)
30028c85
VM
8747 {
8748 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
8749 automaton->minimal_DFA_states_num,
8750 automaton->minimal_DFA_arcs_num);
8751 states_num = automaton->minimal_DFA_states_num;
8752 }
fae15c93
VM
8753 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
8754 description->insns_num, automaton->insn_equiv_classes_num);
5f2f0edd 8755 fprintf (f, " %d locked states\n", automaton->locked_states);
fae15c93
VM
8756#ifndef NDEBUG
8757 fprintf
8758 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
1fb49ce7
ZW
8759 (long) VEC_length (vect_el_t, automaton->trans_table->comb_vect),
8760 (long) VEC_length (vect_el_t, automaton->trans_table->full_vect),
fae15c93
VM
8761 (comb_vect_p (automaton->trans_table)
8762 ? "use comb vect" : "use simple vect"));
fae15c93
VM
8763 fprintf
8764 (f, "%5ld min delay table els, compression factor %d\n",
30028c85 8765 (long) states_num * automaton->insn_equiv_classes_num,
fae15c93
VM
8766 automaton->min_issue_delay_table_compression_factor);
8767 transition_comb_vect_els
1fb49ce7 8768 += VEC_length (vect_el_t, automaton->trans_table->comb_vect);
3d7aafde 8769 transition_full_vect_els
1fb49ce7 8770 += VEC_length (vect_el_t, automaton->trans_table->full_vect);
fae15c93 8771 min_issue_delay_vect_els
30028c85 8772 += states_num * automaton->insn_equiv_classes_num;
5f2f0edd
ZW
8773 locked_states
8774 += automaton->locked_states;
fae15c93
VM
8775#endif
8776 }
8777#ifndef NDEBUG
8778 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
8779 allocated_states_num, allocated_arcs_num);
8780 fprintf (f, "%5d all allocated alternative states\n",
8781 allocated_alt_states_num);
8782 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
8783 transition_comb_vect_els, transition_full_vect_els);
fae15c93 8784 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
5f2f0edd 8785 fprintf (f, "%5d all locked states\n", locked_states);
fae15c93
VM
8786#endif
8787}
8788
8789/* The function output times of work of different phases of DFA
8790 generator. */
8791static void
3d7aafde 8792output_time_statistics (FILE *f)
fae15c93
VM
8793{
8794 fprintf (f, "\n transformation: ");
8795 print_active_time (f, transform_time);
8796 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
8797 print_active_time (f, NDFA_time);
8798 if (ndfa_flag)
8799 {
8800 fprintf (f, ", NDFA -> DFA: ");
8801 print_active_time (f, NDFA_to_DFA_time);
8802 }
8803 fprintf (f, "\n DFA minimization: ");
8804 print_active_time (f, minimize_time);
8805 fprintf (f, ", making insn equivalence: ");
8806 print_active_time (f, equiv_time);
8807 fprintf (f, "\n all automaton generation: ");
8808 print_active_time (f, automaton_generation_time);
8809 fprintf (f, ", output: ");
8810 print_active_time (f, output_time);
8811 fprintf (f, "\n");
8812}
8813
96e13905 8814/* The function generates DFA (deterministic finite state automaton)
fae15c93
VM
8815 for fast recognition of pipeline hazards. No errors during
8816 checking must be fixed before this function call. */
8817static void
3d7aafde 8818generate (void)
fae15c93
VM
8819{
8820 automata_num = split_argument;
8821 if (description->units_num < automata_num)
8822 automata_num = description->units_num;
8823 initiate_states ();
8824 initiate_arcs ();
8825 initiate_automata_lists ();
8826 initiate_pass_states ();
8827 initiate_excl_sets ();
30028c85 8828 initiate_presence_absence_pattern_sets ();
fae15c93 8829 automaton_generation_time = create_ticker ();
fae15c93
VM
8830 create_automata ();
8831 ticker_off (&automaton_generation_time);
8832}
8833
8834\f
8835
fae15c93
VM
8836/* This page mainly contains top level functions of pipeline hazards
8837 description translator. */
8838
8839/* The following macro value is suffix of name of description file of
8840 pipeline hazards description translator. */
8841#define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
8842
8843/* The function returns suffix of given file name. The returned
8844 string can not be changed. */
8845static const char *
3d7aafde 8846file_name_suffix (const char *file_name)
fae15c93
VM
8847{
8848 const char *last_period;
8849
8850 for (last_period = NULL; *file_name != '\0'; file_name++)
8851 if (*file_name == '.')
8852 last_period = file_name;
8853 return (last_period == NULL ? file_name : last_period);
8854}
8855
8856/* The function returns base name of given file name, i.e. pointer to
8857 first char after last `/' (or `\' for WIN32) in given file name,
8858 given file name itself if the directory name is absent. The
8859 returned string can not be changed. */
8860static const char *
3d7aafde 8861base_file_name (const char *file_name)
fae15c93
VM
8862{
8863 int directory_name_length;
8864
8865 directory_name_length = strlen (file_name);
8866#ifdef WIN32
8867 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
8868 && file_name[directory_name_length] != '\\')
8869#else
8870 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
8871#endif
8872 directory_name_length--;
8873 return file_name + directory_name_length + 1;
8874}
8875
8876/* The following is top level function to initialize the work of
8877 pipeline hazards description translator. */
8c94f366 8878static void
3d7aafde 8879initiate_automaton_gen (int argc, char **argv)
fae15c93
VM
8880{
8881 const char *base_name;
8882 int i;
8883
8884 ndfa_flag = 0;
8885 split_argument = 0; /* default value */
8886 no_minimization_flag = 0;
8887 time_flag = 0;
df1133a6 8888 stats_flag = 0;
fae15c93
VM
8889 v_flag = 0;
8890 w_flag = 0;
dfa849f3 8891 progress_flag = 0;
fae15c93
VM
8892 for (i = 2; i < argc; i++)
8893 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
8894 no_minimization_flag = 1;
e3c8eb86 8895 else if (strcmp (argv [i], TIME_OPTION) == 0)
fae15c93 8896 time_flag = 1;
df1133a6
BE
8897 else if (strcmp (argv [i], STATS_OPTION) == 0)
8898 stats_flag = 1;
e3c8eb86 8899 else if (strcmp (argv [i], V_OPTION) == 0)
fae15c93
VM
8900 v_flag = 1;
8901 else if (strcmp (argv [i], W_OPTION) == 0)
8902 w_flag = 1;
8903 else if (strcmp (argv [i], NDFA_OPTION) == 0)
8904 ndfa_flag = 1;
dfa849f3
VM
8905 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
8906 progress_flag = 1;
fae15c93
VM
8907 else if (strcmp (argv [i], "-split") == 0)
8908 {
8909 if (i + 1 >= argc)
8910 fatal ("-split has no argument.");
8911 fatal ("option `-split' has not been implemented yet\n");
8912 /* split_argument = atoi (argument_vect [i + 1]); */
8913 }
1fb49ce7 8914
fae15c93
VM
8915 /* Initialize IR storage. */
8916 obstack_init (&irp);
8917 initiate_automaton_decl_table ();
8918 initiate_insn_decl_table ();
8919 initiate_decl_table ();
8920 output_file = stdout;
8921 output_description_file = NULL;
8922 base_name = base_file_name (argv[1]);
8923 obstack_grow (&irp, base_name,
8924 strlen (base_name) - strlen (file_name_suffix (base_name)));
8925 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
8926 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
8927 obstack_1grow (&irp, '\0');
8928 output_description_file_name = obstack_base (&irp);
8929 obstack_finish (&irp);
8930}
8931
8932/* The following function checks existence at least one arc marked by
8933 each insn. */
8934static void
3d7aafde 8935check_automata_insn_issues (void)
fae15c93
VM
8936{
8937 automaton_t automaton;
8938 ainsn_t ainsn, reserv_ainsn;
8939
8940 for (automaton = description->first_automaton;
8941 automaton != NULL;
8942 automaton = automaton->next_automaton)
8943 {
8944 for (ainsn = automaton->ainsn_list;
8945 ainsn != NULL;
8946 ainsn = ainsn->next_ainsn)
8947 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
8948 {
8949 for (reserv_ainsn = ainsn;
8950 reserv_ainsn != NULL;
8951 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
8952 if (automaton->corresponding_automaton_decl != NULL)
8953 {
8954 if (!w_flag)
8955 error ("Automaton `%s': Insn `%s' will never be issued",
8956 automaton->corresponding_automaton_decl->name,
8957 reserv_ainsn->insn_reserv_decl->name);
8958 else
8959 warning
d4ee4d25 8960 (0, "Automaton `%s': Insn `%s' will never be issued",
fae15c93
VM
8961 automaton->corresponding_automaton_decl->name,
8962 reserv_ainsn->insn_reserv_decl->name);
8963 }
8964 else
8965 {
8966 if (!w_flag)
8967 error ("Insn `%s' will never be issued",
8968 reserv_ainsn->insn_reserv_decl->name);
8969 else
d4ee4d25 8970 warning (0, "Insn `%s' will never be issued",
fae15c93
VM
8971 reserv_ainsn->insn_reserv_decl->name);
8972 }
8973 }
8974 }
8975}
8976
8977/* The following vla is used for storing pointers to all achieved
8978 states. */
1fb49ce7 8979static VEC(state_t,heap) *automaton_states;
fae15c93
VM
8980
8981/* This function is called by function pass_states to add an achieved
8982 STATE. */
8983static void
3d7aafde 8984add_automaton_state (state_t state)
fae15c93 8985{
1fb49ce7 8986 VEC_safe_push (state_t,heap, automaton_states, state);
fae15c93
VM
8987}
8988
8989/* The following function forms list of important automata (whose
8990 states may be changed after the insn issue) for each insn. */
8991static void
3d7aafde 8992form_important_insn_automata_lists (void)
fae15c93
VM
8993{
8994 automaton_t automaton;
fae15c93
VM
8995 decl_t decl;
8996 ainsn_t ainsn;
8997 arc_t arc;
8998 int i;
1fb49ce7 8999 size_t n;
fae15c93 9000
1fb49ce7 9001 automaton_states = 0;
deb09eff 9002 /* Mark important ainsns. */
fae15c93
VM
9003 for (automaton = description->first_automaton;
9004 automaton != NULL;
9005 automaton = automaton->next_automaton)
9006 {
1fb49ce7 9007 VEC_truncate (state_t, automaton_states, 0);
fae15c93 9008 pass_states (automaton, add_automaton_state);
1fb49ce7 9009 for (n = 0; n < VEC_length (state_t, automaton_states); n++)
fae15c93 9010 {
1fb49ce7
ZW
9011 state_t s = VEC_index (state_t, automaton_states, n);
9012 for (arc = first_out_arc (s);
fae15c93
VM
9013 arc != NULL;
9014 arc = next_out_arc (arc))
1fb49ce7 9015 if (arc->to_state != s)
fae15c93 9016 {
b2d59f6f 9017 gcc_assert (arc->insn->first_insn_with_same_reservs);
fae15c93
VM
9018 for (ainsn = arc->insn;
9019 ainsn != NULL;
9020 ainsn = ainsn->next_same_reservs_insn)
9021 ainsn->important_p = TRUE;
9022 }
9023 }
9024 }
1fb49ce7
ZW
9025 VEC_free (state_t,heap, automaton_states);
9026
deb09eff 9027 /* Create automata sets for the insns. */
fae15c93
VM
9028 for (i = 0; i < description->decls_num; i++)
9029 {
9030 decl = description->decls [i];
9031 if (decl->mode == dm_insn_reserv)
9032 {
9033 automata_list_start ();
9034 for (automaton = description->first_automaton;
9035 automaton != NULL;
9036 automaton = automaton->next_automaton)
9037 for (ainsn = automaton->ainsn_list;
9038 ainsn != NULL;
9039 ainsn = ainsn->next_ainsn)
9040 if (ainsn->important_p
4005971c 9041 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
fae15c93
VM
9042 {
9043 automata_list_add (automaton);
9044 break;
9045 }
4005971c 9046 DECL_INSN_RESERV (decl)->important_automata_list
fae15c93
VM
9047 = automata_list_finish ();
9048 }
9049 }
9050}
9051
9052
9053/* The following is top level function to generate automat(a,on) for
9054 fast recognition of pipeline hazards. */
8c94f366 9055static void
3d7aafde 9056expand_automata (void)
fae15c93
VM
9057{
9058 int i;
9059
9060 description = create_node (sizeof (struct description)
9061 /* One entry for cycle advancing insn. */
1fb49ce7
ZW
9062 + sizeof (decl_t) * VEC_length (decl_t, decls));
9063 description->decls_num = VEC_length (decl_t, decls);
fae15c93
VM
9064 description->query_units_num = 0;
9065 for (i = 0; i < description->decls_num; i++)
9066 {
1fb49ce7 9067 description->decls [i] = VEC_index (decl_t, decls, i);
fae15c93 9068 if (description->decls [i]->mode == dm_unit
4005971c
VM
9069 && DECL_UNIT (description->decls [i])->query_p)
9070 DECL_UNIT (description->decls [i])->query_num
fae15c93
VM
9071 = description->query_units_num++;
9072 }
9073 all_time = create_ticker ();
9074 check_time = create_ticker ();
dfa849f3
VM
9075 if (progress_flag)
9076 fprintf (stderr, "Check description...");
fae15c93 9077 check_all_description ();
dfa849f3
VM
9078 if (progress_flag)
9079 fprintf (stderr, "done\n");
fae15c93
VM
9080 ticker_off (&check_time);
9081 generation_time = create_ticker ();
deb09eff
VM
9082 if (!have_error)
9083 {
9084 transform_insn_regexps ();
9085 check_unit_distributions_to_automata ();
9086 }
fae15c93
VM
9087 if (!have_error)
9088 {
9089 generate ();
deb09eff
VM
9090 check_automata_insn_issues ();
9091 }
9092 if (!have_error)
9093 {
9094 form_important_insn_automata_lists ();
fae15c93
VM
9095 }
9096 ticker_off (&generation_time);
fae15c93
VM
9097}
9098
9099/* The following is top level function to output PHR and to finish
9100 work with pipeline description translator. */
8c94f366 9101static void
3d7aafde 9102write_automata (void)
fae15c93 9103{
fae15c93 9104 output_time = create_ticker ();
dfa849f3
VM
9105 if (progress_flag)
9106 fprintf (stderr, "Forming and outputting automata tables...");
fae15c93 9107 output_tables ();
dfa849f3
VM
9108 if (progress_flag)
9109 {
9110 fprintf (stderr, "done\n");
9111 fprintf (stderr, "Output functions to work with automata...");
9112 }
fae15c93
VM
9113 output_chip_definitions ();
9114 output_max_insn_queue_index_def ();
9115 output_internal_min_issue_delay_func ();
9116 output_internal_trans_func ();
9117 /* Cache of insn dfa codes: */
9118 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9119 fprintf (output_file, "\nstatic int %s;\n\n",
9120 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9121 output_dfa_insn_code_func ();
9122 output_trans_func ();
fae15c93
VM
9123 output_min_issue_delay_func ();
9124 output_internal_dead_lock_func ();
9125 output_dead_lock_func ();
9126 output_size_func ();
9127 output_internal_reset_func ();
9128 output_reset_func ();
9129 output_min_insn_conflict_delay_func ();
9130 output_internal_insn_latency_func ();
9131 output_insn_latency_func ();
9132 output_print_reservation_func ();
30028c85
VM
9133 /* Output function get_cpu_unit_code. */
9134 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9135 output_get_cpu_unit_code_func ();
9136 output_cpu_unit_reservation_p ();
9137 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9138 CPU_UNITS_QUERY_MACRO_NAME);
9139 output_dfa_clean_insn_cache_func ();
fae15c93
VM
9140 output_dfa_start_func ();
9141 output_dfa_finish_func ();
dfa849f3
VM
9142 if (progress_flag)
9143 fprintf (stderr, "done\n");
fae15c93
VM
9144 if (v_flag)
9145 {
9146 output_description_file = fopen (output_description_file_name, "w");
9147 if (output_description_file == NULL)
9148 {
9149 perror (output_description_file_name);
9150 exit (FATAL_EXIT_CODE);
9151 }
dfa849f3
VM
9152 if (progress_flag)
9153 fprintf (stderr, "Output automata description...");
fae15c93
VM
9154 output_description ();
9155 output_automaton_descriptions ();
dfa849f3
VM
9156 if (progress_flag)
9157 fprintf (stderr, "done\n");
fae15c93
VM
9158 output_statistics (output_description_file);
9159 }
df1133a6
BE
9160 if (stats_flag)
9161 output_statistics (stderr);
fae15c93 9162 ticker_off (&output_time);
df1133a6
BE
9163 if (time_flag)
9164 output_time_statistics (stderr);
fae15c93
VM
9165 finish_states ();
9166 finish_arcs ();
9167 finish_automata_lists ();
9168 if (time_flag)
9169 {
9170 fprintf (stderr, "Summary:\n");
9171 fprintf (stderr, " check time ");
9172 print_active_time (stderr, check_time);
9173 fprintf (stderr, ", generation time ");
9174 print_active_time (stderr, generation_time);
9175 fprintf (stderr, ", all time ");
9176 print_active_time (stderr, all_time);
9177 fprintf (stderr, "\n");
9178 }
9179 /* Finish all work. */
9180 if (output_description_file != NULL)
9181 {
9182 fflush (output_description_file);
9183 if (ferror (stdout) != 0)
19b8c2d9
BE
9184 fatal ("Error in writing DFA description file %s: %s",
9185 output_description_file_name, xstrerror (errno));
fae15c93
VM
9186 fclose (output_description_file);
9187 }
9188 finish_automaton_decl_table ();
9189 finish_insn_decl_table ();
9190 finish_decl_table ();
9191 obstack_free (&irp, NULL);
9192 if (have_error && output_description_file != NULL)
9193 remove (output_description_file_name);
9194}
8c94f366
ZW
9195
9196int
9197main (int argc, char **argv)
9198{
9199 rtx desc;
9200
9201 progname = "genautomata";
9202
9203 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
9204 return (FATAL_EXIT_CODE);
9205
9206 initiate_automaton_gen (argc, argv);
9207 while (1)
9208 {
9209 int lineno;
9210 int insn_code_number;
9211
9212 desc = read_md_rtx (&lineno, &insn_code_number);
9213 if (desc == NULL)
9214 break;
9215
9216 switch (GET_CODE (desc))
9217 {
9218 case DEFINE_CPU_UNIT:
9219 gen_cpu_unit (desc);
9220 break;
9221
9222 case DEFINE_QUERY_CPU_UNIT:
9223 gen_query_cpu_unit (desc);
9224 break;
9225
9226 case DEFINE_BYPASS:
9227 gen_bypass (desc);
9228 break;
9229
9230 case EXCLUSION_SET:
9231 gen_excl_set (desc);
9232 break;
9233
9234 case PRESENCE_SET:
9235 gen_presence_set (desc);
9236 break;
9237
9238 case FINAL_PRESENCE_SET:
9239 gen_final_presence_set (desc);
9240 break;
9241
9242 case ABSENCE_SET:
9243 gen_absence_set (desc);
9244 break;
9245
9246 case FINAL_ABSENCE_SET:
9247 gen_final_absence_set (desc);
9248 break;
9249
9250 case DEFINE_AUTOMATON:
9251 gen_automaton (desc);
9252 break;
9253
9254 case AUTOMATA_OPTION:
9255 gen_automata_option (desc);
9256 break;
9257
9258 case DEFINE_RESERVATION:
9259 gen_reserv (desc);
9260 break;
9261
9262 case DEFINE_INSN_RESERVATION:
9263 gen_insn_reserv (desc);
9264 break;
9265
9266 default:
9267 break;
9268 }
9269 }
9270
9271 if (have_error)
9272 return FATAL_EXIT_CODE;
9273
9274 puts ("/* Generated automatically by the program `genautomata'\n"
9275 " from the machine description file `md'. */\n\n"
9276 "#include \"config.h\"\n"
9277 "#include \"system.h\"\n"
9278 "#include \"coretypes.h\"\n"
9279 "#include \"tm.h\"\n"
9280 "#include \"rtl.h\"\n"
63622a81
SE
9281 "#include \"tm_p.h\"\n"
9282 "#include \"insn-config.h\"\n"
9283 "#include \"recog.h\"\n"
9284 "#include \"regs.h\"\n"
9285 "#include \"real.h\"\n"
9286 "#include \"output.h\"\n"
9287 "#include \"insn-attr.h\"\n"
9288 "#include \"toplev.h\"\n"
9289 "#include \"flags.h\"\n"
9290 "#include \"function.h\"\n");
8c94f366
ZW
9291
9292 if (VEC_length (decl_t, decls) > 0)
9293 {
9294 expand_automata ();
9295 write_automata ();
9296 }
9297
9298 fflush (stdout);
9299 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9300}