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