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