* profile.c (branch_prob): Remove unused variable insn.
[official-gcc.git] / gcc / read-rtl.c
blob945d9416764b6d551a5b0e605ebc36a076f14f24
1 /* RTL reader for GNU C Compiler.
2 Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
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.
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.
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. */
22 #include "hconfig.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "obstack.h"
26 #include "hashtab.h"
28 #define obstack_chunk_alloc xmalloc
29 #define obstack_chunk_free free
31 static htab_t md_constants;
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));
45 /* Subroutines of read_rtx. */
47 /* The current line number for the file. */
48 int read_rtx_lineno = 1;
50 /* The filename for aborting with file and line. */
51 const char *read_rtx_filename = "<unknown>";
53 static void
54 fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
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;
65 VA_START (ap, msg);
67 #ifndef ANSI_PROTOTYPES
68 infile = va_arg (ap, FILE *);
69 msg = va_arg (ap, const char *);
70 #endif
72 fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
73 vfprintf (stderr, msg, ap);
74 putc ('\n', stderr);
76 /* Gather some following context. */
77 for (i = 0; i < sizeof(context)-1; ++i)
79 c = getc (infile);
80 if (c == EOF)
81 break;
82 if (c == '\r' || c == '\n')
83 break;
84 context[i] = c;
86 context[i] = '\0';
88 fprintf (stderr, "%s:%d: following context is `%s'\n",
89 read_rtx_filename, read_rtx_lineno, context);
91 va_end (ap);
92 exit (1);
95 /* Dump code after printing a message. Used when read_rtx finds
96 invalid data. */
98 static void
99 fatal_expected_char (infile, expected_c, actual_c)
100 FILE *infile;
101 int expected_c, actual_c;
103 fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
104 expected_c, actual_c);
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. */
113 read_skip_spaces (infile)
114 FILE *infile;
116 register int c;
117 while (1)
119 c = getc (infile);
120 switch (c)
122 case '\n':
123 read_rtx_lineno++;
124 break;
126 case ' ': case '\t': case '\f': case '\r':
127 break;
129 case ';':
131 c = getc (infile);
132 while (c != '\n' && c != EOF);
133 read_rtx_lineno++;
134 break;
136 case '/':
138 register int prevc;
139 c = getc (infile);
140 if (c != '*')
141 fatal_expected_char (infile, '*', c);
143 prevc = 0;
144 while ((c = getc (infile)) && c != EOF)
146 if (c == '\n')
147 read_rtx_lineno++;
148 else if (prevc == '*' && c == '/')
149 break;
150 prevc = c;
153 break;
155 default:
156 return c;
161 /* Read an rtx code name into the buffer STR[].
162 It is terminated by any of the punctuation chars of rtx printed syntax. */
164 static void
165 read_name (str, infile)
166 char *str;
167 FILE *infile;
169 register char *p;
170 register int c;
172 c = read_skip_spaces(infile);
174 p = str;
175 while (1)
177 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r')
178 break;
179 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
180 || c == '(' || c == '[')
182 ungetc (c, infile);
183 break;
185 *p++ = c;
186 c = getc (infile);
188 if (p == str)
189 fatal_with_file_and_line (infile, "missing name or number");
190 if (c == '\n')
191 read_rtx_lineno++;
193 *p = 0;
195 if (md_constants)
197 /* Do constant expansion. */
198 struct md_constant *def;
200 p = str;
203 struct md_constant tmp_def;
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);
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;
222 int c = getc (infile);
223 switch (c)
225 /* Backslash-newline is replaced by nothing, as in C. */
226 case '\n':
227 read_rtx_lineno++;
228 return;
230 /* \" \' \\ are replaced by the second character. */
231 case '\\':
232 case '"':
233 case '\'':
234 break;
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;
251 /* \; makes stuff for a C string constant containing
252 newline and tab. */
253 case ';':
254 obstack_grow (ob, "\\n\\t", 4);
255 return;
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;
265 obstack_1grow (ob, c);
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;
276 int c;
277 while (1)
279 c = getc (infile); /* Read the string */
280 if (c == '\n')
281 read_rtx_lineno++;
282 else if (c == '\\')
284 read_escape (ob, infile);
285 continue;
287 else if (c == '"')
288 break;
290 obstack_1grow (ob, c);
293 obstack_1grow (ob, 0);
294 return obstack_finish (ob);
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;
305 int c;
306 int brace_depth = 1; /* caller-processed */
308 obstack_1grow (ob, '{');
309 while (brace_depth)
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 == '\\')
320 read_escape (ob, infile);
321 continue;
324 obstack_1grow (ob, c);
327 obstack_1grow (ob, 0);
328 return obstack_finish (ob);
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. */
335 static char *
336 read_string (ob, infile, star_if_braced)
337 struct obstack *ob;
338 FILE *infile;
339 int star_if_braced;
341 char *stringbuf;
342 int saw_paren = 0;
343 int c;
345 c = read_skip_spaces (infile);
346 if (c == '(')
348 saw_paren = 1;
349 c = read_skip_spaces (infile);
352 if (c == '"')
353 stringbuf = read_quoted_string (ob, infile);
354 else if (c == '{')
356 if (star_if_braced)
357 obstack_1grow (ob, '*');
358 stringbuf = read_braced_string (ob, infile);
360 else
361 fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
363 if (saw_paren)
365 c = read_skip_spaces (infile);
366 if (c != ')')
367 fatal_expected_char (infile, ')', c);
370 return stringbuf;
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;
380 int neg = 0;
381 HOST_WIDE_INT tmp_wide;
383 while (ISSPACE(*p))
384 p++;
385 if (*p == '-')
386 neg = 1, p++;
387 else if (*p == '+')
388 p++;
390 tmp_wide = 0;
391 while (ISDIGIT(*p))
393 HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
394 if (new_wide < tmp_wide)
396 /* Return INT_MAX equiv on overflow. */
397 tmp_wide = (~(unsigned HOST_WIDE_INT)0) >> 1;
398 break;
400 tmp_wide = new_wide;
401 p++;
404 if (neg)
405 tmp_wide = -tmp_wide;
406 return tmp_wide;
408 #endif
410 /* Given a constant definition, return a hash code for its name. */
411 static unsigned
412 def_hash (def)
413 const void *def;
415 unsigned result, i;
416 const char *string = ((const struct md_constant *)def)->name;
418 for (result = i = 0;*string++ != '\0'; i++)
419 result += ((unsigned char) *string << (i % CHAR_BIT));
420 return result;
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;
428 return ! strcmp (((const struct md_constant *)def1)->name,
429 ((const struct md_constant *)def2)->name);
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;
440 int c;
441 htab_t defs;
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)) != ']')
453 struct md_constant *def;
454 void **entry_ptr;
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)
469 def->value = xstrdup (tmp_char);
470 *entry_ptr = def;
472 else
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);
480 c = read_skip_spaces (infile);
481 if (c != ')')
482 fatal_expected_char (infile, ')', c);
484 md_constants = defs;
485 c = read_skip_spaces (infile);
486 if (c != ')')
487 fatal_expected_char (infile, ')', c);
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;
498 if (md_constants)
499 htab_traverse (md_constants, callback, info);
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. */
508 read_rtx (infile)
509 FILE *infile;
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;
523 /* Obstack used for allocating RTL objects. */
524 static struct obstack rtl_obstack;
525 static int initialized;
527 /* Linked list structure for making RTXs: */
528 struct rtx_list
530 struct rtx_list *next;
531 rtx value; /* Value of this node. */
534 if (!initialized) {
535 obstack_init (&rtl_obstack);
536 initialized = 1;
539 again:
540 c = read_skip_spaces (infile); /* Should be open paren. */
541 if (c != '(')
542 fatal_expected_char (infile, '(', c);
544 read_name (tmp_char, infile);
546 tmp_code = UNKNOWN;
548 if (! strcmp (tmp_char, "define_constants"))
550 read_constants (infile, tmp_char);
551 goto again;
553 for (i = 0; i < NUM_RTX_CODE; i++)
554 if (! strcmp (tmp_char, GET_RTX_NAME (i)))
556 tmp_code = (RTX_CODE) i; /* get value for name */
557 break;
560 if (tmp_code == UNKNOWN)
561 fatal_with_file_and_line (infile, "unknown rtx code `%s'", tmp_char);
563 /* (NIL) stands for an expression that isn't there. */
564 if (tmp_code == NIL)
566 /* Discard the closeparen. */
567 while ((c = getc (infile)) && c != ')')
570 return 0;
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));
577 /* If what follows is `: mode ', read it and
578 store the mode in the rtx. */
580 i = read_skip_spaces (infile);
581 if (i == ':')
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;
588 if (j == MAX_MACHINE_MODE)
589 fatal_with_file_and_line (infile, "unknown mode `%s'", tmp_char);
591 PUT_MODE (return_rtx, (enum machine_mode) j);
593 else
594 ungetc (i, infile);
596 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
597 switch (*format_ptr++)
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;
604 case 'e':
605 case 'u':
606 XEXP (return_rtx, i) = read_rtx (infile);
607 break;
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 == ')')
616 XVEC (return_rtx, i) = 0;
617 break;
619 /* Now process the vector. */
621 case 'E':
623 /* Obstack to store scratch vector in. */
624 struct obstack vector_stack;
625 int list_counter = 0;
626 rtvec return_vec = NULL_RTVEC;
628 c = read_skip_spaces (infile);
629 if (c != '[')
630 fatal_expected_char (infile, '[', c);
632 /* add expressions to a list, while keeping a count */
633 obstack_init (&vector_stack);
634 while ((c = read_skip_spaces (infile)) && c != ']')
636 ungetc (c, infile);
637 list_counter++;
638 obstack_ptr_grow (&vector_stack, (PTR) read_rtx (infile));
640 if (list_counter > 0)
642 return_vec = rtvec_alloc (list_counter);
643 memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
644 list_counter * sizeof (rtx));
646 XVEC (return_rtx, i) = return_vec;
647 obstack_free (&vector_stack, NULL);
648 /* close bracket gotten */
650 break;
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 == ')')
659 XSTR (return_rtx, i) = 0;
660 break;
663 case 'T':
664 case 's':
666 char *stringbuf;
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');
674 stringbuf = read_string (&rtl_obstack, infile, star_if_braced);
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))
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);
698 if (star_if_braced)
699 XTMPL (return_rtx, i) = stringbuf;
700 else
701 XSTR (return_rtx, i) = stringbuf;
703 break;
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;
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;
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 ();
740 c = read_skip_spaces (infile);
741 if (c != ')')
742 fatal_expected_char (infile, ')', c);
744 return return_rtx;