OSDN Git Service

* gengenrtl.c (CONST_DOUBLE_FORMAT): Take the size REAL_ARITHMETIC
[pf3gnuchains/gcc-fork.git] / gcc / rtl.c
1 /* Allocate and read RTL for GNU C Compiler.
2    Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "real.h"
27 #include "bitmap.h"
28 #include "ggc.h"
29 #include "obstack.h"
30 #define obstack_chunk_alloc     xmalloc
31 #define obstack_chunk_free      free
32
33 #ifndef DIR_SEPARATOR
34 #define DIR_SEPARATOR '/'
35 #endif
36
37 /* Obstack used for allocating RTL objects.
38    Between functions, this is the permanent_obstack.
39    While parsing and expanding a function, this is maybepermanent_obstack
40    so we can save it if it is an inline function.
41    During optimization and output, this is function_obstack.  */
42
43 extern struct obstack *rtl_obstack;
44 \f
45 /* Calculate the format for CONST_DOUBLE.  This depends on the relative
46    widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
47
48    We need to go out to e0wwwww, since REAL_ARITHMETIC assumes 16-bits
49    per element in REAL_VALUE_TYPE.
50
51    This is duplicated in gengenrtl.c.
52
53    A number of places assume that there are always at least two 'w'
54    slots in a CONST_DOUBLE, so we provide them even if one would suffice.  */
55
56 #ifdef REAL_ARITHMETIC
57 #if LONG_DOUBLE_TYPE_SIZE == 96
58 #define REAL_WIDTH      (11*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
59 #elif LONG_DOUBLE_TYPE_SIZE == 128
60 #define REAL_WIDTH      (19*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
61 #elif HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
62 #define REAL_WIDTH      (7*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
63 #endif
64 #endif /* REAL_ARITHMETIC */
65
66 #ifndef REAL_WIDTH
67 #if HOST_BITS_PER_WIDE_INT*2 >= LONG_DOUBLE_TYPE_SIZE
68 #define REAL_WIDTH      2
69 #elif HOST_BITS_PER_WIDE_INT*3 >= LONG_DOUBLE_TYPE_SIZE
70 #define REAL_WIDTH      3
71 #elif HOST_BITS_PER_WIDE_INT*4 >= LONG_DOUBLE_TYPE_SIZE
72 #define REAL_WIDTH      4
73 #endif
74 #endif /* REAL_WIDTH */
75
76 #if REAL_WIDTH == 1
77 #define CONST_DOUBLE_FORMAT     "e0ww"
78 #elif REAL_WIDTH == 2
79 #define CONST_DOUBLE_FORMAT     "e0ww"
80 #elif REAL_WIDTH == 3
81 #define CONST_DOUBLE_FORMAT     "e0www"
82 #elif REAL_WIDTH == 4
83 #define CONST_DOUBLE_FORMAT     "e0wwww"
84 #elif REAL_WIDTH == 5
85 #define CONST_DOUBLE_FORMAT     "e0wwwww"
86 #else
87 #define CONST_DOUBLE_FORMAT     /* nothing - will cause syntax error */
88 #endif
89
90 /* Indexed by rtx code, gives number of operands for an rtx with that code.
91    Does NOT include rtx header data (code and links).  */
92
93 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   sizeof FORMAT - 1 ,
94
95 const int rtx_length[NUM_RTX_CODE + 1] = {
96 #include "rtl.def"
97 };
98
99 #undef DEF_RTL_EXPR
100
101 /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
102
103 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
104
105 const char * const rtx_name[] = {
106 #include "rtl.def"              /* rtl expressions are documented here */
107 };
108
109 #undef DEF_RTL_EXPR
110
111 /* Indexed by machine mode, gives the name of that machine mode.
112    This name does not include the letters "mode".  */
113
114 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  NAME,
115
116 const char * const mode_name[(int) MAX_MACHINE_MODE + 1] = {
117 #include "machmode.def"
118   /* Add an extra field to avoid a core dump if someone tries to convert
119      MAX_MACHINE_MODE to a string.   */
120   ""
121 };
122
123 #undef DEF_MACHMODE
124
125 /* Indexed by machine mode, gives the length of the mode, in bytes.
126    GET_MODE_CLASS uses this.  */
127
128 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  CLASS,
129
130 const enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
131 #include "machmode.def"
132 };
133
134 #undef DEF_MACHMODE
135
136 /* Indexed by machine mode, gives the length of the mode, in bytes.
137    GET_MODE_SIZE uses this.  */
138
139 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  SIZE,
140
141 const int mode_size[(int) MAX_MACHINE_MODE] = {
142 #include "machmode.def"
143 };
144
145 #undef DEF_MACHMODE
146
147 /* Indexed by machine mode, gives the length of the mode's subunit.
148    GET_MODE_UNIT_SIZE uses this.  */
149
150 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  UNIT,
151
152 const int mode_unit_size[(int) MAX_MACHINE_MODE] = {
153 #include "machmode.def"         /* machine modes are documented here */
154 };
155
156 #undef DEF_MACHMODE
157
158 /* Indexed by machine mode, gives next wider natural mode
159    (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
160    use this.  */
161
162 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
163   (unsigned char) WIDER,
164
165 const unsigned char mode_wider_mode[(int) MAX_MACHINE_MODE] = {
166 #include "machmode.def"         /* machine modes are documented here */
167 };
168
169 #undef DEF_MACHMODE
170
171 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
172   ((SIZE) * BITS_PER_UNIT >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT)0 : ((unsigned HOST_WIDE_INT) 1 << (SIZE) * BITS_PER_UNIT) - 1,
173
174 /* Indexed by machine mode, gives mask of significant bits in mode.  */
175
176 const unsigned HOST_WIDE_INT mode_mask_array[(int) MAX_MACHINE_MODE] = {
177 #include "machmode.def"
178 };
179
180 /* Indexed by mode class, gives the narrowest mode for each class.
181    The Q modes are always of width 1 (2 for complex) - it is impossible
182    for any mode to be narrower.  */
183
184 const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = {
185     /* MODE_RANDOM */           VOIDmode,
186     /* MODE_INT */              QImode,
187     /* MODE_FLOAT */            QFmode,
188     /* MODE_PARTIAL_INT */      PQImode,
189     /* MODE_CC */               CCmode,
190     /* MODE_COMPLEX_INT */      CQImode,
191     /* MODE_COMPLEX_FLOAT */    QCmode
192 };
193                         
194
195 /* Indexed by rtx code, gives a sequence of operand-types for
196    rtx's of that code.  The sequence is a C string in which
197    each character describes one operand.  */
198
199 const char * const rtx_format[] = {
200   /* "*" undefined.
201          can cause a warning message
202      "0" field is unused (or used in a phase-dependent manner)
203          prints nothing
204      "i" an integer
205          prints the integer
206      "n" like "i", but prints entries from `note_insn_name'
207      "w" an integer of width HOST_BITS_PER_WIDE_INT
208          prints the integer
209      "s" a pointer to a string
210          prints the string
211      "S" like "s", but optional:
212          the containing rtx may end before this operand
213      "e" a pointer to an rtl expression
214          prints the expression
215      "E" a pointer to a vector that points to a number of rtl expressions
216          prints a list of the rtl expressions
217      "V" like "E", but optional:
218          the containing rtx may end before this operand
219      "u" a pointer to another insn
220          prints the uid of the insn.
221      "b" is a pointer to a bitmap header.
222      "t" is a tree pointer. */
223
224 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
225 #include "rtl.def"              /* rtl expressions are defined here */
226 #undef DEF_RTL_EXPR
227 };
228
229 /* Indexed by rtx code, gives a character representing the "class" of
230    that rtx code.  See rtl.def for documentation on the defined classes.  */
231
232 const char rtx_class[] = {
233 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS, 
234 #include "rtl.def"              /* rtl expressions are defined here */
235 #undef DEF_RTL_EXPR
236 };
237
238 /* Names for kinds of NOTEs and REG_NOTEs.  */
239
240 const char * const note_insn_name[] = { 0       , "NOTE_INSN_DELETED",
241                            "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
242                            "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
243                            "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
244                            "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
245                            "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
246                            "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
247                            "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
248                            "NOTE_REPEATED_LINE_NUMBER", "NOTE_INSN_RANGE_START",
249                            "NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE",
250                            "NOTE_INSN_BASIC_BLOCK" };
251
252 const char * const reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
253                           "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
254                           "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
255                           "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
256                           "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
257                           "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
258                           "REG_BR_PRED", "REG_EH_CONTEXT",
259                           "REG_FRAME_RELATED_EXPR", "REG_EH_REGION",
260                           "REG_EH_RETHROW" };
261
262 static void dump_and_abort      PROTO((int, int, FILE *)) ATTRIBUTE_NORETURN;
263 static void read_name           PROTO((char *, FILE *));
264 \f
265 /* Allocate an rtx vector of N elements.
266    Store the length, and initialize all elements to zero.  */
267
268 rtvec
269 rtvec_alloc (n)
270      int n;
271 {
272   rtvec rt;
273  
274   if (ggc_p)
275     rt = ggc_alloc_rtvec (n);
276   else
277     {
278       int i;
279
280       rt = (rtvec) obstack_alloc (rtl_obstack,
281                                   sizeof (struct rtvec_def)
282                                   + (( n - 1) * sizeof (rtx)));
283
284       /* clear out the vector */
285       for (i = 0; i < n; i++)
286         rt->elem[i] = 0;
287     }
288
289   PUT_NUM_ELEM (rt, n);
290   return rt;
291 }
292
293 /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
294    all the rest is initialized to zero.  */
295
296 rtx
297 rtx_alloc (code)
298   RTX_CODE code;
299 {
300   rtx rt;
301
302   if (ggc_p)
303     rt = ggc_alloc_rtx (GET_RTX_LENGTH (code));
304   else
305     {
306       register struct obstack *ob = rtl_obstack;
307       register int nelts = GET_RTX_LENGTH (code);
308       register int length = sizeof (struct rtx_def)
309         + (nelts - 1) * sizeof (rtunion);
310
311       /* This function is called more than any other in GCC, so we
312          manipulate the obstack directly.
313        
314          Even though rtx objects are word aligned, we may be sharing
315          an obstack with tree nodes, which may have to be double-word
316          aligned.  So align our length to the alignment mask in the
317          obstack.  */
318
319       length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
320
321       if (ob->chunk_limit - ob->next_free < length)
322         _obstack_newchunk (ob, length);
323       rt = (rtx)ob->object_base;
324       ob->next_free += length;
325       ob->object_base = ob->next_free;
326
327       /* We want to clear everything up to the FLD array.  Normally,
328          this is one int, but we don't want to assume that and it
329          isn't very portable anyway; this is.  */
330
331       memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
332     }
333
334   PUT_CODE (rt, code);
335   return rt;
336 }
337
338 /* Like the above, but allocate based only on the length.  This is called
339    by the routines built into genrtl.c.  */
340
341 rtx
342 obstack_alloc_rtx (length)
343      int length;
344 {
345   rtx rt;
346   register struct obstack *ob = rtl_obstack;
347
348   /* This function is called more than any other in GCC,
349      so we manipulate the obstack directly.
350
351      Even though rtx objects are word aligned, we may be sharing an obstack
352      with tree nodes, which may have to be double-word aligned.  So align
353      our length to the alignment mask in the obstack.  */
354
355   length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
356
357   if (ob->chunk_limit - ob->next_free < length)
358     _obstack_newchunk (ob, length);
359
360   rt = (rtx) ob->object_base;
361   ob->next_free += length;
362   ob->object_base = ob->next_free;
363
364   /* We want to clear everything up to the FLD array.  Normally,
365      this is one int, but we don't want to assume that and it
366      isn't very portable anyway; this is.  */
367
368   memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
369
370   return rt;
371 }
372
373 /* Free the rtx X and all RTL allocated since X.  */
374
375 void
376 rtx_free (x)
377      rtx x;
378 {
379   if (!ggc_p)
380     obstack_free (rtl_obstack, x);
381 }
382 \f
383 /* Create a new copy of an rtx.
384    Recursively copies the operands of the rtx,
385    except for those few rtx codes that are sharable.  */
386
387 rtx
388 copy_rtx (orig)
389      register rtx orig;
390 {
391   register rtx copy;
392   register int i, j;
393   register RTX_CODE code;
394   register const char *format_ptr;
395
396   code = GET_CODE (orig);
397
398   switch (code)
399     {
400     case REG:
401     case QUEUED:
402     case CONST_INT:
403     case CONST_DOUBLE:
404     case SYMBOL_REF:
405     case CODE_LABEL:
406     case PC:
407     case CC0:
408     case SCRATCH:
409       /* SCRATCH must be shared because they represent distinct values.  */
410     case ADDRESSOF:
411       return orig;
412
413     case CONST:
414       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
415          a LABEL_REF, it isn't sharable.  */
416       if (GET_CODE (XEXP (orig, 0)) == PLUS
417           && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
418           && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
419         return orig;
420       break;
421
422       /* A MEM with a constant address is not sharable.  The problem is that
423          the constant address may need to be reloaded.  If the mem is shared,
424          then reloading one copy of this mem will cause all copies to appear
425          to have been reloaded.  */
426
427     default:
428       break;
429     }
430
431   copy = rtx_alloc (code);
432
433   /* Copy the various flags, and other information.  We assume that
434      all fields need copying, and then clear the fields that should
435      not be copied.  That is the sensible default behavior, and forces
436      us to explicitly document why we are *not* copying a flag.  */
437   memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
438
439   /* We do not copy the USED flag, which is used as a mark bit during
440      walks over the RTL.  */
441   copy->used = 0;
442
443   /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs.  */
444   if (GET_RTX_CLASS (code) == 'i')
445     {
446       copy->jump = 0;
447       copy->call = 0;
448       copy->frame_related = 0;
449     }
450   
451   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
452
453   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
454     {
455       switch (*format_ptr++)
456         {
457         case 'e':
458           XEXP (copy, i) = XEXP (orig, i);
459           if (XEXP (orig, i) != NULL)
460             XEXP (copy, i) = copy_rtx (XEXP (orig, i));
461           break;
462
463         case 'u':
464           XEXP (copy, i) = XEXP (orig, i);
465           break;
466
467         case 'E':
468         case 'V':
469           XVEC (copy, i) = XVEC (orig, i);
470           if (XVEC (orig, i) != NULL)
471             {
472               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
473               for (j = 0; j < XVECLEN (copy, i); j++)
474                 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
475             }
476           break;
477
478         case 'b':
479           {
480             bitmap new_bits = BITMAP_OBSTACK_ALLOC (rtl_obstack);
481             bitmap_copy (new_bits, XBITMAP (orig, i));
482             XBITMAP (copy, i) = new_bits;
483             break;
484           }
485
486         case 't':
487           XTREE (copy, i) = XTREE (orig, i);
488           break;
489
490         case 'w':
491           XWINT (copy, i) = XWINT (orig, i);
492           break;
493
494         case 'i':
495           XINT (copy, i) = XINT (orig, i);
496           break;
497
498         case 's':
499         case 'S':
500           XSTR (copy, i) = XSTR (orig, i);
501           break;
502
503         case '0':
504           /* Copy this through the wide int field; that's safest. */
505           X0WINT (copy, i) = X0WINT (orig, i);
506           break;
507           
508         default:
509           abort ();
510         }
511     }
512   return copy;
513 }
514
515 /* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
516    placed in the result directly, rather than being copied.  */
517
518 rtx
519 copy_most_rtx (orig, may_share)
520      register rtx orig;
521      register rtx may_share;
522 {
523   register rtx copy;
524   register int i, j;
525   register RTX_CODE code;
526   register const char *format_ptr;
527
528   if (orig == may_share)
529     return orig;
530
531   code = GET_CODE (orig);
532
533   switch (code)
534     {
535     case REG:
536     case QUEUED:
537     case CONST_INT:
538     case CONST_DOUBLE:
539     case SYMBOL_REF:
540     case CODE_LABEL:
541     case PC:
542     case CC0:
543       return orig;
544     default:
545       break;
546     }
547
548   copy = rtx_alloc (code);
549   PUT_MODE (copy, GET_MODE (orig));
550   copy->in_struct = orig->in_struct;
551   copy->volatil = orig->volatil;
552   copy->unchanging = orig->unchanging;
553   copy->integrated = orig->integrated;
554   
555   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
556
557   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
558     {
559       switch (*format_ptr++)
560         {
561         case 'e':
562           XEXP (copy, i) = XEXP (orig, i);
563           if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
564             XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
565           break;
566
567         case 'u':
568           XEXP (copy, i) = XEXP (orig, i);
569           break;
570
571         case 'E':
572         case 'V':
573           XVEC (copy, i) = XVEC (orig, i);
574           if (XVEC (orig, i) != NULL)
575             {
576               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
577               for (j = 0; j < XVECLEN (copy, i); j++)
578                 XVECEXP (copy, i, j)
579                   = copy_most_rtx (XVECEXP (orig, i, j), may_share);
580             }
581           break;
582
583         case 'w':
584           XWINT (copy, i) = XWINT (orig, i);
585           break;
586
587         case 'n':
588         case 'i':
589           XINT (copy, i) = XINT (orig, i);
590           break;
591
592         case 't':
593           XTREE (copy, i) = XTREE (orig, i);
594           break;
595
596         case 's':
597         case 'S':
598           XSTR (copy, i) = XSTR (orig, i);
599           break;
600
601         case '0':
602           /* Copy this through the wide int field; that's safest. */
603           X0WINT (copy, i) = X0WINT (orig, i);
604           break;
605
606         default:
607           abort ();
608         }
609     }
610   return copy;
611 }
612
613 /* Create a new copy of an rtx.  Only copy just one level.  */
614 rtx
615 shallow_copy_rtx (orig)
616      rtx orig;
617 {
618   register int i;
619   register RTX_CODE code = GET_CODE (orig);
620   register rtx copy = rtx_alloc (code);
621
622   PUT_MODE (copy, GET_MODE (orig));
623   copy->in_struct = orig->in_struct;
624   copy->volatil = orig->volatil;
625   copy->unchanging = orig->unchanging;
626   copy->integrated = orig->integrated;
627
628   for (i = 0; i < GET_RTX_LENGTH (code); i++)
629     copy->fld[i] = orig->fld[i];
630
631   return copy;
632 }
633 \f
634 /* Subroutines of read_rtx.  */
635
636 /* Dump code after printing a message.  Used when read_rtx finds
637    invalid data.  */
638
639 static void
640 dump_and_abort (expected_c, actual_c, infile)
641      int expected_c, actual_c;
642      FILE *infile;
643 {
644   int c, i;
645
646   if (expected_c >= 0)
647     fprintf (stderr,
648              "Expected character %c.  Found character %c.",
649              expected_c, actual_c);
650   fprintf (stderr, "  At file position: %ld\n", ftell (infile));
651   fprintf (stderr, "Following characters are:\n\t");
652   for (i = 0; i < 200; i++)
653     {
654       c = getc (infile);
655       if (EOF == c) break;
656       putc (c, stderr);
657     }
658   fprintf (stderr, "Aborting.\n");
659   abort ();
660 }
661
662 /* Read chars from INFILE until a non-whitespace char
663    and return that.  Comments, both Lisp style and C style,
664    are treated as whitespace.
665    Tools such as genflags use this function.  */
666
667 int
668 read_skip_spaces (infile)
669      FILE *infile;
670 {
671   register int c;
672   while ((c = getc (infile)))
673     {
674       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
675         ;
676       else if (c == ';')
677         {
678           while ((c = getc (infile)) && c != '\n' && c != EOF)
679             ;
680         }
681       else if (c == '/')
682         {
683           register int prevc;
684           c = getc (infile);
685           if (c != '*')
686             dump_and_abort ('*', c, infile);
687           
688           prevc = 0;
689           while ((c = getc (infile)) && c != EOF)
690             {
691               if (prevc == '*' && c == '/')
692                 break;
693               prevc = c;
694             }
695         }
696       else break;
697     }
698   return c;
699 }
700
701 /* Read an rtx code name into the buffer STR[].
702    It is terminated by any of the punctuation chars of rtx printed syntax.  */
703
704 static void
705 read_name (str, infile)
706      char *str;
707      FILE *infile;
708 {
709   register char *p;
710   register int c;
711
712   c = read_skip_spaces(infile);
713
714   p = str;
715   while (1)
716     {
717       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
718         break;
719       if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
720           || c == '(' || c == '[')
721         {
722           ungetc (c, infile);
723           break;
724         }
725       *p++ = c;
726       c = getc (infile);
727     }
728   if (p == str)
729     {
730       fprintf (stderr, "missing name or number");
731       dump_and_abort (-1, -1, infile);
732     }
733
734   *p = 0;
735 }
736 \f
737 /* Provide a version of a function to read a long long if the system does
738    not provide one.  */
739 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
740 HOST_WIDE_INT
741 atoll(p)
742     const char *p;
743 {
744   int neg = 0;
745   HOST_WIDE_INT tmp_wide;
746
747   while (ISSPACE(*p))
748     p++;
749   if (*p == '-')
750     neg = 1, p++;
751   else if (*p == '+')
752     p++;
753
754   tmp_wide = 0;
755   while (ISDIGIT(*p))
756     {
757       HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
758       if (new_wide < tmp_wide)
759         {
760           /* Return INT_MAX equiv on overflow.  */
761           tmp_wide = (~(unsigned HOST_WIDE_INT)0) >> 1;
762           break;
763         }
764       tmp_wide = new_wide;
765       p++;
766     }
767
768   if (neg)
769     tmp_wide = -tmp_wide;
770   return tmp_wide;
771 }
772 #endif
773
774 /* Read an rtx in printed representation from INFILE
775    and return an actual rtx in core constructed accordingly.
776    read_rtx is not used in the compiler proper, but rather in
777    the utilities gen*.c that construct C code from machine descriptions.  */
778
779 rtx
780 read_rtx (infile)
781      FILE *infile;
782 {
783   register int i, j, list_counter;
784   RTX_CODE tmp_code;
785   register const char *format_ptr;
786   /* tmp_char is a buffer used for reading decimal integers
787      and names of rtx types and machine modes.
788      Therefore, 256 must be enough.  */
789   char tmp_char[256];
790   rtx return_rtx;
791   register int c;
792   int tmp_int;
793   HOST_WIDE_INT tmp_wide;
794
795   /* Linked list structure for making RTXs: */
796   struct rtx_list
797     {
798       struct rtx_list *next;
799       rtx value;                /* Value of this node...                */
800     };
801
802   c = read_skip_spaces (infile); /* Should be open paren.  */
803   if (c != '(')
804     dump_and_abort ('(', c, infile);
805
806   read_name (tmp_char, infile);
807
808   tmp_code = UNKNOWN;
809
810   for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
811     {
812       if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
813         {
814           tmp_code = (RTX_CODE) i;      /* get value for name */
815           break;
816         }
817     }
818   if (tmp_code == UNKNOWN)
819     {
820       fprintf (stderr,
821                "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
822                tmp_char);
823     }
824   /* (NIL) stands for an expression that isn't there.  */
825   if (tmp_code == NIL)
826     {
827       /* Discard the closeparen.  */
828       while ((c = getc (infile)) && c != ')');
829       return 0;
830     }
831
832   return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
833                                        then we free this space below.  */
834   format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
835
836   /* If what follows is `: mode ', read it and
837      store the mode in the rtx.  */
838
839   i = read_skip_spaces (infile);
840   if (i == ':')
841     {
842       register int k;
843       read_name (tmp_char, infile);
844       for (k = 0; k < NUM_MACHINE_MODES; k++)
845         if (!strcmp (GET_MODE_NAME (k), tmp_char))
846           break;
847
848       PUT_MODE (return_rtx, (enum machine_mode) k );
849     }
850   else
851     ungetc (i, infile);
852
853   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
854     switch (*format_ptr++)
855       {
856         /* 0 means a field for internal use only.
857            Don't expect it to be present in the input.  */
858       case '0':
859         break;
860
861       case 'e':
862       case 'u':
863         XEXP (return_rtx, i) = read_rtx (infile);
864         break;
865
866       case 'V':
867         /* 'V' is an optional vector: if a closeparen follows,
868            just store NULL for this element.  */
869         c = read_skip_spaces (infile);
870         ungetc (c, infile);
871         if (c == ')')
872           {
873             XVEC (return_rtx, i) = 0;
874             break;
875           }
876         /* Now process the vector.  */
877   
878       case 'E':
879         {
880           register struct rtx_list *next_rtx, *rtx_list_link;
881           struct rtx_list *list_rtx = NULL;
882
883           c = read_skip_spaces (infile);
884           if (c != '[')
885             dump_and_abort ('[', c, infile);
886
887           /* add expressions to a list, while keeping a count */
888           next_rtx = NULL;
889           list_counter = 0;
890           while ((c = read_skip_spaces (infile)) && c != ']')
891             {
892               ungetc (c, infile);
893               list_counter++;
894               rtx_list_link = (struct rtx_list *)
895                 alloca (sizeof (struct rtx_list));
896               rtx_list_link->value = read_rtx (infile);
897               if (next_rtx == 0)
898                 list_rtx = rtx_list_link;
899               else
900                 next_rtx->next = rtx_list_link;
901               next_rtx = rtx_list_link;
902               rtx_list_link->next = 0;
903             }
904           /* get vector length and allocate it */
905           XVEC (return_rtx, i) = (list_counter
906                                   ? rtvec_alloc (list_counter) : NULL_RTVEC);
907           if (list_counter > 0)
908             {
909               next_rtx = list_rtx;
910               for (j = 0; j < list_counter; j++,
911                    next_rtx = next_rtx->next)
912                 XVECEXP (return_rtx, i, j) = next_rtx->value;
913             }
914           /* close bracket gotten */
915         }
916         break;
917
918       case 'S':
919         /* 'S' is an optional string: if a closeparen follows,
920            just store NULL for this element.  */
921         c = read_skip_spaces (infile);
922         ungetc (c, infile);
923         if (c == ')')
924           {
925             XSTR (return_rtx, i) = 0;
926             break;
927           }
928
929       case 's':
930         {
931           int saw_paren = 0;
932           register char *stringbuf;
933
934           c = read_skip_spaces (infile);
935           if (c == '(')
936             {
937               saw_paren = 1;
938               c = read_skip_spaces (infile);
939             }
940           if (c != '"')
941             dump_and_abort ('"', c, infile);
942
943           while (1)
944             {
945               c = getc (infile); /* Read the string  */
946               if (c == '\\')
947                 {
948                   c = getc (infile);    /* Read the string  */
949                   /* \; makes stuff for a C string constant containing
950                      newline and tab.  */
951                   if (c == ';')
952                     {
953                       obstack_grow (rtl_obstack, "\\n\\t", 4);
954                       continue;
955                     }
956                 }
957               else if (c == '"')
958                 break;
959
960               obstack_1grow (rtl_obstack, c);
961             }
962
963           obstack_1grow (rtl_obstack, 0);
964           stringbuf = (char *) obstack_finish (rtl_obstack);
965
966           if (saw_paren)
967             {
968               c = read_skip_spaces (infile);
969               if (c != ')')
970                 dump_and_abort (')', c, infile);
971             }
972           XSTR (return_rtx, i) = stringbuf;
973         }
974         break;
975
976       case 'w':
977         read_name (tmp_char, infile);
978 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
979         tmp_wide = atoi (tmp_char);
980 #else
981 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
982         tmp_wide = atol (tmp_char);
983 #else
984         /* Prefer atoll over atoq, since the former is in the ISO C9X draft. 
985            But prefer not to use our hand-rolled function above either.  */
986 #if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
987         tmp_wide = atoll (tmp_char);
988 #else
989         tmp_wide = atoq (tmp_char);
990 #endif
991 #endif
992 #endif
993         XWINT (return_rtx, i) = tmp_wide;
994         break;
995
996       case 'i':
997       case 'n':
998         read_name (tmp_char, infile);
999         tmp_int = atoi (tmp_char);
1000         XINT (return_rtx, i) = tmp_int;
1001         break;
1002
1003       default:
1004         fprintf (stderr,
1005                  "switch format wrong in rtl.read_rtx(). format was: %c.\n",
1006                  format_ptr[-1]);
1007         fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
1008         abort ();
1009       }
1010
1011   c = read_skip_spaces (infile);
1012   if (c != ')')
1013     dump_and_abort (')', c, infile);
1014
1015   return return_rtx;
1016 }
1017
1018 #if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6)
1019 void
1020 rtl_check_failed_bounds (r, n, file, line, func)
1021     rtx r;
1022     int n;
1023     const char *file;
1024     int line;
1025     const char *func;
1026 {
1027   error ("RTL check: access of elt %d of `%s' with last elt %d",
1028          n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r))-1);
1029   fancy_abort (file, line, func);
1030 }
1031
1032 void
1033 rtl_check_failed_type1 (r, n, c1, file, line, func)
1034     rtx r;
1035     int n;
1036     int c1;
1037     const char *file;
1038     int line;
1039     const char *func;
1040 {
1041   error ("RTL check: expected elt %d type '%c', have '%c' (rtx %s)",
1042          n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)));
1043   fancy_abort (file, line, func);
1044 }
1045
1046 void
1047 rtl_check_failed_type2 (r, n, c1, c2, file, line, func)
1048     rtx r;
1049     int n;
1050     int c1;
1051     int c2;
1052     const char *file;
1053     int line;
1054     const char *func;
1055 {
1056   error ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s)",
1057          n, c1, c2,
1058          GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE(r)));
1059   fancy_abort (file, line, func);
1060 }
1061
1062 void
1063 rtl_check_failed_code1 (r, code, file, line, func)
1064     rtx r;
1065     enum rtx_code code;
1066     const char *file;
1067     int line;
1068     const char *func;
1069 {
1070   error ("RTL check: expected code `%s', have `%s'",
1071          GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)));
1072   fancy_abort (file, line, func);
1073 }
1074
1075 void
1076 rtl_check_failed_code2 (r, code1, code2, file, line, func)
1077     rtx r;
1078     enum rtx_code code1, code2;
1079     const char *file;
1080     int line;
1081     const char *func;
1082 {
1083   error ("RTL check: expected code `%s' or `%s', have `%s'",
1084          GET_RTX_NAME (code1), GET_RTX_NAME (code2),
1085          GET_RTX_NAME (GET_CODE (r)));
1086   fancy_abort (file, line, func);
1087 }
1088
1089 /* XXX Maybe print the vector?  */
1090 void
1091 rtvec_check_failed_bounds (r, n, file, line, func)
1092     rtvec r;
1093     int n;
1094     const char *file;
1095     int line;
1096     const char *func;
1097 {
1098   error ("RTL check: access of elt %d of vector with last elt %d",
1099          n, GET_NUM_ELEM (r)-1);
1100   fancy_abort (file, line, func);
1101 }
1102 #endif /* ENABLE_CHECKING */
1103
1104 /* These are utility functions used by fatal-error functions all over the
1105    code.  rtl.c happens to be linked by all the programs that need them,
1106    so these are here.  In the future we want to break out all error handling
1107    to its own module.  */
1108
1109 /* Given a partial pathname as input, return another pathname that
1110    shares no directory elements with the pathname of __FILE__.  This
1111    is used by fancy_abort() to print `Internal compiler error in expr.c'
1112    instead of `Internal compiler error in ../../egcs/gcc/expr.c'.  */
1113 static const char *
1114 trim_filename (name)
1115      const char *name;
1116 {
1117   static const char this_file[] = __FILE__;
1118   const char *p = name, *q = this_file;
1119
1120   while (*p == *q && *p != 0 && *q != 0) p++, q++;
1121   while (p > name && p[-1] != DIR_SEPARATOR
1122 #ifdef DIR_SEPARATOR_2
1123          && p[-1] != DIR_SEPARATOR_2
1124 #endif
1125          )
1126     p--;
1127
1128   return p;
1129 }
1130
1131 /* Report an internal compiler error in a friendly manner and without
1132    dumping core.  */
1133
1134 extern void fatal PVPROTO ((const char *, ...))
1135   ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
1136
1137 void
1138 fancy_abort (file, line, function)
1139      const char *file;
1140      int line;
1141      const char *function;
1142 {
1143   if (function == NULL)
1144     function = "?";
1145   fatal (
1146 "Internal compiler error in `%s', at %s:%d\n\
1147 Please submit a full bug report.\n\
1148 See <URL:http://www.gnu.org/software/gcc/faq.html#bugreport> \
1149 for instructions.",
1150          function, trim_filename (file), line);
1151 }