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