OSDN Git Service

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