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

Revision 11288, 11.7 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11287, 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, 1996 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 ("#define HAVE_ATTR_alternative\n");
279  printf ("#define get_attr_alternative(insn) which_alternative\n");
280     
281  /* Read the machine description.  */
282
283  while (1)
284    {
285      c = read_skip_spaces (infile);
286      if (c == EOF)
287        break;
288      ungetc (c, infile);
289
290      desc = read_rtx (infile);
291      if (GET_CODE (desc) == DEFINE_ATTR)
292        gen_attr (desc);
293
294      else if (GET_CODE (desc) == DEFINE_DELAY)
295        {
296          if (! have_delay)
297            {
298              printf ("#define DELAY_SLOTS\n");
299              printf ("extern int num_delay_slots PROTO((rtx));\n");
300              printf ("extern int eligible_for_delay PROTO((rtx, int, rtx, int));\n\n");
301              printf ("extern int const_num_delay_slots PROTO((rtx));\n\n");
302              have_delay = 1;
303            }
304
305          for (i = 0; i < XVECLEN (desc, 1); i += 3)
306            {
307              if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
308                {
309                  printf ("#define ANNUL_IFTRUE_SLOTS\n");
310                  printf ("extern int eligible_for_annul_true ();\n");
311                  have_annul_true = 1;
312                }
313
314              if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
315                {
316                  printf ("#define ANNUL_IFFALSE_SLOTS\n");
317                  printf ("extern int eligible_for_annul_false ();\n");
318                  have_annul_false = 1;
319                }
320            }
321        }
322
323      else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
324        {
325          char *name = XSTR (desc, 0);
326          int multiplicity = XINT (desc, 1);
327          int simultaneity = XINT (desc, 2);
328          int ready_cost = MAX (XINT (desc, 4), 1);
329          int issue_delay = MAX (XINT (desc, 5), 1);
330          int issueexp_p = (XVEC (desc, 6) != 0);
331
332          for (unit = units; unit; unit = unit->next)
333            if (strcmp (unit->name, name) == 0)
334              break;
335
336          if (unit == 0)
337            {
338              int len = strlen (name) + 1;
339              unit = (struct function_unit *)
340                alloca (sizeof (struct function_unit));
341              unit->name = (char *) alloca (len);
342              bcopy (name, unit->name, len);
343              unit->multiplicity = multiplicity;
344              unit->simultaneity = simultaneity;
345              unit->ready_cost.min = unit->ready_cost.max = ready_cost;
346              unit->issue_delay.min = unit->issue_delay.max = issue_delay;
347              unit->next = units;
348              units = unit;
349              num_units++;
350
351              extend_range (&all_multiplicity, multiplicity, multiplicity);
352              extend_range (&all_simultaneity, simultaneity, simultaneity);
353            }
354          else if (unit->multiplicity != multiplicity
355                   || unit->simultaneity != simultaneity)
356            fatal ("Differing specifications given for `%s' function unit.",
357                   unit->name);
358
359          extend_range (&unit->ready_cost, ready_cost, ready_cost);
360          extend_range (&unit->issue_delay,
361                        issueexp_p ? 1 : issue_delay, issue_delay);
362          extend_range (&all_ready_cost,
363                        unit->ready_cost.min, unit->ready_cost.max);
364          extend_range (&all_issue_delay,
365                        unit->issue_delay.min, unit->issue_delay.max);
366        }
367    }
368
369  if (num_units > 0)
370    {
371      /* Compute the range of blockage cost values.  See genattrtab.c
372         for the derivation.  BLOCKAGE (E,C) when SIMULTANEITY is zero is
373
374             MAX (ISSUE-DELAY (E,C),
375                  READY-COST (E) - (READY-COST (C) - 1))
376
377         and otherwise
378
379             MAX (ISSUE-DELAY (E,C),
380                  READY-COST (E) - (READY-COST (C) - 1),
381                  READY-COST (E) - FILL-TIME)  */
382
383      for (unit = units; unit; unit = unit->next)
384        {
385          struct range blockage;
386
387          blockage = unit->issue_delay;
388          blockage.max = MAX (unit->ready_cost.max
389                              - (unit->ready_cost.min - 1),
390                              blockage.max);
391          blockage.min = MAX (1, blockage.min);
392
393          if (unit->simultaneity != 0)
394            {
395              int fill_time = ((unit->simultaneity - 1)
396                               * unit->issue_delay.min);
397              blockage.min = MAX (unit->ready_cost.min - fill_time,
398                                  blockage.min);
399              blockage.max = MAX (unit->ready_cost.max - fill_time,
400                                  blockage.max);
401            }
402          extend_range (&all_blockage, blockage.min, blockage.max);
403        }
404
405      write_units (num_units, &all_multiplicity, &all_simultaneity,
406                   &all_ready_cost, &all_issue_delay, &all_blockage);
407    }
408
409  /* Output flag masks for use by reorg. 
410
411     Flags are used to hold branch direction and prediction information
412     for use by eligible_for_...  */
413  printf("\n#define ATTR_FLAG_forward\t0x1\n");
414  printf("#define ATTR_FLAG_backward\t0x2\n");
415  printf("#define ATTR_FLAG_likely\t0x4\n");
416  printf("#define ATTR_FLAG_very_likely\t0x8\n");
417  printf("#define ATTR_FLAG_unlikely\t0x10\n");
418  printf("#define ATTR_FLAG_very_unlikely\t0x20\n");
419
420  fflush (stdout);
421  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
422  /* NOTREACHED */
423  return 0;
424}
Note: See TracBrowser for help on using the repository browser.