OSDN Git Service

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