Don't use #if inside C test expression.
[gcc.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' || c == '\r')
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 }