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

Revision 11288, 20.9 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/* Allocate and read RTL for GNU C Compiler.
2   Copyright (C) 1987, 1988, 1991, 1994, 1997 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22#include "config.h"
23#include <ctype.h>
24#include <stdio.h>
25#include "rtl.h"
26#include "real.h"
27
28#include "obstack.h"
29#define obstack_chunk_alloc     xmalloc
30#define obstack_chunk_free      free
31
32/* Obstack used for allocating RTL objects.
33   Between functions, this is the permanent_obstack.
34   While parsing and expanding a function, this is maybepermanent_obstack
35   so we can save it if it is an inline function.
36   During optimization and output, this is function_obstack.  */
37
38extern struct obstack *rtl_obstack;
39
40#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
41extern long atol();
42#endif
43
44/* Indexed by rtx code, gives number of operands for an rtx with that code.
45   Does NOT include rtx header data (code and links).
46   This array is initialized in init_rtl.  */
47
48int rtx_length[NUM_RTX_CODE + 1];
49
50/* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
51
52#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
53
54char *rtx_name[] = {
55#include "rtl.def"              /* rtl expressions are documented here */
56};
57
58#undef DEF_RTL_EXPR
59
60/* Indexed by machine mode, gives the name of that machine mode.
61   This name does not include the letters "mode".  */
62
63#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  NAME,
64
65char *mode_name[(int) MAX_MACHINE_MODE] = {
66#include "machmode.def"
67
68#ifdef EXTRA_CC_MODES
69  EXTRA_CC_NAMES
70#endif
71
72};
73
74#undef DEF_MACHMODE
75
76/* Indexed by machine mode, gives the length of the mode, in bytes.
77   GET_MODE_CLASS uses this.  */
78
79#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  CLASS,
80
81enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
82#include "machmode.def"
83};
84
85#undef DEF_MACHMODE
86
87/* Indexed by machine mode, gives the length of the mode, in bytes.
88   GET_MODE_SIZE uses this.  */
89
90#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  SIZE,
91
92int mode_size[(int) MAX_MACHINE_MODE] = {
93#include "machmode.def"
94};
95
96#undef DEF_MACHMODE
97
98/* Indexed by machine mode, gives the length of the mode's subunit.
99   GET_MODE_UNIT_SIZE uses this.  */
100
101#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  UNIT,
102
103int mode_unit_size[(int) MAX_MACHINE_MODE] = {
104#include "machmode.def"         /* machine modes are documented here */
105};
106
107#undef DEF_MACHMODE
108
109/* Indexed by machine mode, gives next wider natural mode
110   (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
111   use this.  */
112
113#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
114  (enum machine_mode) WIDER,
115
116enum machine_mode mode_wider_mode[(int) MAX_MACHINE_MODE] = {
117#include "machmode.def"         /* machine modes are documented here */
118};
119
120#undef DEF_MACHMODE
121
122/* Indexed by mode class, gives the narrowest mode for each class.  */
123
124enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
125
126/* Indexed by rtx code, gives a sequence of operand-types for
127   rtx's of that code.  The sequence is a C string in which
128   each character describes one operand.  */
129
130char *rtx_format[] = {
131  /* "*" undefined.
132         can cause a warning message
133     "0" field is unused (or used in a phase-dependent manner)
134         prints nothing
135     "i" an integer
136         prints the integer
137     "n" like "i", but prints entries from `note_insn_name'
138     "w" an integer of width HOST_BITS_PER_WIDE_INT
139         prints the integer
140     "s" a pointer to a string
141         prints the string
142     "S" like "s", but optional:
143         the containing rtx may end before this operand
144     "e" a pointer to an rtl expression
145         prints the expression
146     "E" a pointer to a vector that points to a number of rtl expressions
147         prints a list of the rtl expressions
148     "V" like "E", but optional:
149         the containing rtx may end before this operand
150     "u" a pointer to another insn
151         prints the uid of the insn.  */
152
153#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
154#include "rtl.def"              /* rtl expressions are defined here */
155#undef DEF_RTL_EXPR
156};
157
158/* Indexed by rtx code, gives a character representing the "class" of
159   that rtx code.  See rtl.def for documentation on the defined classes.  */
160
161char rtx_class[] = {
162#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS,
163#include "rtl.def"              /* rtl expressions are defined here */
164#undef DEF_RTL_EXPR
165};
166
167/* Names for kinds of NOTEs and REG_NOTEs.  */
168
169char *note_insn_name[] = { 0                    , "NOTE_INSN_DELETED",
170                           "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
171                           "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
172                           "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
173                           "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
174                           "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
175                           "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
176                           "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
177                           "NOTE_REPEATED_LINE_NUMBER" };
178
179char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
180                          "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
181                          "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
182                          "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
183                          "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
184                          "REG_EXEC_COUNT" };
185
186static void dump_and_abort      PROTO((int, int, FILE *));
187static void read_name           PROTO((char *, FILE *));
188
189/* Allocate an rtx vector of N elements.
190   Store the length, and initialize all elements to zero.  */
191
192rtvec
193rtvec_alloc (n)
194     int n;
195{
196  rtvec rt;
197  int i;
198
199  rt = (rtvec) obstack_alloc (rtl_obstack,
200                              sizeof (struct rtvec_def)
201                              + (( n - 1) * sizeof (rtunion)));
202
203  /* clear out the vector */
204  PUT_NUM_ELEM (rt, n);
205
206  for (i = 0; i < n; i++)
207    rt->elem[i].rtwint = 0;
208
209  return rt;
210}
211
212/* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
213   all the rest is initialized to zero.  */
214
215rtx
216rtx_alloc (code)
217  RTX_CODE code;
218{
219  rtx rt;
220  register struct obstack *ob = rtl_obstack;
221  register int nelts = GET_RTX_LENGTH (code);
222  register int length = sizeof (struct rtx_def)
223    + (nelts - 1) * sizeof (rtunion);
224
225  /* This function is called more than any other in GCC,
226     so we manipulate the obstack directly.
227
228     Even though rtx objects are word aligned, we may be sharing an obstack
229     with tree nodes, which may have to be double-word aligned.  So align
230     our length to the alignment mask in the obstack.  */
231
232  length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
233
234  if (ob->chunk_limit - ob->next_free < length)
235    _obstack_newchunk (ob, length);
236  rt = (rtx)ob->object_base;
237  ob->next_free += length;
238  ob->object_base = ob->next_free;
239
240  /* We want to clear everything up to the FLD array.  Normally, this is
241     one int, but we don't want to assume that and it isn't very portable
242     anyway; this is.  */
243
244  length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
245  for (; length >= 0; length--)
246    ((int *) rt)[length] = 0;
247
248  PUT_CODE (rt, code);
249
250  return rt;
251}
252
253/* Free the rtx X and all RTL allocated since X.  */
254
255void
256rtx_free (x)
257     rtx x;
258{
259  obstack_free (rtl_obstack, x);
260}
261
262/* Create a new copy of an rtx.
263   Recursively copies the operands of the rtx,
264   except for those few rtx codes that are sharable.  */
265
266rtx
267copy_rtx (orig)
268     register rtx orig;
269{
270  register rtx copy;
271  register int i, j;
272  register RTX_CODE code;
273  register char *format_ptr;
274
275  code = GET_CODE (orig);
276
277  switch (code)
278    {
279    case REG:
280    case QUEUED:
281    case CONST_INT:
282    case CONST_DOUBLE:
283    case SYMBOL_REF:
284    case CODE_LABEL:
285    case PC:
286    case CC0:
287    case SCRATCH:
288      /* SCRATCH must be shared because they represent distinct values.  */
289    case ADDRESSOF:
290      return orig;
291
292    case CONST:
293      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
294         a LABEL_REF, it isn't sharable.  */
295      if (GET_CODE (XEXP (orig, 0)) == PLUS
296          && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
297          && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
298        return orig;
299      break;
300
301      /* A MEM with a constant address is not sharable.  The problem is that
302         the constant address may need to be reloaded.  If the mem is shared,
303         then reloading one copy of this mem will cause all copies to appear
304         to have been reloaded.  */
305
306    default:
307      break;
308    }
309
310  copy = rtx_alloc (code);
311  PUT_MODE (copy, GET_MODE (orig));
312  copy->in_struct = orig->in_struct;
313  copy->volatil = orig->volatil;
314  copy->unchanging = orig->unchanging;
315  copy->integrated = orig->integrated;
316 
317  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
318
319  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
320    {
321      switch (*format_ptr++)
322        {
323        case 'e':
324          XEXP (copy, i) = XEXP (orig, i);
325          if (XEXP (orig, i) != NULL)
326            XEXP (copy, i) = copy_rtx (XEXP (orig, i));
327          break;
328
329        case '0':
330        case 'u':
331          XEXP (copy, i) = XEXP (orig, i);
332          break;
333
334        case 'E':
335        case 'V':
336          XVEC (copy, i) = XVEC (orig, i);
337          if (XVEC (orig, i) != NULL)
338            {
339              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
340              for (j = 0; j < XVECLEN (copy, i); j++)
341                XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
342            }
343          break;
344
345        case 'w':
346          XWINT (copy, i) = XWINT (orig, i);
347          break;
348
349        case 'i':
350          XINT (copy, i) = XINT (orig, i);
351          break;
352
353        case 's':
354        case 'S':
355          XSTR (copy, i) = XSTR (orig, i);
356          break;
357
358        default:
359          abort ();
360        }
361    }
362  return copy;
363}
364
365/* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
366   placed in the result directly, rather than being copied.  */
367
368rtx
369copy_most_rtx (orig, may_share)
370     register rtx orig;
371     register rtx may_share;
372{
373  register rtx copy;
374  register int i, j;
375  register RTX_CODE code;
376  register char *format_ptr;
377
378  if (orig == may_share)
379    return orig;
380
381  code = GET_CODE (orig);
382
383  switch (code)
384    {
385    case REG:
386    case QUEUED:
387    case CONST_INT:
388    case CONST_DOUBLE:
389    case SYMBOL_REF:
390    case CODE_LABEL:
391    case PC:
392    case CC0:
393      return orig;
394    default:
395      break;
396    }
397
398  copy = rtx_alloc (code);
399  PUT_MODE (copy, GET_MODE (orig));
400  copy->in_struct = orig->in_struct;
401  copy->volatil = orig->volatil;
402  copy->unchanging = orig->unchanging;
403  copy->integrated = orig->integrated;
404 
405  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
406
407  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
408    {
409      switch (*format_ptr++)
410        {
411        case 'e':
412          XEXP (copy, i) = XEXP (orig, i);
413          if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
414            XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
415          break;
416
417        case '0':
418        case 'u':
419          XEXP (copy, i) = XEXP (orig, i);
420          break;
421
422        case 'E':
423        case 'V':
424          XVEC (copy, i) = XVEC (orig, i);
425          if (XVEC (orig, i) != NULL)
426            {
427              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
428              for (j = 0; j < XVECLEN (copy, i); j++)
429                XVECEXP (copy, i, j)
430                  = copy_most_rtx (XVECEXP (orig, i, j), may_share);
431            }
432          break;
433
434        case 'w':
435          XWINT (copy, i) = XWINT (orig, i);
436          break;
437
438        case 'n':
439        case 'i':
440          XINT (copy, i) = XINT (orig, i);
441          break;
442
443        case 's':
444        case 'S':
445          XSTR (copy, i) = XSTR (orig, i);
446          break;
447
448        default:
449          abort ();
450        }
451    }
452  return copy;
453}
454
455/* Subroutines of read_rtx.  */
456
457/* Dump code after printing a message.  Used when read_rtx finds
458   invalid data.  */
459
460static void
461dump_and_abort (expected_c, actual_c, infile)
462     int expected_c, actual_c;
463     FILE *infile;
464{
465  int c, i;
466
467  if (expected_c >= 0)
468    fprintf (stderr,
469             "Expected character %c.  Found character %c.",
470             expected_c, actual_c);
471  fprintf (stderr, "  At file position: %ld\n", ftell (infile));
472  fprintf (stderr, "Following characters are:\n\t");
473  for (i = 0; i < 200; i++)
474    {
475      c = getc (infile);
476      if (EOF == c) break;
477      putc (c, stderr);
478    }
479  fprintf (stderr, "Aborting.\n");
480  abort ();
481}
482
483/* Read chars from INFILE until a non-whitespace char
484   and return that.  Comments, both Lisp style and C style,
485   are treated as whitespace.
486   Tools such as genflags use this function.  */
487
488int
489read_skip_spaces (infile)
490     FILE *infile;
491{
492  register int c;
493  while (c = getc (infile))
494    {
495      if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
496        ;
497      else if (c == ';')
498        {
499          while ((c = getc (infile)) && c != '\n') ;
500        }
501      else if (c == '/')
502        {
503          register int prevc;
504          c = getc (infile);
505          if (c != '*')
506            dump_and_abort ('*', c, infile);
507         
508          prevc = 0;
509          while (c = getc (infile))
510            {
511              if (prevc == '*' && c == '/')
512                break;
513              prevc = c;
514            }
515        }
516      else break;
517    }
518  return c;
519}
520
521/* Read an rtx code name into the buffer STR[].
522   It is terminated by any of the punctuation chars of rtx printed syntax.  */
523
524static void
525read_name (str, infile)
526     char *str;
527     FILE *infile;
528{
529  register char *p;
530  register int c;
531
532  c = read_skip_spaces(infile);
533
534  p = str;
535  while (1)
536    {
537      if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
538        break;
539      if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
540          || c == '(' || c == '[')
541        {
542          ungetc (c, infile);
543          break;
544        }
545      *p++ = c;
546      c = getc (infile);
547    }
548  if (p == str)
549    {
550      fprintf (stderr, "missing name or number");
551      dump_and_abort (-1, -1, infile);
552    }
553
554  *p = 0;
555}
556
557/* Read an rtx in printed representation from INFILE
558   and return an actual rtx in core constructed accordingly.
559   read_rtx is not used in the compiler proper, but rather in
560   the utilities gen*.c that construct C code from machine descriptions.  */
561
562rtx
563read_rtx (infile)
564     FILE *infile;
565{
566  register int i, j, list_counter;
567  RTX_CODE tmp_code;
568  register char *format_ptr;
569  /* tmp_char is a buffer used for reading decimal integers
570     and names of rtx types and machine modes.
571     Therefore, 256 must be enough.  */
572  char tmp_char[256];
573  rtx return_rtx;
574  register int c;
575  int tmp_int;
576  HOST_WIDE_INT tmp_wide;
577
578  /* Linked list structure for making RTXs: */
579  struct rtx_list
580    {
581      struct rtx_list *next;
582      rtx value;                /* Value of this node...                */
583    };
584
585  c = read_skip_spaces (infile); /* Should be open paren.  */
586  if (c != '(')
587    dump_and_abort ('(', c, infile);
588
589  read_name (tmp_char, infile);
590
591  tmp_code = UNKNOWN;
592
593  for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
594    {
595      if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
596        {
597          tmp_code = (RTX_CODE) i;      /* get value for name */
598          break;
599        }
600    }
601  if (tmp_code == UNKNOWN)
602    {
603      fprintf (stderr,
604               "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
605               tmp_char);
606    }
607  /* (NIL) stands for an expression that isn't there.  */
608  if (tmp_code == NIL)
609    {
610      /* Discard the closeparen.  */
611      while ((c = getc (infile)) && c != ')');
612      return 0;
613    }
614
615  return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
616                                       then we free this space below.  */
617  format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
618
619  /* If what follows is `: mode ', read it and
620     store the mode in the rtx.  */
621
622  i = read_skip_spaces (infile);
623  if (i == ':')
624    {
625      register int k;
626      read_name (tmp_char, infile);
627      for (k = 0; k < NUM_MACHINE_MODES; k++)
628        if (!strcmp (GET_MODE_NAME (k), tmp_char))
629          break;
630
631      PUT_MODE (return_rtx, (enum machine_mode) k );
632    }
633  else
634    ungetc (i, infile);
635
636  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
637    switch (*format_ptr++)
638      {
639        /* 0 means a field for internal use only.
640           Don't expect it to be present in the input.  */
641      case '0':
642        break;
643
644      case 'e':
645      case 'u':
646        XEXP (return_rtx, i) = read_rtx (infile);
647        break;
648
649      case 'V':
650        /* 'V' is an optional vector: if a closeparen follows,
651           just store NULL for this element.  */
652        c = read_skip_spaces (infile);
653        ungetc (c, infile);
654        if (c == ')')
655          {
656            XVEC (return_rtx, i) = 0;
657            break;
658          }
659        /* Now process the vector.  */
660 
661      case 'E':
662        {
663          register struct rtx_list *next_rtx, *rtx_list_link;
664          struct rtx_list *list_rtx;
665
666          c = read_skip_spaces (infile);
667          if (c != '[')
668            dump_and_abort ('[', c, infile);
669
670          /* add expressions to a list, while keeping a count */
671          next_rtx = NULL;
672          list_counter = 0;
673          while ((c = read_skip_spaces (infile)) && c != ']')
674            {
675              ungetc (c, infile);
676              list_counter++;
677              rtx_list_link = (struct rtx_list *)
678                alloca (sizeof (struct rtx_list));
679              rtx_list_link->value = read_rtx (infile);
680              if (next_rtx == 0)
681                list_rtx = rtx_list_link;
682              else
683                next_rtx->next = rtx_list_link;
684              next_rtx = rtx_list_link;
685              rtx_list_link->next = 0;
686            }
687          /* get vector length and allocate it */
688          XVEC (return_rtx, i) = (list_counter
689                                  ? rtvec_alloc (list_counter) : NULL_RTVEC);
690          if (list_counter > 0)
691            {
692              next_rtx = list_rtx;
693              for (j = 0; j < list_counter; j++,
694                   next_rtx = next_rtx->next)
695                XVECEXP (return_rtx, i, j) = next_rtx->value;
696            }
697          /* close bracket gotten */
698        }
699        break;
700
701      case 'S':
702        /* 'S' is an optional string: if a closeparen follows,
703           just store NULL for this element.  */
704        c = read_skip_spaces (infile);
705        ungetc (c, infile);
706        if (c == ')')
707          {
708            XSTR (return_rtx, i) = 0;
709            break;
710          }
711
712      case 's':
713        {
714          int saw_paren = 0;
715          register char *stringbuf;
716
717          c = read_skip_spaces (infile);
718          if (c == '(')
719            {
720              saw_paren = 1;
721              c = read_skip_spaces (infile);
722            }
723          if (c != '"')
724            dump_and_abort ('"', c, infile);
725
726          while (1)
727            {
728              c = getc (infile); /* Read the string  */
729              if (c == '\\')
730                {
731                  c = getc (infile);    /* Read the string  */
732                  /* \; makes stuff for a C string constant containing
733                     newline and tab.  */
734                  if (c == ';')
735                    {
736                      obstack_grow (rtl_obstack, "\\n\\t", 4);
737                      continue;
738                    }
739                }
740              else if (c == '"')
741                break;
742
743              obstack_1grow (rtl_obstack, c);
744            }
745
746          obstack_1grow (rtl_obstack, 0);
747          stringbuf = (char *) obstack_finish (rtl_obstack);
748
749          if (saw_paren)
750            {
751              c = read_skip_spaces (infile);
752              if (c != ')')
753                dump_and_abort (')', c, infile);
754            }
755          XSTR (return_rtx, i) = stringbuf;
756        }
757        break;
758
759      case 'w':
760        read_name (tmp_char, infile);
761#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
762        tmp_wide = atoi (tmp_char);
763#else
764        tmp_wide = atol (tmp_char);
765#endif
766        XWINT (return_rtx, i) = tmp_wide;
767        break;
768
769      case 'i':
770      case 'n':
771        read_name (tmp_char, infile);
772        tmp_int = atoi (tmp_char);
773        XINT (return_rtx, i) = tmp_int;
774        break;
775
776      default:
777        fprintf (stderr,
778                 "switch format wrong in rtl.read_rtx(). format was: %c.\n",
779                 format_ptr[-1]);
780        fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
781        abort ();
782      }
783
784  c = read_skip_spaces (infile);
785  if (c != ')')
786    dump_and_abort (')', c, infile);
787
788  return return_rtx;
789}
790
791/* This is called once per compilation, before any rtx's are constructed.
792   It initializes the vector `rtx_length', the extra CC modes, if any,
793   and computes certain commonly-used modes.  */
794
795void
796init_rtl ()
797{
798  int min_class_size[(int) MAX_MODE_CLASS];
799  enum machine_mode mode;
800  int i;
801
802  for (i = 0; i < NUM_RTX_CODE; i++)
803    rtx_length[i] = strlen (rtx_format[i]);
804
805  /* Make CONST_DOUBLE bigger, if real values are bigger than
806     it normally expects to have room for.
807     Note that REAL_VALUE_TYPE is not defined by default,
808     since tree.h is not included.  But the default dfn as `double'
809     would do no harm.  */
810#ifdef REAL_VALUE_TYPE
811  i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
812  if (rtx_length[(int) CONST_DOUBLE] < i)
813    {
814      char *s = (char *) xmalloc (i + 1);
815      rtx_length[(int) CONST_DOUBLE] = i;
816      rtx_format[(int) CONST_DOUBLE] = s;
817      *s++ = 'e';
818      *s++ = '0';
819      /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
820         of as many `w's as we now have elements.  Subtract two from
821         the size to account for the 'e' and the '0'.  */
822      for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
823        *s++ = 'w';
824      *s++ = 0;
825    }
826#endif
827
828#ifdef EXTRA_CC_MODES
829  for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
830    {
831      mode_class[i] = MODE_CC;
832      mode_size[i] = mode_size[(int) CCmode];
833      mode_unit_size[i] = mode_unit_size[(int) CCmode];
834      mode_wider_mode[i - 1] = (enum machine_mode) i;
835      mode_wider_mode[i] = VOIDmode;
836    }
837#endif
838
839  /* Find the narrowest mode for each class.  */
840
841  for (i = 0; i < (int) MAX_MODE_CLASS; i++)
842    min_class_size[i] = 1000;
843
844  for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
845       mode = (enum machine_mode) ((int) mode + 1))
846    {
847      if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
848        {
849          class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
850          min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
851        }
852    }
853}
Note: See TracBrowser for help on using the repository browser.