OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [genautomata.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.