Make return in memory explicit.
[official-gcc.git] / gcc / gensupport.c
blob2acfc8a3efd7d3c2e37fe46012a43f129e58f652
1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 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 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "bconfig.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "obstack.h"
28 #include "errors.h"
29 #include "hashtab.h"
30 #include "gensupport.h"
33 /* In case some macros used by files we include need it, define this here. */
34 int target_flags;
36 int insn_elision = 1;
38 static struct obstack obstack;
39 struct obstack *rtl_obstack = &obstack;
41 static int sequence_num;
42 static int errors;
44 static int predicable_default;
45 static const char *predicable_true;
46 static const char *predicable_false;
48 static htab_t condition_table;
50 static char *base_dir = NULL;
52 /* We initially queue all patterns, process the define_insn and
53 define_cond_exec patterns, then return them one at a time. */
55 struct queue_elem
57 rtx data;
58 const char *filename;
59 int lineno;
60 struct queue_elem *next;
61 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
62 points to the generated DEFINE_SPLIT. */
63 struct queue_elem *split;
66 static struct queue_elem *define_attr_queue;
67 static struct queue_elem **define_attr_tail = &define_attr_queue;
68 static struct queue_elem *define_insn_queue;
69 static struct queue_elem **define_insn_tail = &define_insn_queue;
70 static struct queue_elem *define_cond_exec_queue;
71 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
72 static struct queue_elem *other_queue;
73 static struct queue_elem **other_tail = &other_queue;
75 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
76 const char *, int);
78 /* Current maximum length of directory names in the search path
79 for include files. (Altered as we get more of them.) */
81 size_t max_include_len;
83 struct file_name_list
85 struct file_name_list *next;
86 const char *fname;
89 struct file_name_list *first_dir_md_include = 0; /* First dir to search */
90 /* First dir to search for <file> */
91 struct file_name_list *first_bracket_include = 0;
92 struct file_name_list *last_dir_md_include = 0; /* Last in chain */
94 static void remove_constraints (rtx);
95 static void process_rtx (rtx, int);
97 static int is_predicable (struct queue_elem *);
98 static void identify_predicable_attribute (void);
99 static int n_alternatives (const char *);
100 static void collect_insn_data (rtx, int *, int *);
101 static rtx alter_predicate_for_insn (rtx, int, int, int);
102 static const char *alter_test_for_insn (struct queue_elem *,
103 struct queue_elem *);
104 static char *shift_output_template (char *, const char *, int);
105 static const char *alter_output_for_insn (struct queue_elem *,
106 struct queue_elem *,
107 int, int);
108 static void process_one_cond_exec (struct queue_elem *);
109 static void process_define_cond_exec (void);
110 static void process_include (rtx, int);
111 static char *save_string (const char *, int);
113 void
114 message_with_line (int lineno, const char *msg, ...)
116 va_list ap;
118 va_start (ap, msg);
120 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
121 vfprintf (stderr, msg, ap);
122 fputc ('\n', stderr);
124 va_end (ap);
127 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
128 the gensupport programs. */
131 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
132 HOST_WIDE_INT arg)
134 rtx rt = rtx_alloc (CONST_INT);
136 XWINT (rt, 0) = arg;
137 return rt;
140 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
141 element. */
143 static struct queue_elem *
144 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
145 const char *filename, int lineno)
147 struct queue_elem *e = XNEW(struct queue_elem);
148 e->data = pattern;
149 e->filename = filename;
150 e->lineno = lineno;
151 e->next = NULL;
152 e->split = NULL;
153 **list_tail = e;
154 *list_tail = &e->next;
155 return e;
158 /* Recursively remove constraints from an rtx. */
160 static void
161 remove_constraints (rtx part)
163 int i, j;
164 const char *format_ptr;
166 if (part == 0)
167 return;
169 if (GET_CODE (part) == MATCH_OPERAND)
170 XSTR (part, 2) = "";
171 else if (GET_CODE (part) == MATCH_SCRATCH)
172 XSTR (part, 1) = "";
174 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
176 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
177 switch (*format_ptr++)
179 case 'e':
180 case 'u':
181 remove_constraints (XEXP (part, i));
182 break;
183 case 'E':
184 if (XVEC (part, i) != NULL)
185 for (j = 0; j < XVECLEN (part, i); j++)
186 remove_constraints (XVECEXP (part, i, j));
187 break;
191 /* Process an include file assuming that it lives in gcc/config/{target}/
192 if the include looks like (include "file"). */
194 static void
195 process_include (rtx desc, int lineno)
197 const char *filename = XSTR (desc, 0);
198 const char *old_filename;
199 int old_lineno;
200 char *pathname;
201 FILE *input_file;
203 /* If specified file name is absolute, skip the include stack. */
204 if (! IS_ABSOLUTE_PATH (filename))
206 struct file_name_list *stackp;
208 /* Search directory path, trying to open the file. */
209 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
211 static const char sep[2] = { DIR_SEPARATOR, '\0' };
213 pathname = concat (stackp->fname, sep, filename, NULL);
214 input_file = fopen (pathname, "r");
215 if (input_file != NULL)
216 goto success;
217 free (pathname);
221 if (base_dir)
222 pathname = concat (base_dir, filename, NULL);
223 else
224 pathname = xstrdup (filename);
225 input_file = fopen (pathname, "r");
226 if (input_file == NULL)
228 free (pathname);
229 message_with_line (lineno, "include file `%s' not found", filename);
230 errors = 1;
231 return;
233 success:
235 /* Save old cursor; setup new for the new file. Note that "lineno" the
236 argument to this function is the beginning of the include statement,
237 while read_rtx_lineno has already been advanced. */
238 old_filename = read_rtx_filename;
239 old_lineno = read_rtx_lineno;
240 read_rtx_filename = pathname;
241 read_rtx_lineno = 1;
243 /* Read the entire file. */
244 while (1)
246 rtx desc;
247 int c;
249 c = read_skip_spaces (input_file);
250 if (c == EOF)
251 break;
253 ungetc (c, input_file);
254 lineno = read_rtx_lineno;
255 desc = read_rtx (input_file);
256 process_rtx (desc, lineno);
259 /* Do not free pathname. It is attached to the various rtx queue
260 elements. */
262 read_rtx_filename = old_filename;
263 read_rtx_lineno = old_lineno;
265 fclose (input_file);
268 /* Process a top level rtx in some way, queuing as appropriate. */
270 static void
271 process_rtx (rtx desc, int lineno)
273 switch (GET_CODE (desc))
275 case DEFINE_INSN:
276 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
277 break;
279 case DEFINE_COND_EXEC:
280 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
281 break;
283 case DEFINE_ATTR:
284 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
285 break;
287 case INCLUDE:
288 process_include (desc, lineno);
289 break;
291 case DEFINE_INSN_AND_SPLIT:
293 const char *split_cond;
294 rtx split;
295 rtvec attr;
296 int i;
297 struct queue_elem *insn_elem;
298 struct queue_elem *split_elem;
300 /* Create a split with values from the insn_and_split. */
301 split = rtx_alloc (DEFINE_SPLIT);
303 i = XVECLEN (desc, 1);
304 XVEC (split, 0) = rtvec_alloc (i);
305 while (--i >= 0)
307 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
308 remove_constraints (XVECEXP (split, 0, i));
311 /* If the split condition starts with "&&", append it to the
312 insn condition to create the new split condition. */
313 split_cond = XSTR (desc, 4);
314 if (split_cond[0] == '&' && split_cond[1] == '&')
315 split_cond = concat (XSTR (desc, 2), split_cond, NULL);
316 XSTR (split, 1) = split_cond;
317 XVEC (split, 2) = XVEC (desc, 5);
318 XSTR (split, 3) = XSTR (desc, 6);
320 /* Fix up the DEFINE_INSN. */
321 attr = XVEC (desc, 7);
322 PUT_CODE (desc, DEFINE_INSN);
323 XVEC (desc, 4) = attr;
325 /* Queue them. */
326 insn_elem
327 = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
328 lineno);
329 split_elem
330 = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
331 insn_elem->split = split_elem;
332 break;
335 default:
336 queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
337 break;
341 /* Return true if attribute PREDICABLE is true for ELEM, which holds
342 a DEFINE_INSN. */
344 static int
345 is_predicable (struct queue_elem *elem)
347 rtvec vec = XVEC (elem->data, 4);
348 const char *value;
349 int i;
351 if (! vec)
352 return predicable_default;
354 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
356 rtx sub = RTVEC_ELT (vec, i);
357 switch (GET_CODE (sub))
359 case SET_ATTR:
360 if (strcmp (XSTR (sub, 0), "predicable") == 0)
362 value = XSTR (sub, 1);
363 goto found;
365 break;
367 case SET_ATTR_ALTERNATIVE:
368 if (strcmp (XSTR (sub, 0), "predicable") == 0)
370 message_with_line (elem->lineno,
371 "multiple alternatives for `predicable'");
372 errors = 1;
373 return 0;
375 break;
377 case SET:
378 if (GET_CODE (SET_DEST (sub)) != ATTR
379 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
380 break;
381 sub = SET_SRC (sub);
382 if (GET_CODE (sub) == CONST_STRING)
384 value = XSTR (sub, 0);
385 goto found;
388 /* ??? It would be possible to handle this if we really tried.
389 It's not easy though, and I'm not going to bother until it
390 really proves necessary. */
391 message_with_line (elem->lineno,
392 "non-constant value for `predicable'");
393 errors = 1;
394 return 0;
396 default:
397 abort ();
401 return predicable_default;
403 found:
404 /* Verify that predicability does not vary on the alternative. */
405 /* ??? It should be possible to handle this by simply eliminating
406 the non-predicable alternatives from the insn. FRV would like
407 to do this. Delay this until we've got the basics solid. */
408 if (strchr (value, ',') != NULL)
410 message_with_line (elem->lineno,
411 "multiple alternatives for `predicable'");
412 errors = 1;
413 return 0;
416 /* Find out which value we're looking at. */
417 if (strcmp (value, predicable_true) == 0)
418 return 1;
419 if (strcmp (value, predicable_false) == 0)
420 return 0;
422 message_with_line (elem->lineno,
423 "unknown value `%s' for `predicable' attribute",
424 value);
425 errors = 1;
426 return 0;
429 /* Examine the attribute "predicable"; discover its boolean values
430 and its default. */
432 static void
433 identify_predicable_attribute (void)
435 struct queue_elem *elem;
436 char *p_true, *p_false;
437 const char *value;
439 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
440 for (elem = define_attr_queue; elem ; elem = elem->next)
441 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
442 goto found;
444 message_with_line (define_cond_exec_queue->lineno,
445 "attribute `predicable' not defined");
446 errors = 1;
447 return;
449 found:
450 value = XSTR (elem->data, 1);
451 p_false = xstrdup (value);
452 p_true = strchr (p_false, ',');
453 if (p_true == NULL || strchr (++p_true, ',') != NULL)
455 message_with_line (elem->lineno,
456 "attribute `predicable' is not a boolean");
457 errors = 1;
458 return;
460 p_true[-1] = '\0';
462 predicable_true = p_true;
463 predicable_false = p_false;
465 switch (GET_CODE (XEXP (elem->data, 2)))
467 case CONST_STRING:
468 value = XSTR (XEXP (elem->data, 2), 0);
469 break;
471 case CONST:
472 message_with_line (elem->lineno,
473 "attribute `predicable' cannot be const");
474 errors = 1;
475 return;
477 default:
478 message_with_line (elem->lineno,
479 "attribute `predicable' must have a constant default");
480 errors = 1;
481 return;
484 if (strcmp (value, p_true) == 0)
485 predicable_default = 1;
486 else if (strcmp (value, p_false) == 0)
487 predicable_default = 0;
488 else
490 message_with_line (elem->lineno,
491 "unknown value `%s' for `predicable' attribute",
492 value);
493 errors = 1;
497 /* Return the number of alternatives in constraint S. */
499 static int
500 n_alternatives (const char *s)
502 int n = 1;
504 if (s)
505 while (*s)
506 n += (*s++ == ',');
508 return n;
511 /* Determine how many alternatives there are in INSN, and how many
512 operands. */
514 static void
515 collect_insn_data (rtx pattern, int *palt, int *pmax)
517 const char *fmt;
518 enum rtx_code code;
519 int i, j, len;
521 code = GET_CODE (pattern);
522 switch (code)
524 case MATCH_OPERAND:
525 i = n_alternatives (XSTR (pattern, 2));
526 *palt = (i > *palt ? i : *palt);
527 /* Fall through. */
529 case MATCH_OPERATOR:
530 case MATCH_SCRATCH:
531 case MATCH_PARALLEL:
532 i = XINT (pattern, 0);
533 if (i > *pmax)
534 *pmax = i;
535 break;
537 default:
538 break;
541 fmt = GET_RTX_FORMAT (code);
542 len = GET_RTX_LENGTH (code);
543 for (i = 0; i < len; i++)
545 switch (fmt[i])
547 case 'e': case 'u':
548 collect_insn_data (XEXP (pattern, i), palt, pmax);
549 break;
551 case 'V':
552 if (XVEC (pattern, i) == NULL)
553 break;
554 /* Fall through. */
555 case 'E':
556 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
557 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
558 break;
560 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
561 break;
563 default:
564 abort ();
569 static rtx
570 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
572 const char *fmt;
573 enum rtx_code code;
574 int i, j, len;
576 code = GET_CODE (pattern);
577 switch (code)
579 case MATCH_OPERAND:
581 const char *c = XSTR (pattern, 2);
583 if (n_alternatives (c) != 1)
585 message_with_line (lineno,
586 "too many alternatives for operand %d",
587 XINT (pattern, 0));
588 errors = 1;
589 return NULL;
592 /* Replicate C as needed to fill out ALT alternatives. */
593 if (c && *c && alt > 1)
595 size_t c_len = strlen (c);
596 size_t len = alt * (c_len + 1);
597 char *new_c = XNEWVEC(char, len);
599 memcpy (new_c, c, c_len);
600 for (i = 1; i < alt; ++i)
602 new_c[i * (c_len + 1) - 1] = ',';
603 memcpy (&new_c[i * (c_len + 1)], c, c_len);
605 new_c[len - 1] = '\0';
606 XSTR (pattern, 2) = new_c;
609 /* Fall through. */
611 case MATCH_OPERATOR:
612 case MATCH_SCRATCH:
613 case MATCH_PARALLEL:
614 XINT (pattern, 0) += max_op;
615 break;
617 default:
618 break;
621 fmt = GET_RTX_FORMAT (code);
622 len = GET_RTX_LENGTH (code);
623 for (i = 0; i < len; i++)
625 rtx r;
627 switch (fmt[i])
629 case 'e': case 'u':
630 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
631 max_op, lineno);
632 if (r == NULL)
633 return r;
634 break;
636 case 'E':
637 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
639 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
640 alt, max_op, lineno);
641 if (r == NULL)
642 return r;
644 break;
646 case 'i': case 'w': case '0': case 's':
647 break;
649 default:
650 abort ();
654 return pattern;
657 static const char *
658 alter_test_for_insn (struct queue_elem *ce_elem,
659 struct queue_elem *insn_elem)
661 const char *ce_test, *insn_test;
663 ce_test = XSTR (ce_elem->data, 1);
664 insn_test = XSTR (insn_elem->data, 2);
665 if (!ce_test || *ce_test == '\0')
666 return insn_test;
667 if (!insn_test || *insn_test == '\0')
668 return ce_test;
670 return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
673 /* Adjust all of the operand numbers in SRC to match the shift they'll
674 get from an operand displacement of DISP. Return a pointer after the
675 adjusted string. */
677 static char *
678 shift_output_template (char *dest, const char *src, int disp)
680 while (*src)
682 char c = *src++;
683 *dest++ = c;
684 if (c == '%')
686 c = *src++;
687 if (ISDIGIT ((unsigned char) c))
688 c += disp;
689 else if (ISALPHA (c))
691 *dest++ = c;
692 c = *src++ + disp;
694 *dest++ = c;
698 return dest;
701 static const char *
702 alter_output_for_insn (struct queue_elem *ce_elem,
703 struct queue_elem *insn_elem,
704 int alt, int max_op)
706 const char *ce_out, *insn_out;
707 char *result, *p;
708 size_t len, ce_len, insn_len;
710 /* ??? Could coordinate with genoutput to not duplicate code here. */
712 ce_out = XSTR (ce_elem->data, 2);
713 insn_out = XTMPL (insn_elem->data, 3);
714 if (!ce_out || *ce_out == '\0')
715 return insn_out;
717 ce_len = strlen (ce_out);
718 insn_len = strlen (insn_out);
720 if (*insn_out == '*')
721 /* You must take care of the predicate yourself. */
722 return insn_out;
724 if (*insn_out == '@')
726 len = (ce_len + 1) * alt + insn_len + 1;
727 p = result = XNEWVEC(char, len);
732 *p++ = *insn_out++;
733 while (ISSPACE ((unsigned char) *insn_out));
735 if (*insn_out != '#')
737 p = shift_output_template (p, ce_out, max_op);
738 *p++ = ' ';
742 *p++ = *insn_out++;
743 while (*insn_out && *insn_out != '\n');
745 while (*insn_out);
746 *p = '\0';
748 else
750 len = ce_len + 1 + insn_len + 1;
751 result = XNEWVEC (char, len);
753 p = shift_output_template (result, ce_out, max_op);
754 *p++ = ' ';
755 memcpy (p, insn_out, insn_len + 1);
758 return result;
761 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
763 static void
764 process_one_cond_exec (struct queue_elem *ce_elem)
766 struct queue_elem *insn_elem;
767 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
769 int alternatives, max_operand;
770 rtx pred, insn, pattern, split;
771 int i;
773 if (! is_predicable (insn_elem))
774 continue;
776 alternatives = 1;
777 max_operand = -1;
778 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
779 max_operand += 1;
781 if (XVECLEN (ce_elem->data, 0) != 1)
783 message_with_line (ce_elem->lineno,
784 "too many patterns in predicate");
785 errors = 1;
786 return;
789 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
790 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
791 ce_elem->lineno);
792 if (pred == NULL)
793 return;
795 /* Construct a new pattern for the new insn. */
796 insn = copy_rtx (insn_elem->data);
797 XSTR (insn, 0) = "";
798 pattern = rtx_alloc (COND_EXEC);
799 XEXP (pattern, 0) = pred;
800 if (XVECLEN (insn, 1) == 1)
802 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
803 XVECEXP (insn, 1, 0) = pattern;
804 PUT_NUM_ELEM (XVEC (insn, 1), 1);
806 else
808 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
809 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
810 XVEC (insn, 1) = rtvec_alloc (1);
811 XVECEXP (insn, 1, 0) = pattern;
814 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
815 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
816 alternatives, max_operand);
818 /* ??? Set `predicable' to false. Not crucial since it's really
819 only used here, and we won't reprocess this new pattern. */
821 /* Put the new pattern on the `other' list so that it
822 (a) is not reprocessed by other define_cond_exec patterns
823 (b) appears after all normal define_insn patterns.
825 ??? B is debatable. If one has normal insns that match
826 cond_exec patterns, they will be preferred over these
827 generated patterns. Whether this matters in practice, or if
828 it's a good thing, or whether we should thread these new
829 patterns into the define_insn chain just after their generator
830 is something we'll have to experiment with. */
832 queue_pattern (insn, &other_tail, insn_elem->filename,
833 insn_elem->lineno);
835 if (!insn_elem->split)
836 continue;
838 /* If the original insn came from a define_insn_and_split,
839 generate a new split to handle the predicated insn. */
840 split = copy_rtx (insn_elem->split->data);
841 /* Predicate the pattern matched by the split. */
842 pattern = rtx_alloc (COND_EXEC);
843 XEXP (pattern, 0) = pred;
844 if (XVECLEN (split, 0) == 1)
846 XEXP (pattern, 1) = XVECEXP (split, 0, 0);
847 XVECEXP (split, 0, 0) = pattern;
848 PUT_NUM_ELEM (XVEC (split, 0), 1);
850 else
852 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
853 XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
854 XVEC (split, 0) = rtvec_alloc (1);
855 XVECEXP (split, 0, 0) = pattern;
857 /* Predicate all of the insns generated by the split. */
858 for (i = 0; i < XVECLEN (split, 2); i++)
860 pattern = rtx_alloc (COND_EXEC);
861 XEXP (pattern, 0) = pred;
862 XEXP (pattern, 1) = XVECEXP (split, 2, i);
863 XVECEXP (split, 2, i) = pattern;
865 /* Add the new split to the queue. */
866 queue_pattern (split, &other_tail, read_rtx_filename,
867 insn_elem->split->lineno);
871 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
872 patterns appropriately. */
874 static void
875 process_define_cond_exec (void)
877 struct queue_elem *elem;
879 identify_predicable_attribute ();
880 if (errors)
881 return;
883 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
884 process_one_cond_exec (elem);
887 static char *
888 save_string (const char *s, int len)
890 char *result = XNEWVEC (char, len + 1);
892 memcpy (result, s, len);
893 result[len] = 0;
894 return result;
898 /* The entry point for initializing the reader. */
901 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
903 FILE *input_file;
904 int i;
905 size_t ix;
906 char *lastsl;
907 const char *in_fname;
909 max_include_len = 0;
910 in_fname = NULL;
911 for (i = 1; i < argc; i++)
913 if (argv[i][0] != '-')
915 if (in_fname)
916 fatal ("too many input files");
918 in_fname = argv[i];
920 else
922 int c = argv[i][1];
923 switch (c)
925 case 'I': /* Add directory to path for includes. */
927 struct file_name_list *dirtmp;
929 dirtmp = XNEW (struct file_name_list);
930 dirtmp->next = 0; /* New one goes on the end */
931 if (first_dir_md_include == 0)
932 first_dir_md_include = dirtmp;
933 else
934 last_dir_md_include->next = dirtmp;
935 last_dir_md_include = dirtmp; /* Tail follows the last one */
936 if (argv[i][1] == 'I' && argv[i][2] != 0)
937 dirtmp->fname = argv[i] + 2;
938 else if (i + 1 == argc)
939 fatal ("directory name missing after -I option");
940 else
941 dirtmp->fname = argv[++i];
942 if (strlen (dirtmp->fname) > max_include_len)
943 max_include_len = strlen (dirtmp->fname);
945 break;
946 default:
947 /* The program may have provided a callback so it can
948 accept its own options. */
949 if (parse_opt && parse_opt (argv[i]))
950 break;
952 fatal ("invalid option `%s'", argv[i]);
957 if (!in_fname)
958 fatal ("no input file name");
960 lastsl = strrchr (in_fname, '/');
961 if (lastsl != NULL)
962 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
964 read_rtx_filename = in_fname;
965 input_file = fopen (in_fname, "r");
966 if (input_file == 0)
968 perror (in_fname);
969 return FATAL_EXIT_CODE;
972 /* Initialize the table of insn conditions. */
973 condition_table = htab_create (n_insn_conditions,
974 hash_c_test, cmp_c_test, NULL);
976 for (ix = 0; ix < n_insn_conditions; ix++)
977 *(htab_find_slot (condition_table, &insn_conditions[ix], INSERT))
978 = (void *) &insn_conditions[ix];
980 obstack_init (rtl_obstack);
981 errors = 0;
982 sequence_num = 0;
984 /* Read the entire file. */
985 while (1)
987 rtx desc;
988 int lineno;
989 int c = read_skip_spaces (input_file);
990 if (c == EOF)
991 break;
993 ungetc (c, input_file);
994 lineno = read_rtx_lineno;
995 desc = read_rtx (input_file);
996 process_rtx (desc, lineno);
998 fclose (input_file);
1000 /* Process define_cond_exec patterns. */
1001 if (define_cond_exec_queue != NULL)
1002 process_define_cond_exec ();
1004 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1007 /* Programs that don't have their own options can use this entry point
1008 instead. */
1010 init_md_reader_args (int argc, char **argv)
1012 return init_md_reader_args_cb (argc, argv, 0);
1015 /* The entry point for reading a single rtx from an md file. */
1018 read_md_rtx (int *lineno, int *seqnr)
1020 struct queue_elem **queue, *elem;
1021 rtx desc;
1023 discard:
1025 /* Read all patterns from a given queue before moving on to the next. */
1026 if (define_attr_queue != NULL)
1027 queue = &define_attr_queue;
1028 else if (define_insn_queue != NULL)
1029 queue = &define_insn_queue;
1030 else if (other_queue != NULL)
1031 queue = &other_queue;
1032 else
1033 return NULL_RTX;
1035 elem = *queue;
1036 *queue = elem->next;
1037 desc = elem->data;
1038 read_rtx_filename = elem->filename;
1039 *lineno = elem->lineno;
1040 *seqnr = sequence_num;
1042 free (elem);
1044 /* Discard insn patterns which we know can never match (because
1045 their C test is provably always false). If insn_elision is
1046 false, our caller needs to see all the patterns. Note that the
1047 elided patterns are never counted by the sequence numbering; it
1048 it is the caller's responsibility, when insn_elision is false, not
1049 to use elided pattern numbers for anything. */
1050 switch (GET_CODE (desc))
1052 case DEFINE_INSN:
1053 case DEFINE_EXPAND:
1054 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1055 sequence_num++;
1056 else if (insn_elision)
1057 goto discard;
1058 break;
1060 case DEFINE_SPLIT:
1061 case DEFINE_PEEPHOLE:
1062 case DEFINE_PEEPHOLE2:
1063 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1064 sequence_num++;
1065 else if (insn_elision)
1066 goto discard;
1067 break;
1069 default:
1070 break;
1073 return desc;
1076 /* Helper functions for insn elision. */
1078 /* Compute a hash function of a c_test structure, which is keyed
1079 by its ->expr field. */
1080 hashval_t
1081 hash_c_test (const void *x)
1083 const struct c_test *a = (const struct c_test *) x;
1084 const unsigned char *base, *s = (const unsigned char *) a->expr;
1085 hashval_t hash;
1086 unsigned char c;
1087 unsigned int len;
1089 base = s;
1090 hash = 0;
1092 while ((c = *s++) != '\0')
1094 hash += c + (c << 17);
1095 hash ^= hash >> 2;
1098 len = s - base;
1099 hash += len + (len << 17);
1100 hash ^= hash >> 2;
1102 return hash;
1105 /* Compare two c_test expression structures. */
1107 cmp_c_test (const void *x, const void *y)
1109 const struct c_test *a = (const struct c_test *) x;
1110 const struct c_test *b = (const struct c_test *) y;
1112 return !strcmp (a->expr, b->expr);
1115 /* Given a string representing a C test expression, look it up in the
1116 condition_table and report whether or not its value is known
1117 at compile time. Returns a tristate: 1 for known true, 0 for
1118 known false, -1 for unknown. */
1120 maybe_eval_c_test (const char *expr)
1122 const struct c_test *test;
1123 struct c_test dummy;
1125 if (expr[0] == 0)
1126 return 1;
1128 if (insn_elision_unavailable)
1129 return -1;
1131 dummy.expr = expr;
1132 test = (const struct c_test *)htab_find (condition_table, &dummy);
1133 if (!test)
1134 abort ();
1136 return test->value;
1139 /* Given a string, return the number of comma-separated elements in it.
1140 Return 0 for the null string. */
1142 n_comma_elts (const char *s)
1144 int n;
1146 if (*s == '\0')
1147 return 0;
1149 for (n = 1; *s; s++)
1150 if (*s == ',')
1151 n++;
1153 return n;
1156 /* Given a pointer to a (char *), return a pointer to the beginning of the
1157 next comma-separated element in the string. Advance the pointer given
1158 to the end of that element. Return NULL if at end of string. Caller
1159 is responsible for copying the string if necessary. White space between
1160 a comma and an element is ignored. */
1162 const char *
1163 scan_comma_elt (const char **pstr)
1165 const char *start;
1166 const char *p = *pstr;
1168 if (*p == ',')
1169 p++;
1170 while (ISSPACE(*p))
1171 p++;
1173 if (*p == '\0')
1174 return NULL;
1176 start = p;
1178 while (*p != ',' && *p != '\0')
1179 p++;
1181 *pstr = p;
1182 return start;