OSDN Git Service

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