xref: /openbsd-src/gnu/gcc/gcc/gensupport.c (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1 /* Support routines for the various generation passes.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
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, 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, 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.  */
34 int target_flags;
35 
36 int insn_elision = 1;
37 
38 const char *in_fname;
39 
40 /* This callback will be invoked whenever an rtl include directive is
41    processed.  To be used for creation of the dependency file.  */
42 void (*include_callback) (const char *);
43 
44 static struct obstack obstack;
45 struct obstack *rtl_obstack = &obstack;
46 
47 static int sequence_num;
48 static int errors;
49 
50 static int predicable_default;
51 static const char *predicable_true;
52 static const char *predicable_false;
53 
54 static htab_t condition_table;
55 
56 static char *base_dir = NULL;
57 
58 /* We initially queue all patterns, process the define_insn and
59    define_cond_exec patterns, then return them one at a time.  */
60 
61 struct queue_elem
62 {
63   rtx data;
64   const char *filename;
65   int lineno;
66   struct queue_elem *next;
67   /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
68      points to the generated DEFINE_SPLIT.  */
69   struct queue_elem *split;
70 };
71 
72 static struct queue_elem *define_attr_queue;
73 static struct queue_elem **define_attr_tail = &define_attr_queue;
74 static struct queue_elem *define_pred_queue;
75 static struct queue_elem **define_pred_tail = &define_pred_queue;
76 static struct queue_elem *define_insn_queue;
77 static struct queue_elem **define_insn_tail = &define_insn_queue;
78 static struct queue_elem *define_cond_exec_queue;
79 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
80 static struct queue_elem *other_queue;
81 static struct queue_elem **other_tail = &other_queue;
82 
83 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
84 					 const char *, int);
85 
86 /* Current maximum length of directory names in the search path
87    for include files.  (Altered as we get more of them.)  */
88 
89 size_t max_include_len;
90 
91 struct file_name_list
92   {
93     struct file_name_list *next;
94     const char *fname;
95   };
96 
97 struct file_name_list *first_dir_md_include = 0;  /* First dir to search */
98         /* First dir to search for <file> */
99 struct file_name_list *first_bracket_include = 0;
100 struct file_name_list *last_dir_md_include = 0;        /* Last in chain */
101 
102 static void remove_constraints (rtx);
103 static void process_rtx (rtx, int);
104 
105 static int is_predicable (struct queue_elem *);
106 static void identify_predicable_attribute (void);
107 static int n_alternatives (const char *);
108 static void collect_insn_data (rtx, int *, int *);
109 static rtx alter_predicate_for_insn (rtx, int, int, int);
110 static const char *alter_test_for_insn (struct queue_elem *,
111 					struct queue_elem *);
112 static char *shift_output_template (char *, const char *, int);
113 static const char *alter_output_for_insn (struct queue_elem *,
114 					  struct queue_elem *,
115 					  int, int);
116 static void process_one_cond_exec (struct queue_elem *);
117 static void process_define_cond_exec (void);
118 static void process_include (rtx, int);
119 static char *save_string (const char *, int);
120 static void init_predicate_table (void);
121 static void record_insn_name (int, const char *);
122 
123 void
message_with_line(int lineno,const char * msg,...)124 message_with_line (int lineno, const char *msg, ...)
125 {
126   va_list ap;
127 
128   va_start (ap, msg);
129 
130   fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
131   vfprintf (stderr, msg, ap);
132   fputc ('\n', stderr);
133 
134   va_end (ap);
135 }
136 
137 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
138    the gensupport programs.  */
139 
140 rtx
gen_rtx_CONST_INT(enum machine_mode ARG_UNUSED (mode),HOST_WIDE_INT arg)141 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
142 		   HOST_WIDE_INT arg)
143 {
144   rtx rt = rtx_alloc (CONST_INT);
145 
146   XWINT (rt, 0) = arg;
147   return rt;
148 }
149 
150 /* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
151    element.  */
152 
153 static struct queue_elem *
queue_pattern(rtx pattern,struct queue_elem *** list_tail,const char * filename,int lineno)154 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
155 	       const char *filename, int lineno)
156 {
157   struct queue_elem *e = XNEW(struct queue_elem);
158   e->data = pattern;
159   e->filename = filename;
160   e->lineno = lineno;
161   e->next = NULL;
162   e->split = NULL;
163   **list_tail = e;
164   *list_tail = &e->next;
165   return e;
166 }
167 
168 /* Recursively remove constraints from an rtx.  */
169 
170 static void
remove_constraints(rtx part)171 remove_constraints (rtx part)
172 {
173   int i, j;
174   const char *format_ptr;
175 
176   if (part == 0)
177     return;
178 
179   if (GET_CODE (part) == MATCH_OPERAND)
180     XSTR (part, 2) = "";
181   else if (GET_CODE (part) == MATCH_SCRATCH)
182     XSTR (part, 1) = "";
183 
184   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
185 
186   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
187     switch (*format_ptr++)
188       {
189       case 'e':
190       case 'u':
191 	remove_constraints (XEXP (part, i));
192 	break;
193       case 'E':
194 	if (XVEC (part, i) != NULL)
195 	  for (j = 0; j < XVECLEN (part, i); j++)
196 	    remove_constraints (XVECEXP (part, i, j));
197 	break;
198       }
199 }
200 
201 /* Process an include file assuming that it lives in gcc/config/{target}/
202    if the include looks like (include "file").  */
203 
204 static void
process_include(rtx desc,int lineno)205 process_include (rtx desc, int lineno)
206 {
207   const char *filename = XSTR (desc, 0);
208   const char *old_filename;
209   int old_lineno;
210   char *pathname;
211   FILE *input_file;
212 
213   /* If specified file name is absolute, skip the include stack.  */
214   if (! IS_ABSOLUTE_PATH (filename))
215     {
216       struct file_name_list *stackp;
217 
218       /* Search directory path, trying to open the file.  */
219       for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
220 	{
221 	  static const char sep[2] = { DIR_SEPARATOR, '\0' };
222 
223 	  pathname = concat (stackp->fname, sep, filename, NULL);
224 	  input_file = fopen (pathname, "r");
225 	  if (input_file != NULL)
226 	    goto success;
227 	  free (pathname);
228 	}
229     }
230 
231   if (base_dir)
232     pathname = concat (base_dir, filename, NULL);
233   else
234     pathname = xstrdup (filename);
235   input_file = fopen (pathname, "r");
236   if (input_file == NULL)
237     {
238       free (pathname);
239       message_with_line (lineno, "include file `%s' not found", filename);
240       errors = 1;
241       return;
242     }
243  success:
244 
245   /* Save old cursor; setup new for the new file.  Note that "lineno" the
246      argument to this function is the beginning of the include statement,
247      while read_rtx_lineno has already been advanced.  */
248   old_filename = read_rtx_filename;
249   old_lineno = read_rtx_lineno;
250   read_rtx_filename = pathname;
251   read_rtx_lineno = 1;
252 
253   if (include_callback)
254     include_callback (pathname);
255 
256   /* Read the entire file.  */
257   while (read_rtx (input_file, &desc, &lineno))
258     process_rtx (desc, lineno);
259 
260   /* Do not free pathname.  It is attached to the various rtx queue
261      elements.  */
262 
263   read_rtx_filename = old_filename;
264   read_rtx_lineno = old_lineno;
265 
266   fclose (input_file);
267 }
268 
269 /* Process a top level rtx in some way, queuing as appropriate.  */
270 
271 static void
process_rtx(rtx desc,int lineno)272 process_rtx (rtx desc, int lineno)
273 {
274   switch (GET_CODE (desc))
275     {
276     case DEFINE_INSN:
277       queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
278       break;
279 
280     case DEFINE_COND_EXEC:
281       queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
282       break;
283 
284     case DEFINE_ATTR:
285       queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
286       break;
287 
288     case DEFINE_PREDICATE:
289     case DEFINE_SPECIAL_PREDICATE:
290     case DEFINE_CONSTRAINT:
291     case DEFINE_REGISTER_CONSTRAINT:
292     case DEFINE_MEMORY_CONSTRAINT:
293     case DEFINE_ADDRESS_CONSTRAINT:
294       queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
295       break;
296 
297     case INCLUDE:
298       process_include (desc, lineno);
299       break;
300 
301     case DEFINE_INSN_AND_SPLIT:
302       {
303 	const char *split_cond;
304 	rtx split;
305 	rtvec attr;
306 	int i;
307 	struct queue_elem *insn_elem;
308 	struct queue_elem *split_elem;
309 
310 	/* Create a split with values from the insn_and_split.  */
311 	split = rtx_alloc (DEFINE_SPLIT);
312 
313 	i = XVECLEN (desc, 1);
314 	XVEC (split, 0) = rtvec_alloc (i);
315 	while (--i >= 0)
316 	  {
317 	    XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
318 	    remove_constraints (XVECEXP (split, 0, i));
319 	  }
320 
321 	/* If the split condition starts with "&&", append it to the
322 	   insn condition to create the new split condition.  */
323 	split_cond = XSTR (desc, 4);
324 	if (split_cond[0] == '&' && split_cond[1] == '&')
325 	  {
326 	    copy_rtx_ptr_loc (split_cond + 2, split_cond);
327 	    split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
328 	  }
329 	XSTR (split, 1) = split_cond;
330 	XVEC (split, 2) = XVEC (desc, 5);
331 	XSTR (split, 3) = XSTR (desc, 6);
332 
333 	/* Fix up the DEFINE_INSN.  */
334 	attr = XVEC (desc, 7);
335 	PUT_CODE (desc, DEFINE_INSN);
336 	XVEC (desc, 4) = attr;
337 
338 	/* Queue them.  */
339 	insn_elem
340 	  = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
341 			   lineno);
342 	split_elem
343 	  = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
344 	insn_elem->split = split_elem;
345 	break;
346       }
347 
348     default:
349       queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
350       break;
351     }
352 }
353 
354 /* Return true if attribute PREDICABLE is true for ELEM, which holds
355    a DEFINE_INSN.  */
356 
357 static int
is_predicable(struct queue_elem * elem)358 is_predicable (struct queue_elem *elem)
359 {
360   rtvec vec = XVEC (elem->data, 4);
361   const char *value;
362   int i;
363 
364   if (! vec)
365     return predicable_default;
366 
367   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
368     {
369       rtx sub = RTVEC_ELT (vec, i);
370       switch (GET_CODE (sub))
371 	{
372 	case SET_ATTR:
373 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
374 	    {
375 	      value = XSTR (sub, 1);
376 	      goto found;
377 	    }
378 	  break;
379 
380 	case SET_ATTR_ALTERNATIVE:
381 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
382 	    {
383 	      message_with_line (elem->lineno,
384 				 "multiple alternatives for `predicable'");
385 	      errors = 1;
386 	      return 0;
387 	    }
388 	  break;
389 
390 	case SET:
391 	  if (GET_CODE (SET_DEST (sub)) != ATTR
392 	      || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
393 	    break;
394 	  sub = SET_SRC (sub);
395 	  if (GET_CODE (sub) == CONST_STRING)
396 	    {
397 	      value = XSTR (sub, 0);
398 	      goto found;
399 	    }
400 
401 	  /* ??? It would be possible to handle this if we really tried.
402 	     It's not easy though, and I'm not going to bother until it
403 	     really proves necessary.  */
404 	  message_with_line (elem->lineno,
405 			     "non-constant value for `predicable'");
406 	  errors = 1;
407 	  return 0;
408 
409 	default:
410 	  gcc_unreachable ();
411 	}
412     }
413 
414   return predicable_default;
415 
416  found:
417   /* Verify that predicability does not vary on the alternative.  */
418   /* ??? It should be possible to handle this by simply eliminating
419      the non-predicable alternatives from the insn.  FRV would like
420      to do this.  Delay this until we've got the basics solid.  */
421   if (strchr (value, ',') != NULL)
422     {
423       message_with_line (elem->lineno,
424 			 "multiple alternatives for `predicable'");
425       errors = 1;
426       return 0;
427     }
428 
429   /* Find out which value we're looking at.  */
430   if (strcmp (value, predicable_true) == 0)
431     return 1;
432   if (strcmp (value, predicable_false) == 0)
433     return 0;
434 
435   message_with_line (elem->lineno,
436 		     "unknown value `%s' for `predicable' attribute",
437 		     value);
438   errors = 1;
439   return 0;
440 }
441 
442 /* Examine the attribute "predicable"; discover its boolean values
443    and its default.  */
444 
445 static void
identify_predicable_attribute(void)446 identify_predicable_attribute (void)
447 {
448   struct queue_elem *elem;
449   char *p_true, *p_false;
450   const char *value;
451 
452   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
453   for (elem = define_attr_queue; elem ; elem = elem->next)
454     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
455       goto found;
456 
457   message_with_line (define_cond_exec_queue->lineno,
458 		     "attribute `predicable' not defined");
459   errors = 1;
460   return;
461 
462  found:
463   value = XSTR (elem->data, 1);
464   p_false = xstrdup (value);
465   p_true = strchr (p_false, ',');
466   if (p_true == NULL || strchr (++p_true, ',') != NULL)
467     {
468       message_with_line (elem->lineno,
469 			 "attribute `predicable' is not a boolean");
470       errors = 1;
471       if (p_false)
472         free (p_false);
473       return;
474     }
475   p_true[-1] = '\0';
476 
477   predicable_true = p_true;
478   predicable_false = p_false;
479 
480   switch (GET_CODE (XEXP (elem->data, 2)))
481     {
482     case CONST_STRING:
483       value = XSTR (XEXP (elem->data, 2), 0);
484       break;
485 
486     case CONST:
487       message_with_line (elem->lineno,
488 			 "attribute `predicable' cannot be const");
489       errors = 1;
490       if (p_false)
491 	free (p_false);
492       return;
493 
494     default:
495       message_with_line (elem->lineno,
496 			 "attribute `predicable' must have a constant default");
497       errors = 1;
498       if (p_false)
499 	free (p_false);
500       return;
501     }
502 
503   if (strcmp (value, p_true) == 0)
504     predicable_default = 1;
505   else if (strcmp (value, p_false) == 0)
506     predicable_default = 0;
507   else
508     {
509       message_with_line (elem->lineno,
510 			 "unknown value `%s' for `predicable' attribute",
511 			 value);
512       errors = 1;
513       if (p_false)
514 	free (p_false);
515     }
516 }
517 
518 /* Return the number of alternatives in constraint S.  */
519 
520 static int
n_alternatives(const char * s)521 n_alternatives (const char *s)
522 {
523   int n = 1;
524 
525   if (s)
526     while (*s)
527       n += (*s++ == ',');
528 
529   return n;
530 }
531 
532 /* Determine how many alternatives there are in INSN, and how many
533    operands.  */
534 
535 static void
collect_insn_data(rtx pattern,int * palt,int * pmax)536 collect_insn_data (rtx pattern, int *palt, int *pmax)
537 {
538   const char *fmt;
539   enum rtx_code code;
540   int i, j, len;
541 
542   code = GET_CODE (pattern);
543   switch (code)
544     {
545     case MATCH_OPERAND:
546       i = n_alternatives (XSTR (pattern, 2));
547       *palt = (i > *palt ? i : *palt);
548       /* Fall through.  */
549 
550     case MATCH_OPERATOR:
551     case MATCH_SCRATCH:
552     case MATCH_PARALLEL:
553       i = XINT (pattern, 0);
554       if (i > *pmax)
555 	*pmax = i;
556       break;
557 
558     default:
559       break;
560     }
561 
562   fmt = GET_RTX_FORMAT (code);
563   len = GET_RTX_LENGTH (code);
564   for (i = 0; i < len; i++)
565     {
566       switch (fmt[i])
567 	{
568 	case 'e': case 'u':
569 	  collect_insn_data (XEXP (pattern, i), palt, pmax);
570 	  break;
571 
572 	case 'V':
573 	  if (XVEC (pattern, i) == NULL)
574 	    break;
575 	  /* Fall through.  */
576 	case 'E':
577 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
578 	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
579 	  break;
580 
581 	case 'i': case 'w': case '0': case 's': case 'S': case 'T':
582 	  break;
583 
584 	default:
585 	  gcc_unreachable ();
586 	}
587     }
588 }
589 
590 static rtx
alter_predicate_for_insn(rtx pattern,int alt,int max_op,int lineno)591 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
592 {
593   const char *fmt;
594   enum rtx_code code;
595   int i, j, len;
596 
597   code = GET_CODE (pattern);
598   switch (code)
599     {
600     case MATCH_OPERAND:
601       {
602 	const char *c = XSTR (pattern, 2);
603 
604 	if (n_alternatives (c) != 1)
605 	  {
606 	    message_with_line (lineno,
607 			       "too many alternatives for operand %d",
608 			       XINT (pattern, 0));
609 	    errors = 1;
610 	    return NULL;
611 	  }
612 
613 	/* Replicate C as needed to fill out ALT alternatives.  */
614 	if (c && *c && alt > 1)
615 	  {
616 	    size_t c_len = strlen (c);
617 	    size_t len = alt * (c_len + 1);
618 	    char *new_c = XNEWVEC(char, len);
619 
620 	    memcpy (new_c, c, c_len);
621 	    for (i = 1; i < alt; ++i)
622 	      {
623 		new_c[i * (c_len + 1) - 1] = ',';
624 		memcpy (&new_c[i * (c_len + 1)], c, c_len);
625 	      }
626 	    new_c[len - 1] = '\0';
627 	    XSTR (pattern, 2) = new_c;
628 	  }
629       }
630       /* Fall through.  */
631 
632     case MATCH_OPERATOR:
633     case MATCH_SCRATCH:
634     case MATCH_PARALLEL:
635       XINT (pattern, 0) += max_op;
636       break;
637 
638     default:
639       break;
640     }
641 
642   fmt = GET_RTX_FORMAT (code);
643   len = GET_RTX_LENGTH (code);
644   for (i = 0; i < len; i++)
645     {
646       rtx r;
647 
648       switch (fmt[i])
649 	{
650 	case 'e': case 'u':
651 	  r = alter_predicate_for_insn (XEXP (pattern, i), alt,
652 					max_op, lineno);
653 	  if (r == NULL)
654 	    return r;
655 	  break;
656 
657 	case 'E':
658 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
659 	    {
660 	      r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
661 					    alt, max_op, lineno);
662 	      if (r == NULL)
663 		return r;
664 	    }
665 	  break;
666 
667 	case 'i': case 'w': case '0': case 's':
668 	  break;
669 
670 	default:
671 	  gcc_unreachable ();
672 	}
673     }
674 
675   return pattern;
676 }
677 
678 static const char *
alter_test_for_insn(struct queue_elem * ce_elem,struct queue_elem * insn_elem)679 alter_test_for_insn (struct queue_elem *ce_elem,
680 		     struct queue_elem *insn_elem)
681 {
682   return join_c_conditions (XSTR (ce_elem->data, 1),
683 			    XSTR (insn_elem->data, 2));
684 }
685 
686 /* Adjust all of the operand numbers in SRC to match the shift they'll
687    get from an operand displacement of DISP.  Return a pointer after the
688    adjusted string.  */
689 
690 static char *
shift_output_template(char * dest,const char * src,int disp)691 shift_output_template (char *dest, const char *src, int disp)
692 {
693   while (*src)
694     {
695       char c = *src++;
696       *dest++ = c;
697       if (c == '%')
698 	{
699 	  c = *src++;
700 	  if (ISDIGIT ((unsigned char) c))
701 	    c += disp;
702 	  else if (ISALPHA (c))
703 	    {
704 	      *dest++ = c;
705 	      c = *src++ + disp;
706 	    }
707 	  *dest++ = c;
708 	}
709     }
710 
711   return dest;
712 }
713 
714 static const char *
alter_output_for_insn(struct queue_elem * ce_elem,struct queue_elem * insn_elem,int alt,int max_op)715 alter_output_for_insn (struct queue_elem *ce_elem,
716 		       struct queue_elem *insn_elem,
717 		       int alt, int max_op)
718 {
719   const char *ce_out, *insn_out;
720   char *result, *p;
721   size_t len, ce_len, insn_len;
722 
723   /* ??? Could coordinate with genoutput to not duplicate code here.  */
724 
725   ce_out = XSTR (ce_elem->data, 2);
726   insn_out = XTMPL (insn_elem->data, 3);
727   if (!ce_out || *ce_out == '\0')
728     return insn_out;
729 
730   ce_len = strlen (ce_out);
731   insn_len = strlen (insn_out);
732 
733   if (*insn_out == '*')
734     /* You must take care of the predicate yourself.  */
735     return insn_out;
736 
737   if (*insn_out == '@')
738     {
739       len = (ce_len + 1) * alt + insn_len + 1;
740       p = result = XNEWVEC(char, len);
741 
742       do
743 	{
744 	  do
745 	    *p++ = *insn_out++;
746 	  while (ISSPACE ((unsigned char) *insn_out));
747 
748 	  if (*insn_out != '#')
749 	    {
750 	      p = shift_output_template (p, ce_out, max_op);
751 	      *p++ = ' ';
752 	    }
753 
754 	  do
755 	    *p++ = *insn_out++;
756 	  while (*insn_out && *insn_out != '\n');
757 	}
758       while (*insn_out);
759       *p = '\0';
760     }
761   else
762     {
763       len = ce_len + 1 + insn_len + 1;
764       result = XNEWVEC (char, len);
765 
766       p = shift_output_template (result, ce_out, max_op);
767       *p++ = ' ';
768       memcpy (p, insn_out, insn_len + 1);
769     }
770 
771   return result;
772 }
773 
774 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
775 
776 static void
process_one_cond_exec(struct queue_elem * ce_elem)777 process_one_cond_exec (struct queue_elem *ce_elem)
778 {
779   struct queue_elem *insn_elem;
780   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
781     {
782       int alternatives, max_operand;
783       rtx pred, insn, pattern, split;
784       int i;
785 
786       if (! is_predicable (insn_elem))
787 	continue;
788 
789       alternatives = 1;
790       max_operand = -1;
791       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
792       max_operand += 1;
793 
794       if (XVECLEN (ce_elem->data, 0) != 1)
795 	{
796 	  message_with_line (ce_elem->lineno,
797 			     "too many patterns in predicate");
798 	  errors = 1;
799 	  return;
800 	}
801 
802       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
803       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
804 				       ce_elem->lineno);
805       if (pred == NULL)
806 	return;
807 
808       /* Construct a new pattern for the new insn.  */
809       insn = copy_rtx (insn_elem->data);
810       XSTR (insn, 0) = "";
811       pattern = rtx_alloc (COND_EXEC);
812       XEXP (pattern, 0) = pred;
813       if (XVECLEN (insn, 1) == 1)
814 	{
815 	  XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
816 	  XVECEXP (insn, 1, 0) = pattern;
817 	  PUT_NUM_ELEM (XVEC (insn, 1), 1);
818 	}
819       else
820 	{
821 	  XEXP (pattern, 1) = rtx_alloc (PARALLEL);
822 	  XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
823 	  XVEC (insn, 1) = rtvec_alloc (1);
824 	  XVECEXP (insn, 1, 0) = pattern;
825 	}
826 
827       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
828       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
829 					      alternatives, max_operand);
830 
831       /* ??? Set `predicable' to false.  Not crucial since it's really
832          only used here, and we won't reprocess this new pattern.  */
833 
834       /* Put the new pattern on the `other' list so that it
835 	 (a) is not reprocessed by other define_cond_exec patterns
836 	 (b) appears after all normal define_insn patterns.
837 
838 	 ??? B is debatable.  If one has normal insns that match
839 	 cond_exec patterns, they will be preferred over these
840 	 generated patterns.  Whether this matters in practice, or if
841 	 it's a good thing, or whether we should thread these new
842 	 patterns into the define_insn chain just after their generator
843 	 is something we'll have to experiment with.  */
844 
845       queue_pattern (insn, &other_tail, insn_elem->filename,
846 		     insn_elem->lineno);
847 
848       if (!insn_elem->split)
849 	continue;
850 
851       /* If the original insn came from a define_insn_and_split,
852 	 generate a new split to handle the predicated insn.  */
853       split = copy_rtx (insn_elem->split->data);
854       /* Predicate the pattern matched by the split.  */
855       pattern = rtx_alloc (COND_EXEC);
856       XEXP (pattern, 0) = pred;
857       if (XVECLEN (split, 0) == 1)
858 	{
859 	  XEXP (pattern, 1) = XVECEXP (split, 0, 0);
860 	  XVECEXP (split, 0, 0) = pattern;
861 	  PUT_NUM_ELEM (XVEC (split, 0), 1);
862 	}
863       else
864 	{
865 	  XEXP (pattern, 1) = rtx_alloc (PARALLEL);
866 	  XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
867 	  XVEC (split, 0) = rtvec_alloc (1);
868 	  XVECEXP (split, 0, 0) = pattern;
869 	}
870       /* Predicate all of the insns generated by the split.  */
871       for (i = 0; i < XVECLEN (split, 2); i++)
872 	{
873 	  pattern = rtx_alloc (COND_EXEC);
874 	  XEXP (pattern, 0) = pred;
875 	  XEXP (pattern, 1) = XVECEXP (split, 2, i);
876 	  XVECEXP (split, 2, i) = pattern;
877 	}
878       /* Add the new split to the queue.  */
879       queue_pattern (split, &other_tail, read_rtx_filename,
880 		     insn_elem->split->lineno);
881     }
882 }
883 
884 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
885    patterns appropriately.  */
886 
887 static void
process_define_cond_exec(void)888 process_define_cond_exec (void)
889 {
890   struct queue_elem *elem;
891 
892   identify_predicable_attribute ();
893   if (errors)
894     return;
895 
896   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
897     process_one_cond_exec (elem);
898 }
899 
900 static char *
save_string(const char * s,int len)901 save_string (const char *s, int len)
902 {
903   char *result = XNEWVEC (char, len + 1);
904 
905   memcpy (result, s, len);
906   result[len] = 0;
907   return result;
908 }
909 
910 
911 /* The entry point for initializing the reader.  */
912 
913 int
init_md_reader_args_cb(int argc,char ** argv,bool (* parse_opt)(const char *))914 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
915 {
916   FILE *input_file;
917   int c, i, lineno;
918   char *lastsl;
919   rtx desc;
920   bool no_more_options;
921   bool already_read_stdin;
922 
923   /* Unlock the stdio streams.  */
924   unlock_std_streams ();
925 
926   /* First we loop over all the options.  */
927   for (i = 1; i < argc; i++)
928     {
929       if (argv[i][0] != '-')
930 	continue;
931 
932       c = argv[i][1];
933       switch (c)
934 	{
935 	case 'I':		/* Add directory to path for includes.  */
936 	  {
937 	    struct file_name_list *dirtmp;
938 
939 	    dirtmp = XNEW (struct file_name_list);
940 	    dirtmp->next = 0;	/* New one goes on the end */
941 	    if (first_dir_md_include == 0)
942 	      first_dir_md_include = dirtmp;
943 	    else
944 	      last_dir_md_include->next = dirtmp;
945 	    last_dir_md_include = dirtmp;	/* Tail follows the last one */
946 	    if (argv[i][1] == 'I' && argv[i][2] != 0)
947 	      dirtmp->fname = argv[i] + 2;
948 	    else if (i + 1 == argc)
949 	      fatal ("directory name missing after -I option");
950 	    else
951 	      dirtmp->fname = argv[++i];
952 	    if (strlen (dirtmp->fname) > max_include_len)
953 	      max_include_len = strlen (dirtmp->fname);
954 	  }
955 	  break;
956 
957 	case '\0':
958 	  /* An argument consisting of exactly one dash is a request to
959 	     read stdin.  This will be handled in the second loop.  */
960 	  continue;
961 
962 	case '-':
963 	  /* An argument consisting of just two dashes causes option
964 	     parsing to cease.  */
965 	  if (argv[i][2] == '\0')
966 	    goto stop_parsing_options;
967 
968 	default:
969 	  /* The program may have provided a callback so it can
970 	     accept its own options.  */
971 	  if (parse_opt && parse_opt (argv[i]))
972 	    break;
973 
974 	  fatal ("invalid option `%s'", argv[i]);
975 	}
976     }
977 
978  stop_parsing_options:
979 
980   /* Prepare to read input.  */
981   condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
982   init_predicate_table ();
983   obstack_init (rtl_obstack);
984   errors = 0;
985   sequence_num = 0;
986   no_more_options = false;
987   already_read_stdin = false;
988 
989 
990   /* Now loop over all input files.  */
991   for (i = 1; i < argc; i++)
992     {
993       if (argv[i][0] == '-')
994 	{
995 	  if (argv[i][1] == '\0')
996 	    {
997 	      /* Read stdin.  */
998 	      if (already_read_stdin)
999 		fatal ("cannot read standard input twice");
1000 
1001 	      base_dir = NULL;
1002 	      read_rtx_filename = in_fname = "<stdin>";
1003 	      read_rtx_lineno = 1;
1004 	      input_file = stdin;
1005 	      already_read_stdin = true;
1006 
1007 	      while (read_rtx (input_file, &desc, &lineno))
1008 		process_rtx (desc, lineno);
1009 	      fclose (input_file);
1010 	      continue;
1011 	    }
1012 	  else if (argv[i][1] == '-' && argv[i][2] == '\0')
1013 	    {
1014 	      /* No further arguments are to be treated as options.  */
1015 	      no_more_options = true;
1016 	      continue;
1017 	    }
1018 	  else if (!no_more_options)
1019 	    continue;
1020 	}
1021 
1022       /* If we get here we are looking at a non-option argument, i.e.
1023 	 a file to be processed.  */
1024 
1025       in_fname = argv[i];
1026       lastsl = strrchr (in_fname, '/');
1027       if (lastsl != NULL)
1028 	base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1029       else
1030 	base_dir = NULL;
1031 
1032       read_rtx_filename = in_fname;
1033       read_rtx_lineno = 1;
1034       input_file = fopen (in_fname, "r");
1035       if (input_file == 0)
1036 	{
1037 	  perror (in_fname);
1038 	  return FATAL_EXIT_CODE;
1039 	}
1040 
1041       while (read_rtx (input_file, &desc, &lineno))
1042 	process_rtx (desc, lineno);
1043       fclose (input_file);
1044     }
1045 
1046   /* If we get to this point without having seen any files to process,
1047      read standard input now.  */
1048   if (!in_fname)
1049     {
1050       base_dir = NULL;
1051       read_rtx_filename = in_fname = "<stdin>";
1052       read_rtx_lineno = 1;
1053       input_file = stdin;
1054 
1055       while (read_rtx (input_file, &desc, &lineno))
1056 	process_rtx (desc, lineno);
1057       fclose (input_file);
1058     }
1059 
1060   /* Process define_cond_exec patterns.  */
1061   if (define_cond_exec_queue != NULL)
1062     process_define_cond_exec ();
1063 
1064   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1065 }
1066 
1067 /* Programs that don't have their own options can use this entry point
1068    instead.  */
1069 int
init_md_reader_args(int argc,char ** argv)1070 init_md_reader_args (int argc, char **argv)
1071 {
1072   return init_md_reader_args_cb (argc, argv, 0);
1073 }
1074 
1075 /* The entry point for reading a single rtx from an md file.  */
1076 
1077 rtx
read_md_rtx(int * lineno,int * seqnr)1078 read_md_rtx (int *lineno, int *seqnr)
1079 {
1080   struct queue_elem **queue, *elem;
1081   rtx desc;
1082 
1083  discard:
1084 
1085   /* Read all patterns from a given queue before moving on to the next.  */
1086   if (define_attr_queue != NULL)
1087     queue = &define_attr_queue;
1088   else if (define_pred_queue != NULL)
1089     queue = &define_pred_queue;
1090   else if (define_insn_queue != NULL)
1091     queue = &define_insn_queue;
1092   else if (other_queue != NULL)
1093     queue = &other_queue;
1094   else
1095     return NULL_RTX;
1096 
1097   elem = *queue;
1098   *queue = elem->next;
1099   desc = elem->data;
1100   read_rtx_filename = elem->filename;
1101   *lineno = elem->lineno;
1102   *seqnr = sequence_num;
1103 
1104   free (elem);
1105 
1106   /* Discard insn patterns which we know can never match (because
1107      their C test is provably always false).  If insn_elision is
1108      false, our caller needs to see all the patterns.  Note that the
1109      elided patterns are never counted by the sequence numbering; it
1110      it is the caller's responsibility, when insn_elision is false, not
1111      to use elided pattern numbers for anything.  */
1112   switch (GET_CODE (desc))
1113     {
1114     case DEFINE_INSN:
1115     case DEFINE_EXPAND:
1116       if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1117 	sequence_num++;
1118       else if (insn_elision)
1119 	goto discard;
1120 
1121       /* *seqnr is used here so the name table will match caller's
1122 	 idea of insn numbering, whether or not elision is active.  */
1123       record_insn_name (*seqnr, XSTR (desc, 0));
1124       break;
1125 
1126     case DEFINE_SPLIT:
1127     case DEFINE_PEEPHOLE:
1128     case DEFINE_PEEPHOLE2:
1129       if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1130 	sequence_num++;
1131       else if (insn_elision)
1132 	    goto discard;
1133       break;
1134 
1135     default:
1136       break;
1137     }
1138 
1139   return desc;
1140 }
1141 
1142 /* Helper functions for insn elision.  */
1143 
1144 /* Compute a hash function of a c_test structure, which is keyed
1145    by its ->expr field.  */
1146 hashval_t
hash_c_test(const void * x)1147 hash_c_test (const void *x)
1148 {
1149   const struct c_test *a = (const struct c_test *) x;
1150   const unsigned char *base, *s = (const unsigned char *) a->expr;
1151   hashval_t hash;
1152   unsigned char c;
1153   unsigned int len;
1154 
1155   base = s;
1156   hash = 0;
1157 
1158   while ((c = *s++) != '\0')
1159     {
1160       hash += c + (c << 17);
1161       hash ^= hash >> 2;
1162     }
1163 
1164   len = s - base;
1165   hash += len + (len << 17);
1166   hash ^= hash >> 2;
1167 
1168   return hash;
1169 }
1170 
1171 /* Compare two c_test expression structures.  */
1172 int
cmp_c_test(const void * x,const void * y)1173 cmp_c_test (const void *x, const void *y)
1174 {
1175   const struct c_test *a = (const struct c_test *) x;
1176   const struct c_test *b = (const struct c_test *) y;
1177 
1178   return !strcmp (a->expr, b->expr);
1179 }
1180 
1181 /* Given a string representing a C test expression, look it up in the
1182    condition_table and report whether or not its value is known
1183    at compile time.  Returns a tristate: 1 for known true, 0 for
1184    known false, -1 for unknown.  */
1185 int
maybe_eval_c_test(const char * expr)1186 maybe_eval_c_test (const char *expr)
1187 {
1188   const struct c_test *test;
1189   struct c_test dummy;
1190 
1191   if (expr[0] == 0)
1192     return 1;
1193 
1194   dummy.expr = expr;
1195   test = (const struct c_test *)htab_find (condition_table, &dummy);
1196   if (!test)
1197     return -1;
1198   return test->value;
1199 }
1200 
1201 /* Record the C test expression EXPR in the condition_table, with
1202    value VAL.  Duplicates clobber previous entries.  */
1203 
1204 void
add_c_test(const char * expr,int value)1205 add_c_test (const char *expr, int value)
1206 {
1207   struct c_test *test;
1208 
1209   if (expr[0] == 0)
1210     return;
1211 
1212   test = XNEW (struct c_test);
1213   test->expr = expr;
1214   test->value = value;
1215 
1216   *(htab_find_slot (condition_table, test, INSERT)) = test;
1217 }
1218 
1219 /* For every C test, call CALLBACK with two arguments: a pointer to
1220    the condition structure and INFO.  Stops when CALLBACK returns zero.  */
1221 void
traverse_c_tests(htab_trav callback,void * info)1222 traverse_c_tests (htab_trav callback, void *info)
1223 {
1224   if (condition_table)
1225     htab_traverse (condition_table, callback, info);
1226 }
1227 
1228 
1229 /* Given a string, return the number of comma-separated elements in it.
1230    Return 0 for the null string.  */
1231 int
n_comma_elts(const char * s)1232 n_comma_elts (const char *s)
1233 {
1234   int n;
1235 
1236   if (*s == '\0')
1237     return 0;
1238 
1239   for (n = 1; *s; s++)
1240     if (*s == ',')
1241       n++;
1242 
1243   return n;
1244 }
1245 
1246 /* Given a pointer to a (char *), return a pointer to the beginning of the
1247    next comma-separated element in the string.  Advance the pointer given
1248    to the end of that element.  Return NULL if at end of string.  Caller
1249    is responsible for copying the string if necessary.  White space between
1250    a comma and an element is ignored.  */
1251 
1252 const char *
scan_comma_elt(const char ** pstr)1253 scan_comma_elt (const char **pstr)
1254 {
1255   const char *start;
1256   const char *p = *pstr;
1257 
1258   if (*p == ',')
1259     p++;
1260   while (ISSPACE(*p))
1261     p++;
1262 
1263   if (*p == '\0')
1264     return NULL;
1265 
1266   start = p;
1267 
1268   while (*p != ',' && *p != '\0')
1269     p++;
1270 
1271   *pstr = p;
1272   return start;
1273 }
1274 
1275 /* Helper functions for define_predicate and define_special_predicate
1276    processing.  Shared between genrecog.c and genpreds.c.  */
1277 
1278 static htab_t predicate_table;
1279 struct pred_data *first_predicate;
1280 static struct pred_data **last_predicate = &first_predicate;
1281 
1282 static hashval_t
hash_struct_pred_data(const void * ptr)1283 hash_struct_pred_data (const void *ptr)
1284 {
1285   return htab_hash_string (((const struct pred_data *)ptr)->name);
1286 }
1287 
1288 static int
eq_struct_pred_data(const void * a,const void * b)1289 eq_struct_pred_data (const void *a, const void *b)
1290 {
1291   return !strcmp (((const struct pred_data *)a)->name,
1292 		  ((const struct pred_data *)b)->name);
1293 }
1294 
1295 struct pred_data *
lookup_predicate(const char * name)1296 lookup_predicate (const char *name)
1297 {
1298   struct pred_data key;
1299   key.name = name;
1300   return (struct pred_data *) htab_find (predicate_table, &key);
1301 }
1302 
1303 void
add_predicate(struct pred_data * pred)1304 add_predicate (struct pred_data *pred)
1305 {
1306   void **slot = htab_find_slot (predicate_table, pred, INSERT);
1307   if (*slot)
1308     {
1309       error ("duplicate predicate definition for '%s'", pred->name);
1310       return;
1311     }
1312   *slot = pred;
1313   *last_predicate = pred;
1314   last_predicate = &pred->next;
1315 }
1316 
1317 /* This array gives the initial content of the predicate table.  It
1318    has entries for all predicates defined in recog.c.  */
1319 
1320 struct std_pred_table
1321 {
1322   const char *name;
1323   bool special;
1324   RTX_CODE codes[NUM_RTX_CODE];
1325 };
1326 
1327 static const struct std_pred_table std_preds[] = {
1328   {"general_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1329 			      LABEL_REF, SUBREG, REG, MEM }},
1330   {"address_operand", true, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1331 			     LABEL_REF, SUBREG, REG, MEM,
1332 			     PLUS, MINUS, MULT}},
1333   {"register_operand", false, {SUBREG, REG}},
1334   {"pmode_register_operand", true, {SUBREG, REG}},
1335   {"scratch_operand", false, {SCRATCH, REG}},
1336   {"immediate_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1337 				LABEL_REF}},
1338   {"const_int_operand", false, {CONST_INT}},
1339   {"const_double_operand", false, {CONST_INT, CONST_DOUBLE}},
1340   {"nonimmediate_operand", false, {SUBREG, REG, MEM}},
1341   {"nonmemory_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1342 			        LABEL_REF, SUBREG, REG}},
1343   {"push_operand", false, {MEM}},
1344   {"pop_operand", false, {MEM}},
1345   {"memory_operand", false, {SUBREG, MEM}},
1346   {"indirect_operand", false, {SUBREG, MEM}},
1347   {"comparison_operator", false, {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
1348 				  UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
1349 				  UNLT, LTGT}}
1350 };
1351 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1352 
1353 /* Initialize the table of predicate definitions, starting with
1354    the information we have on generic predicates.  */
1355 
1356 static void
init_predicate_table(void)1357 init_predicate_table (void)
1358 {
1359   size_t i, j;
1360   struct pred_data *pred;
1361 
1362   predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1363 				       eq_struct_pred_data, 0,
1364 				       xcalloc, free);
1365 
1366   for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
1367     {
1368       pred = XCNEW (struct pred_data);
1369       pred->name = std_preds[i].name;
1370       pred->special = std_preds[i].special;
1371 
1372       for (j = 0; std_preds[i].codes[j] != 0; j++)
1373 	{
1374 	  enum rtx_code code = std_preds[i].codes[j];
1375 
1376 	  pred->codes[code] = true;
1377 	  if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1378 	    pred->allows_non_const = true;
1379 	  if (code != REG
1380 	      && code != SUBREG
1381 	      && code != MEM
1382 	      && code != CONCAT
1383 	      && code != PARALLEL
1384 	      && code != STRICT_LOW_PART)
1385 	    pred->allows_non_lvalue = true;
1386 	}
1387       if (j == 1)
1388 	pred->singleton = std_preds[i].codes[0];
1389 
1390       add_predicate (pred);
1391     }
1392 }
1393 
1394 /* These functions allow linkage with print-rtl.c.  Also, some generators
1395    like to annotate their output with insn names.  */
1396 
1397 /* Holds an array of names indexed by insn_code_number.  */
1398 static char **insn_name_ptr = 0;
1399 static int insn_name_ptr_size = 0;
1400 
1401 const char *
get_insn_name(int code)1402 get_insn_name (int code)
1403 {
1404   if (code < insn_name_ptr_size)
1405     return insn_name_ptr[code];
1406   else
1407     return NULL;
1408 }
1409 
1410 static void
record_insn_name(int code,const char * name)1411 record_insn_name (int code, const char *name)
1412 {
1413   static const char *last_real_name = "insn";
1414   static int last_real_code = 0;
1415   char *new;
1416 
1417   if (insn_name_ptr_size <= code)
1418     {
1419       int new_size;
1420       new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1421       insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
1422       memset (insn_name_ptr + insn_name_ptr_size, 0,
1423 	      sizeof(char *) * (new_size - insn_name_ptr_size));
1424       insn_name_ptr_size = new_size;
1425     }
1426 
1427   if (!name || name[0] == '\0')
1428     {
1429       new = xmalloc (strlen (last_real_name) + 10);
1430       sprintf (new, "%s+%d", last_real_name, code - last_real_code);
1431     }
1432   else
1433     {
1434       last_real_name = new = xstrdup (name);
1435       last_real_code = code;
1436     }
1437 
1438   insn_name_ptr[code] = new;
1439 }
1440