OSDN Git Service

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