OSDN Git Service

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