OSDN Git Service

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