OSDN Git Service

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