OSDN Git Service

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