OSDN Git Service

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