OSDN Git Service

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