source: trunk/third/gcc/genattr.c @ 8834

Revision 8834, 11.9 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* Generate attribute information (insn-attr.h) from machine description.
2   Copyright (C) 1991, 1994 Free Software Foundation, Inc.
3   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22
23#include <stdio.h>
24#include "hconfig.h"
25#include "rtl.h"
26#include "obstack.h"
27
28static struct obstack obstack;
29struct obstack *rtl_obstack = &obstack;
30
31#define obstack_chunk_alloc xmalloc
32#define obstack_chunk_free free
33
34extern void free PROTO((void *));
35extern rtx read_rtx PROTO((FILE *));
36
37char *xmalloc PROTO((unsigned));
38static void fatal ();
39void fancy_abort PROTO((void));
40
41/* A range of values.  */
42
43struct range
44{
45  int min;
46  int max;
47};
48
49/* Record information about each function unit mentioned in a
50   DEFINE_FUNCTION_UNIT.  */
51
52struct function_unit
53{
54  char *name;                   /* Function unit name.  */
55  struct function_unit *next;   /* Next function unit.  */
56  int multiplicity;             /* Number of units of this type.  */
57  int simultaneity;             /* Maximum number of simultaneous insns
58                                   on this function unit or 0 if unlimited.  */
59  struct range ready_cost;      /* Range of ready cost values.  */
60  struct range issue_delay;     /* Range of issue delay values.  */
61};
62
63static void
64extend_range (range, min, max)
65     struct range *range;
66     int min;
67     int max;
68{
69  if (range->min > min) range->min = min;
70  if (range->max < max) range->max = max;
71}
72
73static void
74init_range (range)
75     struct range *range;
76{
77  range->min = 100000;
78  range->max = -1;
79}
80
81static void
82write_upcase (str)
83    char *str;
84{
85  for (; *str; str++)
86    if (*str >= 'a' && *str <= 'z')
87      printf ("%c", *str - 'a' + 'A');
88    else
89      printf ("%c", *str);
90}
91
92static void
93gen_attr (attr)
94     rtx attr;
95{
96  char *p;
97
98  printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0));
99
100  /* If numeric attribute, don't need to write an enum.  */
101  if (*XSTR (attr, 1) == '\0')
102    printf ("extern int get_attr_%s ();\n", XSTR (attr, 0));
103  else
104    {
105      printf ("enum attr_%s {", XSTR (attr, 0));
106      write_upcase (XSTR (attr, 0));
107      printf ("_");
108
109      for (p = XSTR (attr, 1); *p != '\0'; p++)
110        {
111          if (*p == ',')
112            {
113              printf (", ");
114              write_upcase (XSTR (attr, 0));
115              printf ("_");
116            }
117          else if (*p >= 'a' && *p <= 'z')
118            printf ("%c", *p - 'a' + 'A');
119          else
120            printf ("%c", *p);
121        }
122
123      printf ("};\n");
124      printf ("extern enum attr_%s get_attr_%s ();\n\n",
125              XSTR (attr, 0), XSTR (attr, 0));
126    }
127
128  /* If `length' attribute, write additional function definitions and define
129     variables used by `insn_current_length'.  */
130  if (! strcmp (XSTR (attr, 0), "length"))
131    {
132      printf ("extern void init_lengths ();\n");
133      printf ("extern void shorten_branches PROTO((rtx));\n");
134      printf ("extern int insn_default_length PROTO((rtx));\n");
135      printf ("extern int insn_variable_length_p PROTO((rtx));\n");
136      printf ("extern int insn_current_length PROTO((rtx));\n\n");
137      printf ("extern int *insn_addresses;\n");
138      printf ("extern int insn_current_address;\n\n");
139    }
140}
141
142static void
143write_units (num_units, multiplicity, simultaneity,
144             ready_cost, issue_delay, blockage)
145     int num_units;
146     struct range *multiplicity;
147     struct range *simultaneity;
148     struct range *ready_cost;
149     struct range *issue_delay;
150     struct range *blockage;
151{
152  int i, q_size;
153
154  printf ("#define INSN_SCHEDULING\n\n");
155  printf ("extern int result_ready_cost PROTO((rtx));\n");
156  printf ("extern int function_units_used PROTO((rtx));\n\n");
157  printf ("extern struct function_unit_desc\n");
158  printf ("{\n");
159  printf ("  char *name;\n");
160  printf ("  int bitmask;\n");
161  printf ("  int multiplicity;\n");
162  printf ("  int simultaneity;\n");
163  printf ("  int default_cost;\n");
164  printf ("  int max_issue_delay;\n");
165  printf ("  int (*ready_cost_function) ();\n");
166  printf ("  int (*conflict_cost_function) ();\n");
167  printf ("  int max_blockage;\n");
168  printf ("  unsigned int (*blockage_range_function) ();\n");
169  printf ("  int (*blockage_function) ();\n");
170  printf ("} function_units[];\n\n");
171  printf ("#define FUNCTION_UNITS_SIZE %d\n", num_units);
172  printf ("#define MIN_MULTIPLICITY %d\n", multiplicity->min);
173  printf ("#define MAX_MULTIPLICITY %d\n", multiplicity->max);
174  printf ("#define MIN_SIMULTANEITY %d\n", simultaneity->min);
175  printf ("#define MAX_SIMULTANEITY %d\n", simultaneity->max);
176  printf ("#define MIN_READY_COST %d\n", ready_cost->min);
177  printf ("#define MAX_READY_COST %d\n", ready_cost->max);
178  printf ("#define MIN_ISSUE_DELAY %d\n", issue_delay->min);
179  printf ("#define MAX_ISSUE_DELAY %d\n", issue_delay->max);
180  printf ("#define MIN_BLOCKAGE %d\n", blockage->min);
181  printf ("#define MAX_BLOCKAGE %d\n", blockage->max);
182  for (i = 0; (1 << i) < blockage->max; i++)
183    ;
184  printf ("#define BLOCKAGE_BITS %d\n", i + 1);
185
186  /* INSN_QUEUE_SIZE is a power of two larger than MAX_BLOCKAGE and
187     MAX_READY_COST.  This is the longest time an isnsn may be queued.  */
188  i = MAX (blockage->max, ready_cost->max);
189  for (q_size = 1; q_size <= i; q_size <<= 1)
190    ;
191  printf ("#define INSN_QUEUE_SIZE %d\n", q_size);
192}
193
194char *
195xmalloc (size)
196     unsigned size;
197{
198  register char *val = (char *) malloc (size);
199
200  if (val == 0)
201    fatal ("virtual memory exhausted");
202  return val;
203}
204
205char *
206xrealloc (ptr, size)
207     char *ptr;
208     unsigned size;
209{
210  char * result = (char *) realloc (ptr, size);
211  if (!result)
212    fatal ("virtual memory exhausted");
213  return result;
214}
215
216static void
217fatal (s, a1, a2)
218     char *s;
219{
220  fprintf (stderr, "genattr: ");
221  fprintf (stderr, s, a1, a2);
222  fprintf (stderr, "\n");
223  exit (FATAL_EXIT_CODE);
224}
225
226/* More 'friendly' abort that prints the line and file.
227   config.h can #define abort fancy_abort if you like that sort of thing.  */
228
229void
230fancy_abort ()
231{
232  fatal ("Internal gcc abort.");
233}
234
235int
236main (argc, argv)
237     int argc;
238     char **argv;
239{
240  rtx desc;
241  FILE *infile;
242  register int c;
243  int have_delay = 0;
244  int have_annul_true = 0;
245  int have_annul_false = 0;
246  int num_units = 0;
247  struct range all_simultaneity, all_multiplicity;
248  struct range all_ready_cost, all_issue_delay, all_blockage;
249  struct function_unit *units = 0, *unit;
250  int i;
251
252  init_range (&all_multiplicity);
253  init_range (&all_simultaneity);
254  init_range (&all_ready_cost);
255  init_range (&all_issue_delay);
256  init_range (&all_blockage);
257
258  obstack_init (rtl_obstack);
259
260  if (argc <= 1)
261    fatal ("No input file name.");
262
263  infile = fopen (argv[1], "r");
264  if (infile == 0)
265    {
266      perror (argv[1]);
267      exit (FATAL_EXIT_CODE);
268    }
269
270  init_rtl ();
271
272  printf ("/* Generated automatically by the program `genattr'\n\
273from the machine description file `md'.  */\n\n");
274
275  /* For compatibility, define the attribute `alternative', which is just
276     a reference to the variable `which_alternative'.  */
277
278  printf("#ifndef PROTO\n");
279  printf("#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)\n");
280  printf("#define PROTO(ARGS) ARGS\n");
281  printf("#else\n");
282  printf("#define PROTO(ARGS) ()\n");
283  printf("#endif\n");
284  printf("#endif\n");
285
286  printf ("#define HAVE_ATTR_alternative\n");
287  printf ("#define get_attr_alternative(insn) which_alternative\n");
288     
289  /* Read the machine description.  */
290
291  while (1)
292    {
293      c = read_skip_spaces (infile);
294      if (c == EOF)
295        break;
296      ungetc (c, infile);
297
298      desc = read_rtx (infile);
299      if (GET_CODE (desc) == DEFINE_ATTR)
300        gen_attr (desc);
301
302      else if (GET_CODE (desc) == DEFINE_DELAY)
303        {
304          if (! have_delay)
305            {
306              printf ("#define DELAY_SLOTS\n");
307              printf ("extern int num_delay_slots PROTO((rtx));\n");
308              printf ("extern int eligible_for_delay PROTO((rtx, int, rtx, int));\n\n");
309              printf ("extern int const_num_delay_slots PROTO((rtx));\n\n");
310              have_delay = 1;
311            }
312
313          for (i = 0; i < XVECLEN (desc, 1); i += 3)
314            {
315              if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
316                {
317                  printf ("#define ANNUL_IFTRUE_SLOTS\n");
318                  printf ("extern int eligible_for_annul_true ();\n");
319                  have_annul_true = 1;
320                }
321
322              if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
323                {
324                  printf ("#define ANNUL_IFFALSE_SLOTS\n");
325                  printf ("extern int eligible_for_annul_false ();\n");
326                  have_annul_false = 1;
327                }
328            }
329        }
330
331      else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
332        {
333          char *name = XSTR (desc, 0);
334          int multiplicity = XINT (desc, 1);
335          int simultaneity = XINT (desc, 2);
336          int ready_cost = MAX (XINT (desc, 4), 1);
337          int issue_delay = MAX (XINT (desc, 5), 1);
338          int issueexp_p = (XVEC (desc, 6) != 0);
339
340          for (unit = units; unit; unit = unit->next)
341            if (strcmp (unit->name, name) == 0)
342              break;
343
344          if (unit == 0)
345            {
346              int len = strlen (name) + 1;
347              unit = (struct function_unit *)
348                alloca (sizeof (struct function_unit));
349              unit->name = (char *) alloca (len);
350              bcopy (name, unit->name, len);
351              unit->multiplicity = multiplicity;
352              unit->simultaneity = simultaneity;
353              unit->ready_cost.min = unit->ready_cost.max = ready_cost;
354              unit->issue_delay.min = unit->issue_delay.max = issue_delay;
355              unit->next = units;
356              units = unit;
357              num_units++;
358
359              extend_range (&all_multiplicity, multiplicity, multiplicity);
360              extend_range (&all_simultaneity, simultaneity, simultaneity);
361            }
362          else if (unit->multiplicity != multiplicity
363                   || unit->simultaneity != simultaneity)
364            fatal ("Differing specifications given for `%s' function unit.",
365                   unit->name);
366
367          extend_range (&unit->ready_cost, ready_cost, ready_cost);
368          extend_range (&unit->issue_delay,
369                        issueexp_p ? 1 : issue_delay, issue_delay);
370          extend_range (&all_ready_cost,
371                        unit->ready_cost.min, unit->ready_cost.max);
372          extend_range (&all_issue_delay,
373                        unit->issue_delay.min, unit->issue_delay.max);
374        }
375    }
376
377  if (num_units > 0)
378    {
379      /* Compute the range of blockage cost values.  See genattrtab.c
380         for the derivation.  BLOCKAGE (E,C) when SIMULTANEITY is zero is
381
382             MAX (ISSUE-DELAY (E,C),
383                  READY-COST (E) - (READY-COST (C) - 1))
384
385         and otherwise
386
387             MAX (ISSUE-DELAY (E,C),
388                  READY-COST (E) - (READY-COST (C) - 1),
389                  READY-COST (E) - FILL-TIME)  */
390
391      for (unit = units; unit; unit = unit->next)
392        {
393          struct range blockage;
394
395          blockage = unit->issue_delay;
396          blockage.max = MAX (unit->ready_cost.max
397                              - (unit->ready_cost.min - 1),
398                              blockage.max);
399          blockage.min = MAX (1, blockage.min);
400
401          if (unit->simultaneity != 0)
402            {
403              int fill_time = ((unit->simultaneity - 1)
404                               * unit->issue_delay.min);
405              blockage.min = MAX (unit->ready_cost.min - fill_time,
406                                  blockage.min);
407              blockage.max = MAX (unit->ready_cost.max - fill_time,
408                                  blockage.max);
409            }
410          extend_range (&all_blockage, blockage.min, blockage.max);
411        }
412
413      write_units (num_units, &all_multiplicity, &all_simultaneity,
414                   &all_ready_cost, &all_issue_delay, &all_blockage);
415    }
416
417  /* Output flag masks for use by reorg. 
418
419     Flags are used to hold branch direction and prediction information
420     for use by eligible_for_...  */
421  printf("\n#define ATTR_FLAG_forward\t0x1\n");
422  printf("#define ATTR_FLAG_backward\t0x2\n");
423  printf("#define ATTR_FLAG_likely\t0x4\n");
424  printf("#define ATTR_FLAG_very_likely\t0x8\n");
425  printf("#define ATTR_FLAG_unlikely\t0x10\n");
426  printf("#define ATTR_FLAG_very_unlikely\t0x20\n");
427
428  fflush (stdout);
429  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
430  /* NOTREACHED */
431  return 0;
432}
Note: See TracBrowser for help on using the repository browser.