gensupport.c revision 132718
1/* Support routines for the various generation passes.
2   Copyright (C) 2000, 2001, 2002, 2003, 2004
3   Free Software Foundation, Inc.
4
5   This file is part of GCC.
6
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.
11
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.
16
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.  */
21
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"
31
32
33/* In case some macros used by files we include need it, define this here.  */
34int target_flags;
35
36int insn_elision = 1;
37
38static struct obstack obstack;
39struct obstack *rtl_obstack = &obstack;
40
41static int sequence_num;
42static int errors;
43
44static int predicable_default;
45static const char *predicable_true;
46static const char *predicable_false;
47
48static htab_t condition_table;
49
50static char *base_dir = NULL;
51
52/* We initially queue all patterns, process the define_insn and
53   define_cond_exec patterns, then return them one at a time.  */
54
55struct queue_elem
56{
57  rtx data;
58  const char *filename;
59  int lineno;
60  struct queue_elem *next;
61};
62
63static struct queue_elem *define_attr_queue;
64static struct queue_elem **define_attr_tail = &define_attr_queue;
65static struct queue_elem *define_insn_queue;
66static struct queue_elem **define_insn_tail = &define_insn_queue;
67static struct queue_elem *define_cond_exec_queue;
68static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
69static struct queue_elem *other_queue;
70static struct queue_elem **other_tail = &other_queue;
71
72static void queue_pattern (rtx, struct queue_elem ***,
73			   const char *, int);
74
75/* Current maximum length of directory names in the search path
76   for include files.  (Altered as we get more of them.)  */
77
78size_t max_include_len;
79
80struct file_name_list
81  {
82    struct file_name_list *next;
83    const char *fname;
84  };
85
86struct file_name_list *first_dir_md_include = 0;  /* First dir to search */
87        /* First dir to search for <file> */
88struct file_name_list *first_bracket_include = 0;
89struct file_name_list *last_dir_md_include = 0;        /* Last in chain */
90
91static void remove_constraints (rtx);
92static void process_rtx (rtx, int);
93
94static int is_predicable (struct queue_elem *);
95static void identify_predicable_attribute (void);
96static int n_alternatives (const char *);
97static void collect_insn_data (rtx, int *, int *);
98static rtx alter_predicate_for_insn (rtx, int, int, int);
99static const char *alter_test_for_insn (struct queue_elem *,
100					struct queue_elem *);
101static char *shift_output_template (char *, const char *, int);
102static const char *alter_output_for_insn (struct queue_elem *,
103					  struct queue_elem *,
104					  int, int);
105static void process_one_cond_exec (struct queue_elem *);
106static void process_define_cond_exec (void);
107static void process_include (rtx, int);
108static char *save_string (const char *, int);
109
110void
111message_with_line (int lineno, const char *msg, ...)
112{
113  va_list ap;
114
115  va_start (ap, msg);
116
117  fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
118  vfprintf (stderr, msg, ap);
119  fputc ('\n', stderr);
120
121  va_end (ap);
122}
123
124/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
125   the gensupport programs.  */
126
127rtx
128gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
129		   HOST_WIDE_INT arg)
130{
131  rtx rt = rtx_alloc (CONST_INT);
132
133  XWINT (rt, 0) = arg;
134  return rt;
135}
136
137/* Queue PATTERN on LIST_TAIL.  */
138
139static void
140queue_pattern (rtx pattern, struct queue_elem ***list_tail,
141	       const char *filename, int lineno)
142{
143  struct queue_elem *e = xmalloc (sizeof (*e));
144  e->data = pattern;
145  e->filename = filename;
146  e->lineno = lineno;
147  e->next = NULL;
148  **list_tail = e;
149  *list_tail = &e->next;
150}
151
152/* Recursively remove constraints from an rtx.  */
153
154static void
155remove_constraints (rtx part)
156{
157  int i, j;
158  const char *format_ptr;
159
160  if (part == 0)
161    return;
162
163  if (GET_CODE (part) == MATCH_OPERAND)
164    XSTR (part, 2) = "";
165  else if (GET_CODE (part) == MATCH_SCRATCH)
166    XSTR (part, 1) = "";
167
168  format_ptr = GET_RTX_FORMAT (GET_CODE (part));
169
170  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
171    switch (*format_ptr++)
172      {
173      case 'e':
174      case 'u':
175	remove_constraints (XEXP (part, i));
176	break;
177      case 'E':
178	if (XVEC (part, i) != NULL)
179	  for (j = 0; j < XVECLEN (part, i); j++)
180	    remove_constraints (XVECEXP (part, i, j));
181	break;
182      }
183}
184
185/* Process an include file assuming that it lives in gcc/config/{target}/
186   if the include looks like (include "file").  */
187
188static void
189process_include (rtx desc, int lineno)
190{
191  const char *filename = XSTR (desc, 0);
192  const char *old_filename;
193  int old_lineno;
194  char *pathname;
195  FILE *input_file;
196
197  /* If specified file name is absolute, skip the include stack.  */
198  if (! IS_ABSOLUTE_PATH (filename))
199    {
200      struct file_name_list *stackp;
201
202      /* Search directory path, trying to open the file.  */
203      for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
204	{
205	  static const char sep[2] = { DIR_SEPARATOR, '\0' };
206
207	  pathname = concat (stackp->fname, sep, filename, NULL);
208	  input_file = fopen (pathname, "r");
209	  if (input_file != NULL)
210	    goto success;
211	  free (pathname);
212	}
213    }
214
215  if (base_dir)
216    pathname = concat (base_dir, filename, NULL);
217  else
218    pathname = xstrdup (filename);
219  input_file = fopen (pathname, "r");
220  if (input_file == NULL)
221    {
222      free (pathname);
223      message_with_line (lineno, "include file `%s' not found", filename);
224      errors = 1;
225      return;
226    }
227 success:
228
229  /* Save old cursor; setup new for the new file.  Note that "lineno" the
230     argument to this function is the beginning of the include statement,
231     while read_rtx_lineno has already been advanced.  */
232  old_filename = read_rtx_filename;
233  old_lineno = read_rtx_lineno;
234  read_rtx_filename = pathname;
235  read_rtx_lineno = 1;
236
237  /* Read the entire file.  */
238  while (1)
239    {
240      rtx desc;
241      int c;
242
243      c = read_skip_spaces (input_file);
244      if (c == EOF)
245	break;
246
247      ungetc (c, input_file);
248      lineno = read_rtx_lineno;
249      desc = read_rtx (input_file);
250      process_rtx (desc, lineno);
251    }
252
253  /* Do not free pathname.  It is attached to the various rtx queue
254     elements.  */
255
256  read_rtx_filename = old_filename;
257  read_rtx_lineno = old_lineno;
258
259  fclose (input_file);
260}
261
262/* Process a top level rtx in some way, queuing as appropriate.  */
263
264static void
265process_rtx (rtx desc, int lineno)
266{
267  switch (GET_CODE (desc))
268    {
269    case DEFINE_INSN:
270      queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
271      break;
272
273    case DEFINE_COND_EXEC:
274      queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
275      break;
276
277    case DEFINE_ATTR:
278      queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
279      break;
280
281    case INCLUDE:
282      process_include (desc, lineno);
283      break;
284
285    case DEFINE_INSN_AND_SPLIT:
286      {
287	const char *split_cond;
288	rtx split;
289	rtvec attr;
290	int i;
291
292	/* Create a split with values from the insn_and_split.  */
293	split = rtx_alloc (DEFINE_SPLIT);
294
295	i = XVECLEN (desc, 1);
296	XVEC (split, 0) = rtvec_alloc (i);
297	while (--i >= 0)
298	  {
299	    XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
300	    remove_constraints (XVECEXP (split, 0, i));
301	  }
302
303	/* If the split condition starts with "&&", append it to the
304	   insn condition to create the new split condition.  */
305	split_cond = XSTR (desc, 4);
306	if (split_cond[0] == '&' && split_cond[1] == '&')
307	  split_cond = concat (XSTR (desc, 2), split_cond, NULL);
308	XSTR (split, 1) = split_cond;
309	XVEC (split, 2) = XVEC (desc, 5);
310	XSTR (split, 3) = XSTR (desc, 6);
311
312	/* Fix up the DEFINE_INSN.  */
313	attr = XVEC (desc, 7);
314	PUT_CODE (desc, DEFINE_INSN);
315	XVEC (desc, 4) = attr;
316
317	/* Queue them.  */
318	queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
319	queue_pattern (split, &other_tail, read_rtx_filename, lineno);
320	break;
321      }
322
323    default:
324      queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
325      break;
326    }
327}
328
329/* Return true if attribute PREDICABLE is true for ELEM, which holds
330   a DEFINE_INSN.  */
331
332static int
333is_predicable (struct queue_elem *elem)
334{
335  rtvec vec = XVEC (elem->data, 4);
336  const char *value;
337  int i;
338
339  if (! vec)
340    return predicable_default;
341
342  for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
343    {
344      rtx sub = RTVEC_ELT (vec, i);
345      switch (GET_CODE (sub))
346	{
347	case SET_ATTR:
348	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
349	    {
350	      value = XSTR (sub, 1);
351	      goto found;
352	    }
353	  break;
354
355	case SET_ATTR_ALTERNATIVE:
356	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
357	    {
358	      message_with_line (elem->lineno,
359				 "multiple alternatives for `predicable'");
360	      errors = 1;
361	      return 0;
362	    }
363	  break;
364
365	case SET:
366	  if (GET_CODE (SET_DEST (sub)) != ATTR
367	      || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
368	    break;
369	  sub = SET_SRC (sub);
370	  if (GET_CODE (sub) == CONST_STRING)
371	    {
372	      value = XSTR (sub, 0);
373	      goto found;
374	    }
375
376	  /* ??? It would be possible to handle this if we really tried.
377	     It's not easy though, and I'm not going to bother until it
378	     really proves necessary.  */
379	  message_with_line (elem->lineno,
380			     "non-constant value for `predicable'");
381	  errors = 1;
382	  return 0;
383
384	default:
385	  abort ();
386	}
387    }
388
389  return predicable_default;
390
391 found:
392  /* Verify that predicability does not vary on the alternative.  */
393  /* ??? It should be possible to handle this by simply eliminating
394     the non-predicable alternatives from the insn.  FRV would like
395     to do this.  Delay this until we've got the basics solid.  */
396  if (strchr (value, ',') != NULL)
397    {
398      message_with_line (elem->lineno,
399			 "multiple alternatives for `predicable'");
400      errors = 1;
401      return 0;
402    }
403
404  /* Find out which value we're looking at.  */
405  if (strcmp (value, predicable_true) == 0)
406    return 1;
407  if (strcmp (value, predicable_false) == 0)
408    return 0;
409
410  message_with_line (elem->lineno,
411		     "unknown value `%s' for `predicable' attribute",
412		     value);
413  errors = 1;
414  return 0;
415}
416
417/* Examine the attribute "predicable"; discover its boolean values
418   and its default.  */
419
420static void
421identify_predicable_attribute (void)
422{
423  struct queue_elem *elem;
424  char *p_true, *p_false;
425  const char *value;
426
427  /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
428  for (elem = define_attr_queue; elem ; elem = elem->next)
429    if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
430      goto found;
431
432  message_with_line (define_cond_exec_queue->lineno,
433		     "attribute `predicable' not defined");
434  errors = 1;
435  return;
436
437 found:
438  value = XSTR (elem->data, 1);
439  p_false = xstrdup (value);
440  p_true = strchr (p_false, ',');
441  if (p_true == NULL || strchr (++p_true, ',') != NULL)
442    {
443      message_with_line (elem->lineno,
444			 "attribute `predicable' is not a boolean");
445      errors = 1;
446      return;
447    }
448  p_true[-1] = '\0';
449
450  predicable_true = p_true;
451  predicable_false = p_false;
452
453  switch (GET_CODE (XEXP (elem->data, 2)))
454    {
455    case CONST_STRING:
456      value = XSTR (XEXP (elem->data, 2), 0);
457      break;
458
459    case CONST:
460      message_with_line (elem->lineno,
461			 "attribute `predicable' cannot be const");
462      errors = 1;
463      return;
464
465    default:
466      message_with_line (elem->lineno,
467			 "attribute `predicable' must have a constant default");
468      errors = 1;
469      return;
470    }
471
472  if (strcmp (value, p_true) == 0)
473    predicable_default = 1;
474  else if (strcmp (value, p_false) == 0)
475    predicable_default = 0;
476  else
477    {
478      message_with_line (elem->lineno,
479			 "unknown value `%s' for `predicable' attribute",
480			 value);
481      errors = 1;
482    }
483}
484
485/* Return the number of alternatives in constraint S.  */
486
487static int
488n_alternatives (const char *s)
489{
490  int n = 1;
491
492  if (s)
493    while (*s)
494      n += (*s++ == ',');
495
496  return n;
497}
498
499/* Determine how many alternatives there are in INSN, and how many
500   operands.  */
501
502static void
503collect_insn_data (rtx pattern, int *palt, int *pmax)
504{
505  const char *fmt;
506  enum rtx_code code;
507  int i, j, len;
508
509  code = GET_CODE (pattern);
510  switch (code)
511    {
512    case MATCH_OPERAND:
513      i = n_alternatives (XSTR (pattern, 2));
514      *palt = (i > *palt ? i : *palt);
515      /* Fall through.  */
516
517    case MATCH_OPERATOR:
518    case MATCH_SCRATCH:
519    case MATCH_PARALLEL:
520    case MATCH_INSN:
521      i = XINT (pattern, 0);
522      if (i > *pmax)
523	*pmax = i;
524      break;
525
526    default:
527      break;
528    }
529
530  fmt = GET_RTX_FORMAT (code);
531  len = GET_RTX_LENGTH (code);
532  for (i = 0; i < len; i++)
533    {
534      switch (fmt[i])
535	{
536	case 'e': case 'u':
537	  collect_insn_data (XEXP (pattern, i), palt, pmax);
538	  break;
539
540	case 'V':
541	  if (XVEC (pattern, i) == NULL)
542	    break;
543	  /* Fall through.  */
544	case 'E':
545	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
546	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
547	  break;
548
549	case 'i': case 'w': case '0': case 's': case 'S': case 'T':
550	  break;
551
552	default:
553	  abort ();
554	}
555    }
556}
557
558static rtx
559alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
560{
561  const char *fmt;
562  enum rtx_code code;
563  int i, j, len;
564
565  code = GET_CODE (pattern);
566  switch (code)
567    {
568    case MATCH_OPERAND:
569      {
570	const char *c = XSTR (pattern, 2);
571
572	if (n_alternatives (c) != 1)
573	  {
574	    message_with_line (lineno,
575			       "too many alternatives for operand %d",
576			       XINT (pattern, 0));
577	    errors = 1;
578	    return NULL;
579	  }
580
581	/* Replicate C as needed to fill out ALT alternatives.  */
582	if (c && *c && alt > 1)
583	  {
584	    size_t c_len = strlen (c);
585	    size_t len = alt * (c_len + 1);
586	    char *new_c = xmalloc (len);
587
588	    memcpy (new_c, c, c_len);
589	    for (i = 1; i < alt; ++i)
590	      {
591		new_c[i * (c_len + 1) - 1] = ',';
592		memcpy (&new_c[i * (c_len + 1)], c, c_len);
593	      }
594	    new_c[len - 1] = '\0';
595	    XSTR (pattern, 2) = new_c;
596	  }
597      }
598      /* Fall through.  */
599
600    case MATCH_OPERATOR:
601    case MATCH_SCRATCH:
602    case MATCH_PARALLEL:
603    case MATCH_INSN:
604      XINT (pattern, 0) += max_op;
605      break;
606
607    default:
608      break;
609    }
610
611  fmt = GET_RTX_FORMAT (code);
612  len = GET_RTX_LENGTH (code);
613  for (i = 0; i < len; i++)
614    {
615      rtx r;
616
617      switch (fmt[i])
618	{
619	case 'e': case 'u':
620	  r = alter_predicate_for_insn (XEXP (pattern, i), alt,
621					max_op, lineno);
622	  if (r == NULL)
623	    return r;
624	  break;
625
626	case 'E':
627	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
628	    {
629	      r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
630					    alt, max_op, lineno);
631	      if (r == NULL)
632		return r;
633	    }
634	  break;
635
636	case 'i': case 'w': case '0': case 's':
637	  break;
638
639	default:
640	  abort ();
641	}
642    }
643
644  return pattern;
645}
646
647static const char *
648alter_test_for_insn (struct queue_elem *ce_elem,
649		     struct queue_elem *insn_elem)
650{
651  const char *ce_test, *insn_test;
652
653  ce_test = XSTR (ce_elem->data, 1);
654  insn_test = XSTR (insn_elem->data, 2);
655  if (!ce_test || *ce_test == '\0')
656    return insn_test;
657  if (!insn_test || *insn_test == '\0')
658    return ce_test;
659
660  return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
661}
662
663/* Adjust all of the operand numbers in OLD to match the shift they'll
664   get from an operand displacement of DISP.  Return a pointer after the
665   adjusted string.  */
666
667static char *
668shift_output_template (char *new, const char *old, int disp)
669{
670  while (*old)
671    {
672      char c = *old++;
673      *new++ = c;
674      if (c == '%')
675	{
676	  c = *old++;
677	  if (ISDIGIT ((unsigned char) c))
678	    c += disp;
679	  else if (ISALPHA (c))
680	    {
681	      *new++ = c;
682	      c = *old++ + disp;
683	    }
684	  *new++ = c;
685	}
686    }
687
688  return new;
689}
690
691static const char *
692alter_output_for_insn (struct queue_elem *ce_elem,
693		       struct queue_elem *insn_elem,
694		       int alt, int max_op)
695{
696  const char *ce_out, *insn_out;
697  char *new, *p;
698  size_t len, ce_len, insn_len;
699
700  /* ??? Could coordinate with genoutput to not duplicate code here.  */
701
702  ce_out = XSTR (ce_elem->data, 2);
703  insn_out = XTMPL (insn_elem->data, 3);
704  if (!ce_out || *ce_out == '\0')
705    return insn_out;
706
707  ce_len = strlen (ce_out);
708  insn_len = strlen (insn_out);
709
710  if (*insn_out == '*')
711    /* You must take care of the predicate yourself.  */
712    return insn_out;
713
714  if (*insn_out == '@')
715    {
716      len = (ce_len + 1) * alt + insn_len + 1;
717      p = new = xmalloc (len);
718
719      do
720	{
721	  do
722	    *p++ = *insn_out++;
723	  while (ISSPACE ((unsigned char) *insn_out));
724
725	  if (*insn_out != '#')
726	    {
727	      p = shift_output_template (p, ce_out, max_op);
728	      *p++ = ' ';
729	    }
730
731	  do
732	    *p++ = *insn_out++;
733	  while (*insn_out && *insn_out != '\n');
734	}
735      while (*insn_out);
736      *p = '\0';
737    }
738  else
739    {
740      len = ce_len + 1 + insn_len + 1;
741      new = xmalloc (len);
742
743      p = shift_output_template (new, ce_out, max_op);
744      *p++ = ' ';
745      memcpy (p, insn_out, insn_len + 1);
746    }
747
748  return new;
749}
750
751/* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
752
753static void
754process_one_cond_exec (struct queue_elem *ce_elem)
755{
756  struct queue_elem *insn_elem;
757  for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
758    {
759      int alternatives, max_operand;
760      rtx pred, insn, pattern;
761
762      if (! is_predicable (insn_elem))
763	continue;
764
765      alternatives = 1;
766      max_operand = -1;
767      collect_insn_data (insn_elem->data, &alternatives, &max_operand);
768      max_operand += 1;
769
770      if (XVECLEN (ce_elem->data, 0) != 1)
771	{
772	  message_with_line (ce_elem->lineno,
773			     "too many patterns in predicate");
774	  errors = 1;
775	  return;
776	}
777
778      pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
779      pred = alter_predicate_for_insn (pred, alternatives, max_operand,
780				       ce_elem->lineno);
781      if (pred == NULL)
782	return;
783
784      /* Construct a new pattern for the new insn.  */
785      insn = copy_rtx (insn_elem->data);
786      XSTR (insn, 0) = "";
787      pattern = rtx_alloc (COND_EXEC);
788      XEXP (pattern, 0) = pred;
789      if (XVECLEN (insn, 1) == 1)
790	{
791	  XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
792	  XVECEXP (insn, 1, 0) = pattern;
793	  PUT_NUM_ELEM (XVEC (insn, 1), 1);
794	}
795      else
796	{
797	  XEXP (pattern, 1) = rtx_alloc (PARALLEL);
798	  XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
799	  XVEC (insn, 1) = rtvec_alloc (1);
800	  XVECEXP (insn, 1, 0) = pattern;
801	}
802
803      XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
804      XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
805					      alternatives, max_operand);
806
807      /* ??? Set `predicable' to false.  Not crucial since it's really
808         only used here, and we won't reprocess this new pattern.  */
809
810      /* Put the new pattern on the `other' list so that it
811	 (a) is not reprocessed by other define_cond_exec patterns
812	 (b) appears after all normal define_insn patterns.
813
814	 ??? B is debatable.  If one has normal insns that match
815	 cond_exec patterns, they will be preferred over these
816	 generated patterns.  Whether this matters in practice, or if
817	 it's a good thing, or whether we should thread these new
818	 patterns into the define_insn chain just after their generator
819	 is something we'll have to experiment with.  */
820
821      queue_pattern (insn, &other_tail, insn_elem->filename,
822		     insn_elem->lineno);
823    }
824}
825
826/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
827   patterns appropriately.  */
828
829static void
830process_define_cond_exec (void)
831{
832  struct queue_elem *elem;
833
834  identify_predicable_attribute ();
835  if (errors)
836    return;
837
838  for (elem = define_cond_exec_queue; elem ; elem = elem->next)
839    process_one_cond_exec (elem);
840}
841
842static char *
843save_string (const char *s, int len)
844{
845  char *result = xmalloc (len + 1);
846
847  memcpy (result, s, len);
848  result[len] = 0;
849  return result;
850}
851
852
853/* The entry point for initializing the reader.  */
854
855int
856init_md_reader_args (int argc, char **argv)
857{
858  int i;
859  const char *in_fname;
860
861  max_include_len = 0;
862  in_fname = NULL;
863  for (i = 1; i < argc; i++)
864    {
865      if (argv[i][0] != '-')
866	{
867	  if (in_fname == NULL)
868	    in_fname = argv[i];
869	}
870      else
871	{
872	  int c = argv[i][1];
873	  switch (c)
874	    {
875	    case 'I':		/* Add directory to path for includes.  */
876	      {
877		struct file_name_list *dirtmp;
878
879		dirtmp = xmalloc (sizeof (struct file_name_list));
880		dirtmp->next = 0;	/* New one goes on the end */
881		if (first_dir_md_include == 0)
882		  first_dir_md_include = dirtmp;
883		else
884		  last_dir_md_include->next = dirtmp;
885		last_dir_md_include = dirtmp;	/* Tail follows the last one */
886		if (argv[i][1] == 'I' && argv[i][2] != 0)
887		  dirtmp->fname = argv[i] + 2;
888		else if (i + 1 == argc)
889		  fatal ("directory name missing after -I option");
890		else
891		  dirtmp->fname = argv[++i];
892		if (strlen (dirtmp->fname) > max_include_len)
893		  max_include_len = strlen (dirtmp->fname);
894	      }
895	      break;
896	    default:
897	      fatal ("invalid option `%s'", argv[i]);
898
899	    }
900	}
901    }
902    return init_md_reader (in_fname);
903}
904
905/* The entry point for initializing the reader.  */
906
907int
908init_md_reader (const char *filename)
909{
910  FILE *input_file;
911  int c;
912  size_t i;
913  char *lastsl;
914
915  lastsl = strrchr (filename, '/');
916  if (lastsl != NULL)
917    base_dir = save_string (filename, lastsl - filename + 1 );
918
919  read_rtx_filename = filename;
920  input_file = fopen (filename, "r");
921  if (input_file == 0)
922    {
923      perror (filename);
924      return FATAL_EXIT_CODE;
925    }
926
927  /* Initialize the table of insn conditions.  */
928  condition_table = htab_create (n_insn_conditions,
929				 hash_c_test, cmp_c_test, NULL);
930
931  for (i = 0; i < n_insn_conditions; i++)
932    *(htab_find_slot (condition_table, &insn_conditions[i], INSERT))
933      = (void *) &insn_conditions[i];
934
935  obstack_init (rtl_obstack);
936  errors = 0;
937  sequence_num = 0;
938
939  /* Read the entire file.  */
940  while (1)
941    {
942      rtx desc;
943      int lineno;
944
945      c = read_skip_spaces (input_file);
946      if (c == EOF)
947        break;
948
949      ungetc (c, input_file);
950      lineno = read_rtx_lineno;
951      desc = read_rtx (input_file);
952      process_rtx (desc, lineno);
953    }
954  fclose (input_file);
955
956  /* Process define_cond_exec patterns.  */
957  if (define_cond_exec_queue != NULL)
958    process_define_cond_exec ();
959
960  return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
961}
962
963/* The entry point for reading a single rtx from an md file.  */
964
965rtx
966read_md_rtx (int *lineno, int *seqnr)
967{
968  struct queue_elem **queue, *elem;
969  rtx desc;
970
971 discard:
972
973  /* Read all patterns from a given queue before moving on to the next.  */
974  if (define_attr_queue != NULL)
975    queue = &define_attr_queue;
976  else if (define_insn_queue != NULL)
977    queue = &define_insn_queue;
978  else if (other_queue != NULL)
979    queue = &other_queue;
980  else
981    return NULL_RTX;
982
983  elem = *queue;
984  *queue = elem->next;
985  desc = elem->data;
986  read_rtx_filename = elem->filename;
987  *lineno = elem->lineno;
988  *seqnr = sequence_num;
989
990  free (elem);
991
992  /* Discard insn patterns which we know can never match (because
993     their C test is provably always false).  If insn_elision is
994     false, our caller needs to see all the patterns.  Note that the
995     elided patterns are never counted by the sequence numbering; it
996     it is the caller's responsibility, when insn_elision is false, not
997     to use elided pattern numbers for anything.  */
998  switch (GET_CODE (desc))
999    {
1000    case DEFINE_INSN:
1001    case DEFINE_EXPAND:
1002      if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1003	sequence_num++;
1004      else if (insn_elision)
1005	goto discard;
1006      break;
1007
1008    case DEFINE_SPLIT:
1009    case DEFINE_PEEPHOLE:
1010    case DEFINE_PEEPHOLE2:
1011      if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1012	sequence_num++;
1013      else if (insn_elision)
1014	    goto discard;
1015      break;
1016
1017    default:
1018      break;
1019    }
1020
1021  return desc;
1022}
1023
1024/* Helper functions for insn elision.  */
1025
1026/* Compute a hash function of a c_test structure, which is keyed
1027   by its ->expr field.  */
1028hashval_t
1029hash_c_test (const void *x)
1030{
1031  const struct c_test *a = (const struct c_test *) x;
1032  const unsigned char *base, *s = (const unsigned char *) a->expr;
1033  hashval_t hash;
1034  unsigned char c;
1035  unsigned int len;
1036
1037  base = s;
1038  hash = 0;
1039
1040  while ((c = *s++) != '\0')
1041    {
1042      hash += c + (c << 17);
1043      hash ^= hash >> 2;
1044    }
1045
1046  len = s - base;
1047  hash += len + (len << 17);
1048  hash ^= hash >> 2;
1049
1050  return hash;
1051}
1052
1053/* Compare two c_test expression structures.  */
1054int
1055cmp_c_test (const void *x, const void *y)
1056{
1057  const struct c_test *a = (const struct c_test *) x;
1058  const struct c_test *b = (const struct c_test *) y;
1059
1060  return !strcmp (a->expr, b->expr);
1061}
1062
1063/* Given a string representing a C test expression, look it up in the
1064   condition_table and report whether or not its value is known
1065   at compile time.  Returns a tristate: 1 for known true, 0 for
1066   known false, -1 for unknown.  */
1067int
1068maybe_eval_c_test (const char *expr)
1069{
1070  const struct c_test *test;
1071  struct c_test dummy;
1072
1073  if (expr[0] == 0)
1074    return 1;
1075
1076  if (insn_elision_unavailable)
1077    return -1;
1078
1079  dummy.expr = expr;
1080  test = htab_find (condition_table, &dummy);
1081  if (!test)
1082    abort ();
1083
1084  return test->value;
1085}
1086
1087/* Given a string, return the number of comma-separated elements in it.
1088   Return 0 for the null string.  */
1089int
1090n_comma_elts (const char *s)
1091{
1092  int n;
1093
1094  if (*s == '\0')
1095    return 0;
1096
1097  for (n = 1; *s; s++)
1098    if (*s == ',')
1099      n++;
1100
1101  return n;
1102}
1103
1104/* Given a pointer to a (char *), return a pointer to the beginning of the
1105   next comma-separated element in the string.  Advance the pointer given
1106   to the end of that element.  Return NULL if at end of string.  Caller
1107   is responsible for copying the string if necessary.  White space between
1108   a comma and an element is ignored.  */
1109
1110const char *
1111scan_comma_elt (const char **pstr)
1112{
1113  const char *start;
1114  const char *p = *pstr;
1115
1116  if (*p == ',')
1117    p++;
1118  while (ISSPACE(*p))
1119    p++;
1120
1121  if (*p == '\0')
1122    return NULL;
1123
1124  start = p;
1125
1126  while (*p != ',' && *p != '\0')
1127    p++;
1128
1129  *pstr = p;
1130  return start;
1131}
1132