OSDN Git Service

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