OSDN Git Service

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