OSDN Git Service

2002-09-10 Frank Ch. Eigler <fche@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / read-rtl.c
1 /* RTL reader for GNU C Compiler.
2    Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "hconfig.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "obstack.h"
26 #include "hashtab.h"
27
28 static htab_t md_constants;
29
30 static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
31   ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
32 static void fatal_expected_char PARAMS ((FILE *, int, int)) ATTRIBUTE_NORETURN;
33 static void read_name           PARAMS ((char *, FILE *));
34 static char *read_string        PARAMS ((struct obstack *, FILE *, int));
35 static char *read_quoted_string PARAMS ((struct obstack *, FILE *));
36 static char *read_braced_string PARAMS ((struct obstack *, FILE *));
37 static void read_escape         PARAMS ((struct obstack *, FILE *));
38 static unsigned def_hash PARAMS ((const void *));
39 static int def_name_eq_p PARAMS ((const void *, const void *));
40 static void read_constants PARAMS ((FILE *infile, char *tmp_char));
41 static void validate_const_int PARAMS ((FILE *, const char *));
42
43 /* Subroutines of read_rtx.  */
44
45 /* The current line number for the file.  */
46 int read_rtx_lineno = 1;
47
48 /* The filename for aborting with file and line.  */
49 const char *read_rtx_filename = "<unknown>";
50
51 static void
52 fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
53 {
54   char context[64];
55   size_t i;
56   int c;
57
58   VA_OPEN (ap, msg);
59   VA_FIXEDARG (ap, FILE *, infile);
60   VA_FIXEDARG (ap, const char *, msg);
61
62   fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
63   vfprintf (stderr, msg, ap);
64   putc ('\n', stderr);
65
66   /* Gather some following context.  */
67   for (i = 0; i < sizeof (context)-1; ++i)
68     {
69       c = getc (infile);
70       if (c == EOF)
71         break;
72       if (c == '\r' || c == '\n')
73         break;
74       context[i] = c;
75     }
76   context[i] = '\0';
77
78   fprintf (stderr, "%s:%d: following context is `%s'\n",
79            read_rtx_filename, read_rtx_lineno, context);
80
81   VA_CLOSE (ap);
82   exit (1);
83 }
84
85 /* Dump code after printing a message.  Used when read_rtx finds
86    invalid data.  */
87
88 static void
89 fatal_expected_char (infile, expected_c, actual_c)
90      FILE *infile;
91      int expected_c, actual_c;
92 {
93   fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
94                             expected_c, actual_c);
95 }
96
97 /* Read chars from INFILE until a non-whitespace char
98    and return that.  Comments, both Lisp style and C style,
99    are treated as whitespace.
100    Tools such as genflags use this function.  */
101
102 int
103 read_skip_spaces (infile)
104      FILE *infile;
105 {
106   int c;
107
108   while (1)
109     {
110       c = getc (infile);
111       switch (c)
112         {
113         case '\n':
114           read_rtx_lineno++;
115           break;
116
117         case ' ': case '\t': case '\f': case '\r':
118           break;
119
120         case ';':
121           do
122             c = getc (infile);
123           while (c != '\n' && c != EOF);
124           read_rtx_lineno++;
125           break;
126
127         case '/':
128           {
129             int prevc;
130             c = getc (infile);
131             if (c != '*')
132               fatal_expected_char (infile, '*', c);
133
134             prevc = 0;
135             while ((c = getc (infile)) && c != EOF)
136               {
137                 if (c == '\n')
138                    read_rtx_lineno++;
139                 else if (prevc == '*' && c == '/')
140                   break;
141                 prevc = c;
142               }
143           }
144           break;
145
146         default:
147           return c;
148         }
149     }
150 }
151
152 /* Read an rtx code name into the buffer STR[].
153    It is terminated by any of the punctuation chars of rtx printed syntax.  */
154
155 static void
156 read_name (str, infile)
157      char *str;
158      FILE *infile;
159 {
160   char *p;
161   int c;
162
163   c = read_skip_spaces (infile);
164
165   p = str;
166   while (1)
167     {
168       if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r')
169         break;
170       if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
171           || c == '(' || c == '[')
172         {
173           ungetc (c, infile);
174           break;
175         }
176       *p++ = c;
177       c = getc (infile);
178     }
179   if (p == str)
180     fatal_with_file_and_line (infile, "missing name or number");
181   if (c == '\n')
182     read_rtx_lineno++;
183
184   *p = 0;
185
186   if (md_constants)
187     {
188       /* Do constant expansion.  */
189       struct md_constant *def;
190
191       p = str;
192       do
193         {
194           struct md_constant tmp_def;
195
196           tmp_def.name = p;
197           def = htab_find (md_constants, &tmp_def);
198           if (def)
199             p = def->value;
200         } while (def);
201       if (p != str)
202         strcpy (str, p);
203     }
204 }
205
206 /* Subroutine of the string readers.  Handles backslash escapes.
207    Caller has read the backslash, but not placed it into the obstack.  */
208 static void
209 read_escape (ob, infile)
210      struct obstack *ob;
211      FILE *infile;
212 {
213   int c = getc (infile);
214
215   switch (c)
216     {
217       /* Backslash-newline is replaced by nothing, as in C.  */
218     case '\n':
219       read_rtx_lineno++;
220       return;
221
222       /* \" \' \\ are replaced by the second character.  */
223     case '\\':
224     case '"':
225     case '\'':
226       break;
227
228       /* Standard C string escapes:
229          \a \b \f \n \r \t \v
230          \[0-7] \x
231          all are passed through to the output string unmolested.
232          In normal use these wind up in a string constant processed
233          by the C compiler, which will translate them appropriately.
234          We do not bother checking that \[0-7] are followed by up to
235          two octal digits, or that \x is followed by N hex digits.
236          \? \u \U are left out because they are not in traditional C.  */
237     case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
238     case '0': case '1': case '2': case '3': case '4': case '5': case '6':
239     case '7': case 'x':
240       obstack_1grow (ob, '\\');
241       break;
242
243       /* \; makes stuff for a C string constant containing
244          newline and tab.  */
245     case ';':
246       obstack_grow (ob, "\\n\\t", 4);
247       return;
248
249       /* pass anything else through, but issue a warning.  */
250     default:
251       fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
252                read_rtx_filename, read_rtx_lineno, c);
253       obstack_1grow (ob, '\\');
254       break;
255     }
256
257   obstack_1grow (ob, c);
258 }
259
260
261 /* Read a double-quoted string onto the obstack.  Caller has scanned
262    the leading quote.  */
263 static char *
264 read_quoted_string (ob, infile)
265      struct obstack *ob;
266      FILE *infile;
267 {
268   int c;
269
270   while (1)
271     {
272       c = getc (infile); /* Read the string  */
273       if (c == '\n')
274         read_rtx_lineno++;
275       else if (c == '\\')
276         {
277           read_escape (ob, infile);
278           continue;
279         }
280       else if (c == '"')
281         break;
282
283       obstack_1grow (ob, c);
284     }
285
286   obstack_1grow (ob, 0);
287   return obstack_finish (ob);
288 }
289
290 /* Read a braced string (a la Tcl) onto the obstack.  Caller has
291    scanned the leading brace.  Note that unlike quoted strings,
292    the outermost braces _are_ included in the string constant.  */
293 static char *
294 read_braced_string (ob, infile)
295      struct obstack *ob;
296      FILE *infile;
297 {
298   int c;
299   int brace_depth = 1;  /* caller-processed */
300
301   obstack_1grow (ob, '{');
302   while (brace_depth)
303     {
304       c = getc (infile); /* Read the string  */
305       if (c == '\n')
306         read_rtx_lineno++;
307       else if (c == '{')
308         brace_depth++;
309       else if (c == '}')
310         brace_depth--;
311       else if (c == '\\')
312         {
313           read_escape (ob, infile);
314           continue;
315         }
316
317       obstack_1grow (ob, c);
318     }
319
320   obstack_1grow (ob, 0);
321   return obstack_finish (ob);
322 }
323
324 /* Read some kind of string constant.  This is the high-level routine
325    used by read_rtx.  It handles surrounding parentheses, leading star,
326    and dispatch to the appropriate string constant reader.  */
327
328 static char *
329 read_string (ob, infile, star_if_braced)
330      struct obstack *ob;
331      FILE *infile;
332      int star_if_braced;
333 {
334   char *stringbuf;
335   int saw_paren = 0;
336   int c;
337
338   c = read_skip_spaces (infile);
339   if (c == '(')
340     {
341       saw_paren = 1;
342       c = read_skip_spaces (infile);
343     }
344
345   if (c == '"')
346     stringbuf = read_quoted_string (ob, infile);
347   else if (c == '{')
348     {
349       if (star_if_braced)
350         obstack_1grow (ob, '*');
351       stringbuf = read_braced_string (ob, infile);
352     }
353   else
354     fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
355
356   if (saw_paren)
357     {
358       c = read_skip_spaces (infile);
359       if (c != ')')
360         fatal_expected_char (infile, ')', c);
361     }
362
363   return stringbuf;
364 }
365 \f
366 /* Provide a version of a function to read a long long if the system does
367    not provide one.  */
368 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
369 HOST_WIDE_INT
370 atoll (p)
371     const char *p;
372 {
373   int neg = 0;
374   HOST_WIDE_INT tmp_wide;
375
376   while (ISSPACE (*p))
377     p++;
378   if (*p == '-')
379     neg = 1, p++;
380   else if (*p == '+')
381     p++;
382
383   tmp_wide = 0;
384   while (ISDIGIT (*p))
385     {
386       HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
387       if (new_wide < tmp_wide)
388         {
389           /* Return INT_MAX equiv on overflow.  */
390           tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
391           break;
392         }
393       tmp_wide = new_wide;
394       p++;
395     }
396
397   if (neg)
398     tmp_wide = -tmp_wide;
399   return tmp_wide;
400 }
401 #endif
402
403 /* Given a constant definition, return a hash code for its name.  */
404 static unsigned
405 def_hash (def)
406      const void *def;
407 {
408   unsigned result, i;
409   const char *string = ((const struct md_constant *) def)->name;
410
411   for (result = i = 0;*string++ != '\0'; i++)
412     result += ((unsigned char) *string << (i % CHAR_BIT));
413   return result;
414 }
415
416 /* Given two constant definitions, return true if they have the same name.  */
417 static int
418 def_name_eq_p (def1, def2)
419      const void *def1, *def2;
420 {
421   return ! strcmp (((const struct md_constant *) def1)->name,
422                    ((const struct md_constant *) def2)->name);
423 }
424
425 /* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer suitable
426    to read a name or number into.  Process a define_constants directive,
427    starting with the optional space after the "define_constants".  */
428 static void
429 read_constants (infile, tmp_char)
430      FILE *infile;
431      char *tmp_char;
432 {
433   int c;
434   htab_t defs;
435
436   c = read_skip_spaces (infile);
437   if (c != '[')
438     fatal_expected_char (infile, '[', c);
439   defs = md_constants;
440   if (! defs)
441     defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0);
442   /* Disable constant expansion during definition processing.  */
443   md_constants = 0;
444   while ( (c = read_skip_spaces (infile)) != ']')
445     {
446       struct md_constant *def;
447       void **entry_ptr;
448
449       if (c != '(')
450         fatal_expected_char (infile, '(', c);
451       def = xmalloc (sizeof (struct md_constant));
452       def->name = tmp_char;
453       read_name (tmp_char, infile);
454       entry_ptr = htab_find_slot (defs, def, TRUE);
455       if (! *entry_ptr)
456         def->name = xstrdup (tmp_char);
457       c = read_skip_spaces (infile);
458       ungetc (c, infile);
459       read_name (tmp_char, infile);
460       if (! *entry_ptr)
461         {
462           def->value = xstrdup (tmp_char);
463           *entry_ptr = def;
464         }
465       else
466         {
467           def = *entry_ptr;
468           if (strcmp (def->value, tmp_char))
469             fatal_with_file_and_line (infile,
470                                       "redefinition of %s, was %s, now %s",
471                                       def->name, def->value, tmp_char);
472         }
473       c = read_skip_spaces (infile);
474       if (c != ')')
475         fatal_expected_char (infile, ')', c);
476     }
477   md_constants = defs;
478   c = read_skip_spaces (infile);
479   if (c != ')')
480     fatal_expected_char (infile, ')', c);
481 }
482
483 /* For every constant definition, call CALLBACK with two arguments:
484    a pointer a pointer to the constant definition and INFO.
485    Stops when CALLBACK returns zero.  */
486 void
487 traverse_md_constants (callback, info)
488      htab_trav callback;
489      void *info;
490 {
491   if (md_constants)
492     htab_traverse (md_constants, callback, info);
493 }
494
495 static void
496 validate_const_int (infile, string)
497      FILE *infile;
498      const char *string;
499 {
500   const char *cp;
501   int valid = 1;
502
503   cp = string;
504   while (*cp && ISSPACE (*cp))
505     cp++;
506   if (*cp == '-' || *cp == '+')
507     cp++;
508   if (*cp == 0)
509     valid = 0;
510   for (; *cp; cp++)
511     if (! ISDIGIT (*cp))
512       valid = 0;
513   if (!valid)
514     fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string);
515 }
516
517 /* Read an rtx in printed representation from INFILE
518    and return an actual rtx in core constructed accordingly.
519    read_rtx is not used in the compiler proper, but rather in
520    the utilities gen*.c that construct C code from machine descriptions.  */
521
522 rtx
523 read_rtx (infile)
524      FILE *infile;
525 {
526   int i, j;
527   RTX_CODE tmp_code;
528   const char *format_ptr;
529   /* tmp_char is a buffer used for reading decimal integers
530      and names of rtx types and machine modes.
531      Therefore, 256 must be enough.  */
532   char tmp_char[256];
533   rtx return_rtx;
534   int c;
535   int tmp_int;
536   HOST_WIDE_INT tmp_wide;
537
538   /* Obstack used for allocating RTL objects.  */
539   static struct obstack rtl_obstack;
540   static int initialized;
541
542   /* Linked list structure for making RTXs: */
543   struct rtx_list
544     {
545       struct rtx_list *next;
546       rtx value;                /* Value of this node.  */
547     };
548
549   if (!initialized) {
550     obstack_init (&rtl_obstack);
551     initialized = 1;
552   }
553
554 again:
555   c = read_skip_spaces (infile); /* Should be open paren.  */
556   if (c != '(')
557     fatal_expected_char (infile, '(', c);
558
559   read_name (tmp_char, infile);
560
561   tmp_code = UNKNOWN;
562
563   if (! strcmp (tmp_char, "define_constants"))
564     {
565       read_constants (infile, tmp_char);
566       goto again;
567     }
568   for (i = 0; i < NUM_RTX_CODE; i++)
569     if (! strcmp (tmp_char, GET_RTX_NAME (i)))
570       {
571         tmp_code = (RTX_CODE) i;        /* get value for name */
572         break;
573       }
574
575   if (tmp_code == UNKNOWN)
576     fatal_with_file_and_line (infile, "unknown rtx code `%s'", tmp_char);
577
578   /* (NIL) stands for an expression that isn't there.  */
579   if (tmp_code == NIL)
580     {
581       /* Discard the closeparen.  */
582       while ((c = getc (infile)) && c != ')')
583         ;
584
585       return 0;
586     }
587
588   /* If we end up with an insn expression then we free this space below.  */
589   return_rtx = rtx_alloc (tmp_code);
590   format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
591
592   /* If what follows is `: mode ', read it and
593      store the mode in the rtx.  */
594
595   i = read_skip_spaces (infile);
596   if (i == ':')
597     {
598       read_name (tmp_char, infile);
599       for (j = 0; j < NUM_MACHINE_MODES; j++)
600         if (! strcmp (GET_MODE_NAME (j), tmp_char))
601           break;
602
603       if (j == MAX_MACHINE_MODE)
604         fatal_with_file_and_line (infile, "unknown mode `%s'", tmp_char);
605
606       PUT_MODE (return_rtx, (enum machine_mode) j);
607     }
608   else
609     ungetc (i, infile);
610
611   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
612     switch (*format_ptr++)
613       {
614         /* 0 means a field for internal use only.
615            Don't expect it to be present in the input.  */
616       case '0':
617         break;
618
619       case 'e':
620       case 'u':
621         XEXP (return_rtx, i) = read_rtx (infile);
622         break;
623
624       case 'V':
625         /* 'V' is an optional vector: if a closeparen follows,
626            just store NULL for this element.  */
627         c = read_skip_spaces (infile);
628         ungetc (c, infile);
629         if (c == ')')
630           {
631             XVEC (return_rtx, i) = 0;
632             break;
633           }
634         /* Now process the vector.  */
635
636       case 'E':
637         {
638           /* Obstack to store scratch vector in.  */
639           struct obstack vector_stack;
640           int list_counter = 0;
641           rtvec return_vec = NULL_RTVEC;
642
643           c = read_skip_spaces (infile);
644           if (c != '[')
645             fatal_expected_char (infile, '[', c);
646
647           /* add expressions to a list, while keeping a count */
648           obstack_init (&vector_stack);
649           while ((c = read_skip_spaces (infile)) && c != ']')
650             {
651               ungetc (c, infile);
652               list_counter++;
653               obstack_ptr_grow (&vector_stack, (PTR) read_rtx (infile));
654             }
655           if (list_counter > 0)
656             {
657               return_vec = rtvec_alloc (list_counter);
658               memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
659                       list_counter * sizeof (rtx));
660             }
661           XVEC (return_rtx, i) = return_vec;
662           obstack_free (&vector_stack, NULL);
663           /* close bracket gotten */
664         }
665         break;
666
667       case 'S':
668         /* 'S' is an optional string: if a closeparen follows,
669            just store NULL for this element.  */
670         c = read_skip_spaces (infile);
671         ungetc (c, infile);
672         if (c == ')')
673           {
674             XSTR (return_rtx, i) = 0;
675             break;
676           }
677
678       case 'T':
679       case 's':
680         {
681           char *stringbuf;
682
683           /* The output template slot of a DEFINE_INSN,
684              DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
685              gets a star inserted as its first character, if it is
686              written with a brace block instead of a string constant.  */
687           int star_if_braced = (format_ptr[-1] == 'T');
688
689           stringbuf = read_string (&rtl_obstack, infile, star_if_braced);
690
691           /* For insn patterns, we want to provide a default name
692              based on the file and line, like "*foo.md:12", if the
693              given name is blank.  These are only for define_insn and
694              define_insn_and_split, to aid debugging.  */
695           if (*stringbuf == '\0'
696               && i == 0
697               && (GET_CODE (return_rtx) == DEFINE_INSN
698                   || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
699             {
700               char line_name[20];
701               const char *fn = (read_rtx_filename ? read_rtx_filename : "rtx");
702               const char *slash;
703               for (slash = fn; *slash; slash ++)
704                 if (*slash == '/' || *slash == '\\' || *slash == ':')
705                   fn = slash + 1;
706               obstack_1grow (&rtl_obstack, '*');
707               obstack_grow (&rtl_obstack, fn, strlen (fn));
708               sprintf (line_name, ":%d", read_rtx_lineno);
709               obstack_grow (&rtl_obstack, line_name, strlen (line_name)+1);
710               stringbuf = (char *) obstack_finish (&rtl_obstack);
711             }
712
713           if (star_if_braced)
714             XTMPL (return_rtx, i) = stringbuf;
715           else
716             XSTR (return_rtx, i) = stringbuf;
717         }
718         break;
719
720       case 'w':
721         read_name (tmp_char, infile);
722         validate_const_int (infile, tmp_char);
723 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
724         tmp_wide = atoi (tmp_char);
725 #else
726 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
727         tmp_wide = atol (tmp_char);
728 #else
729         /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
730            But prefer not to use our hand-rolled function above either.  */
731 #if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
732         tmp_wide = atoll (tmp_char);
733 #else
734         tmp_wide = atoq (tmp_char);
735 #endif
736 #endif
737 #endif
738         XWINT (return_rtx, i) = tmp_wide;
739         break;
740
741       case 'i':
742       case 'n':
743         read_name (tmp_char, infile);
744         validate_const_int (infile, tmp_char);
745         tmp_int = atoi (tmp_char);
746         XINT (return_rtx, i) = tmp_int;
747         break;
748
749       default:
750         fprintf (stderr,
751                  "switch format wrong in rtl.read_rtx(). format was: %c.\n",
752                  format_ptr[-1]);
753         fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
754         abort ();
755       }
756
757   c = read_skip_spaces (infile);
758   if (c != ')')
759     fatal_expected_char (infile, ')', c);
760
761   return return_rtx;
762 }