2004-06-22 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / read-rtl.c
blobd17235f5f61b994df1fbc95317a064415227d449
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.
6 This file is part of GCC.
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.
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.
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. */
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"
31 static htab_t md_constants;
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 *);
46 /* Subroutines of read_rtx. */
48 /* The current line number for the file. */
49 int read_rtx_lineno = 1;
51 /* The filename for aborting with file and line. */
52 const char *read_rtx_filename = "<unknown>";
54 static void
55 fatal_with_file_and_line (FILE *infile, const char *msg, ...)
57 char context[64];
58 size_t i;
59 int c;
60 va_list ap;
62 va_start (ap, msg);
64 fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
65 vfprintf (stderr, msg, ap);
66 putc ('\n', stderr);
68 /* Gather some following context. */
69 for (i = 0; i < sizeof (context)-1; ++i)
71 c = getc (infile);
72 if (c == EOF)
73 break;
74 if (c == '\r' || c == '\n')
75 break;
76 context[i] = c;
78 context[i] = '\0';
80 fprintf (stderr, "%s:%d: following context is `%s'\n",
81 read_rtx_filename, read_rtx_lineno, context);
83 va_end (ap);
84 exit (1);
87 /* Dump code after printing a message. Used when read_rtx finds
88 invalid data. */
90 static void
91 fatal_expected_char (FILE *infile, int expected_c, int actual_c)
93 fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
94 expected_c, actual_c);
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. */
103 read_skip_spaces (FILE *infile)
105 int c;
107 while (1)
109 c = getc (infile);
110 switch (c)
112 case '\n':
113 read_rtx_lineno++;
114 break;
116 case ' ': case '\t': case '\f': case '\r':
117 break;
119 case ';':
121 c = getc (infile);
122 while (c != '\n' && c != EOF);
123 read_rtx_lineno++;
124 break;
126 case '/':
128 int prevc;
129 c = getc (infile);
130 if (c != '*')
131 fatal_expected_char (infile, '*', c);
133 prevc = 0;
134 while ((c = getc (infile)) && c != EOF)
136 if (c == '\n')
137 read_rtx_lineno++;
138 else if (prevc == '*' && c == '/')
139 break;
140 prevc = c;
143 break;
145 default:
146 return c;
151 /* Read an rtx code name into the buffer STR[].
152 It is terminated by any of the punctuation chars of rtx printed syntax. */
154 static void
155 read_name (char *str, FILE *infile)
157 char *p;
158 int c;
160 c = read_skip_spaces (infile);
162 p = str;
163 while (1)
165 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r')
166 break;
167 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
168 || c == '(' || c == '[')
170 ungetc (c, infile);
171 break;
173 *p++ = c;
174 c = getc (infile);
176 if (p == str)
177 fatal_with_file_and_line (infile, "missing name or number");
178 if (c == '\n')
179 read_rtx_lineno++;
181 *p = 0;
183 if (md_constants)
185 /* Do constant expansion. */
186 struct md_constant *def;
188 p = str;
191 struct md_constant tmp_def;
193 tmp_def.name = p;
194 def = htab_find (md_constants, &tmp_def);
195 if (def)
196 p = def->value;
197 } while (def);
198 if (p != str)
199 strcpy (str, p);
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)
208 int c = getc (infile);
210 switch (c)
212 /* Backslash-newline is replaced by nothing, as in C. */
213 case '\n':
214 read_rtx_lineno++;
215 return;
217 /* \" \' \\ are replaced by the second character. */
218 case '\\':
219 case '"':
220 case '\'':
221 break;
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;
238 /* \; makes stuff for a C string constant containing
239 newline and tab. */
240 case ';':
241 obstack_grow (ob, "\\n\\t", 4);
242 return;
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;
252 obstack_1grow (ob, c);
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)
261 int c;
263 while (1)
265 c = getc (infile); /* Read the string */
266 if (c == '\n')
267 read_rtx_lineno++;
268 else if (c == '\\')
270 read_escape (ob, infile);
271 continue;
273 else if (c == '"')
274 break;
276 obstack_1grow (ob, c);
279 obstack_1grow (ob, 0);
280 return obstack_finish (ob);
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)
289 int c;
290 int brace_depth = 1; /* caller-processed */
291 unsigned long starting_read_rtx_lineno = read_rtx_lineno;
293 obstack_1grow (ob, '{');
294 while (brace_depth)
296 c = getc (infile); /* Read the string */
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 == '\\')
306 read_escape (ob, infile);
307 continue;
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);
314 obstack_1grow (ob, c);
317 obstack_1grow (ob, 0);
318 return obstack_finish (ob);
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. */
325 static char *
326 read_string (struct obstack *ob, FILE *infile, int star_if_braced)
328 char *stringbuf;
329 int saw_paren = 0;
330 int c;
332 c = read_skip_spaces (infile);
333 if (c == '(')
335 saw_paren = 1;
336 c = read_skip_spaces (infile);
339 if (c == '"')
340 stringbuf = read_quoted_string (ob, infile);
341 else if (c == '{')
343 if (star_if_braced)
344 obstack_1grow (ob, '*');
345 stringbuf = read_braced_string (ob, infile);
347 else
348 fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
350 if (saw_paren)
352 c = read_skip_spaces (infile);
353 if (c != ')')
354 fatal_expected_char (infile, ')', c);
357 return stringbuf;
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 *);
365 HOST_WIDE_INT
366 atoll (const char *p)
368 int neg = 0;
369 HOST_WIDE_INT tmp_wide;
371 while (ISSPACE (*p))
372 p++;
373 if (*p == '-')
374 neg = 1, p++;
375 else if (*p == '+')
376 p++;
378 tmp_wide = 0;
379 while (ISDIGIT (*p))
381 HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
382 if (new_wide < tmp_wide)
384 /* Return INT_MAX equiv on overflow. */
385 tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
386 break;
388 tmp_wide = new_wide;
389 p++;
392 if (neg)
393 tmp_wide = -tmp_wide;
394 return tmp_wide;
396 #endif
398 /* Given a constant definition, return a hash code for its name. */
399 static hashval_t
400 def_hash (const void *def)
402 unsigned result, i;
403 const char *string = ((const struct md_constant *) def)->name;
405 for (result = i = 0;*string++ != '\0'; i++)
406 result += ((unsigned char) *string << (i % CHAR_BIT));
407 return result;
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)
414 return ! strcmp (((const struct md_constant *) def1)->name,
415 ((const struct md_constant *) def2)->name);
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)
424 int c;
425 htab_t defs;
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)) != ']')
437 struct md_constant *def;
438 void **entry_ptr;
440 if (c != '(')
441 fatal_expected_char (infile, '(', c);
442 def = xmalloc (sizeof (struct md_constant));
443 def->name = tmp_char;
444 read_name (tmp_char, infile);
445 entry_ptr = htab_find_slot (defs, def, TRUE);
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)
453 def->value = xstrdup (tmp_char);
454 *entry_ptr = def;
456 else
458 def = *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);
464 c = read_skip_spaces (infile);
465 if (c != ')')
466 fatal_expected_char (infile, ')', c);
468 md_constants = defs;
469 c = read_skip_spaces (infile);
470 if (c != ')')
471 fatal_expected_char (infile, ')', c);
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)
480 if (md_constants)
481 htab_traverse (md_constants, callback, info);
484 static void
485 validate_const_int (FILE *infile, const char *string)
487 const char *cp;
488 int valid = 1;
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);
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. */
510 read_rtx (FILE *infile)
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;
524 /* Obstack used for allocating RTL objects. */
525 static struct obstack rtl_obstack;
526 static int initialized;
528 /* Linked list structure for making RTXs: */
529 struct rtx_list
531 struct rtx_list *next;
532 rtx value; /* Value of this node. */
535 if (!initialized) {
536 obstack_init (&rtl_obstack);
537 initialized = 1;
540 again:
541 c = read_skip_spaces (infile); /* Should be open paren. */
542 if (c != '(')
543 fatal_expected_char (infile, '(', c);
545 read_name (tmp_char, infile);
547 tmp_code = UNKNOWN;
549 if (! strcmp (tmp_char, "define_constants"))
551 read_constants (infile, tmp_char);
552 goto again;
554 for (i = 0; i < NUM_RTX_CODE; i++)
555 if (! strcmp (tmp_char, GET_RTX_NAME (i)))
557 tmp_code = (RTX_CODE) i; /* get value for name */
558 break;
561 if (tmp_code == UNKNOWN)
562 fatal_with_file_and_line (infile, "unknown rtx code `%s'", tmp_char);
564 /* (NIL) stands for an expression that isn't there. */
565 if (tmp_code == NIL)
567 /* Discard the closeparen. */
568 while ((c = getc (infile)) && c != ')')
571 return 0;
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));
578 /* If what follows is `: mode ', read it and
579 store the mode in the rtx. */
581 i = read_skip_spaces (infile);
582 if (i == ':')
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;
589 if (j == MAX_MACHINE_MODE)
590 fatal_with_file_and_line (infile, "unknown mode `%s'", tmp_char);
592 PUT_MODE (return_rtx, (enum machine_mode) j);
594 else
595 ungetc (i, infile);
597 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
598 switch (*format_ptr++)
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;
605 case 'e':
606 case 'u':
607 XEXP (return_rtx, i) = read_rtx (infile);
608 break;
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 == ')')
617 XVEC (return_rtx, i) = 0;
618 break;
620 /* Now process the vector. */
622 case 'E':
624 /* Obstack to store scratch vector in. */
625 struct obstack vector_stack;
626 int list_counter = 0;
627 rtvec return_vec = NULL_RTVEC;
629 c = read_skip_spaces (infile);
630 if (c != '[')
631 fatal_expected_char (infile, '[', c);
633 /* Add expressions to a list, while keeping a count. */
634 obstack_init (&vector_stack);
635 while ((c = read_skip_spaces (infile)) && c != ']')
637 ungetc (c, infile);
638 list_counter++;
639 obstack_ptr_grow (&vector_stack, read_rtx (infile));
641 if (list_counter > 0)
643 return_vec = rtvec_alloc (list_counter);
644 memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
645 list_counter * sizeof (rtx));
647 XVEC (return_rtx, i) = return_vec;
648 obstack_free (&vector_stack, NULL);
649 /* close bracket gotten */
651 break;
653 case 'S':
654 case 'T':
655 case 's':
657 char *stringbuf;
658 int star_if_braced;
660 c = read_skip_spaces (infile);
661 ungetc (c, infile);
662 if (c == ')')
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;
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');
677 stringbuf = read_string (&rtl_obstack, infile, star_if_braced);
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))
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);
701 if (star_if_braced)
702 XTMPL (return_rtx, i) = stringbuf;
703 else
704 XSTR (return_rtx, i) = stringbuf;
706 break;
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;
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;
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 ();
745 c = read_skip_spaces (infile);
746 if (c != ')')
747 fatal_expected_char (infile, ')', c);
749 return return_rtx;