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.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
30 #include "gensupport.h"
33 /* In case some macros used by files we include need it, define this here. */
38 static struct obstack obstack
;
39 struct obstack
*rtl_obstack
= &obstack
;
41 static int sequence_num
;
43 static int predicable_default
;
44 static const char *predicable_true
;
45 static const char *predicable_false
;
47 static htab_t condition_table
;
49 /* We initially queue all patterns, process the define_insn and
50 define_cond_exec patterns, then return them one at a time. */
57 struct queue_elem
*next
;
58 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
59 points to the generated DEFINE_SPLIT. */
60 struct queue_elem
*split
;
63 static struct queue_elem
*define_attr_queue
;
64 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
65 static struct queue_elem
*define_pred_queue
;
66 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
67 static struct queue_elem
*define_insn_queue
;
68 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
69 static struct queue_elem
*define_cond_exec_queue
;
70 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
71 static struct queue_elem
*other_queue
;
72 static struct queue_elem
**other_tail
= &other_queue
;
74 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
77 static void remove_constraints (rtx
);
78 static void process_rtx (rtx
, int);
80 static int is_predicable (struct queue_elem
*);
81 static void identify_predicable_attribute (void);
82 static int n_alternatives (const char *);
83 static void collect_insn_data (rtx
, int *, int *);
84 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
85 static const char *alter_test_for_insn (struct queue_elem
*,
87 static char *shift_output_template (char *, const char *, int);
88 static const char *alter_output_for_insn (struct queue_elem
*,
91 static void process_one_cond_exec (struct queue_elem
*);
92 static void process_define_cond_exec (void);
93 static void init_predicate_table (void);
94 static void record_insn_name (int, const char *);
96 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
97 the gensupport programs. */
100 gen_rtx_CONST_INT (enum machine_mode
ARG_UNUSED (mode
),
103 rtx rt
= rtx_alloc (CONST_INT
);
109 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
112 static struct queue_elem
*
113 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
114 const char *filename
, int lineno
)
116 struct queue_elem
*e
= XNEW(struct queue_elem
);
118 e
->filename
= filename
;
123 *list_tail
= &e
->next
;
127 /* Recursively remove constraints from an rtx. */
130 remove_constraints (rtx part
)
133 const char *format_ptr
;
138 if (GET_CODE (part
) == MATCH_OPERAND
)
140 else if (GET_CODE (part
) == MATCH_SCRATCH
)
143 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
145 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
146 switch (*format_ptr
++)
150 remove_constraints (XEXP (part
, i
));
153 if (XVEC (part
, i
) != NULL
)
154 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
155 remove_constraints (XVECEXP (part
, i
, j
));
160 /* Process a top level rtx in some way, queuing as appropriate. */
163 process_rtx (rtx desc
, int lineno
)
165 switch (GET_CODE (desc
))
168 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
171 case DEFINE_COND_EXEC
:
172 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
176 case DEFINE_ENUM_ATTR
:
177 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
180 case DEFINE_PREDICATE
:
181 case DEFINE_SPECIAL_PREDICATE
:
182 case DEFINE_CONSTRAINT
:
183 case DEFINE_REGISTER_CONSTRAINT
:
184 case DEFINE_MEMORY_CONSTRAINT
:
185 case DEFINE_ADDRESS_CONSTRAINT
:
186 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
189 case DEFINE_INSN_AND_SPLIT
:
191 const char *split_cond
;
195 struct queue_elem
*insn_elem
;
196 struct queue_elem
*split_elem
;
198 /* Create a split with values from the insn_and_split. */
199 split
= rtx_alloc (DEFINE_SPLIT
);
201 i
= XVECLEN (desc
, 1);
202 XVEC (split
, 0) = rtvec_alloc (i
);
205 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
206 remove_constraints (XVECEXP (split
, 0, i
));
209 /* If the split condition starts with "&&", append it to the
210 insn condition to create the new split condition. */
211 split_cond
= XSTR (desc
, 4);
212 if (split_cond
[0] == '&' && split_cond
[1] == '&')
214 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
215 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
217 XSTR (split
, 1) = split_cond
;
218 XVEC (split
, 2) = XVEC (desc
, 5);
219 XSTR (split
, 3) = XSTR (desc
, 6);
221 /* Fix up the DEFINE_INSN. */
222 attr
= XVEC (desc
, 7);
223 PUT_CODE (desc
, DEFINE_INSN
);
224 XVEC (desc
, 4) = attr
;
228 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
231 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
232 insn_elem
->split
= split_elem
;
237 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
242 /* Return true if attribute PREDICABLE is true for ELEM, which holds
246 is_predicable (struct queue_elem
*elem
)
248 rtvec vec
= XVEC (elem
->data
, 4);
253 return predicable_default
;
255 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
257 rtx sub
= RTVEC_ELT (vec
, i
);
258 switch (GET_CODE (sub
))
261 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
263 value
= XSTR (sub
, 1);
268 case SET_ATTR_ALTERNATIVE
:
269 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
271 error_with_line (elem
->lineno
,
272 "multiple alternatives for `predicable'");
278 if (GET_CODE (SET_DEST (sub
)) != ATTR
279 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
282 if (GET_CODE (sub
) == CONST_STRING
)
284 value
= XSTR (sub
, 0);
288 /* ??? It would be possible to handle this if we really tried.
289 It's not easy though, and I'm not going to bother until it
290 really proves necessary. */
291 error_with_line (elem
->lineno
,
292 "non-constant value for `predicable'");
300 return predicable_default
;
303 /* Verify that predicability does not vary on the alternative. */
304 /* ??? It should be possible to handle this by simply eliminating
305 the non-predicable alternatives from the insn. FRV would like
306 to do this. Delay this until we've got the basics solid. */
307 if (strchr (value
, ',') != NULL
)
309 error_with_line (elem
->lineno
, "multiple alternatives for `predicable'");
313 /* Find out which value we're looking at. */
314 if (strcmp (value
, predicable_true
) == 0)
316 if (strcmp (value
, predicable_false
) == 0)
319 error_with_line (elem
->lineno
,
320 "unknown value `%s' for `predicable' attribute", value
);
324 /* Examine the attribute "predicable"; discover its boolean values
328 identify_predicable_attribute (void)
330 struct queue_elem
*elem
;
331 char *p_true
, *p_false
;
334 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
335 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
336 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
339 error_with_line (define_cond_exec_queue
->lineno
,
340 "attribute `predicable' not defined");
344 value
= XSTR (elem
->data
, 1);
345 p_false
= xstrdup (value
);
346 p_true
= strchr (p_false
, ',');
347 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
349 error_with_line (elem
->lineno
, "attribute `predicable' is not a boolean");
356 predicable_true
= p_true
;
357 predicable_false
= p_false
;
359 switch (GET_CODE (XEXP (elem
->data
, 2)))
362 value
= XSTR (XEXP (elem
->data
, 2), 0);
366 error_with_line (elem
->lineno
, "attribute `predicable' cannot be const");
372 error_with_line (elem
->lineno
,
373 "attribute `predicable' must have a constant default");
379 if (strcmp (value
, p_true
) == 0)
380 predicable_default
= 1;
381 else if (strcmp (value
, p_false
) == 0)
382 predicable_default
= 0;
385 error_with_line (elem
->lineno
,
386 "unknown value `%s' for `predicable' attribute", value
);
392 /* Return the number of alternatives in constraint S. */
395 n_alternatives (const char *s
)
406 /* Determine how many alternatives there are in INSN, and how many
410 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
416 code
= GET_CODE (pattern
);
420 i
= n_alternatives (XSTR (pattern
, 2));
421 *palt
= (i
> *palt
? i
: *palt
);
427 i
= XINT (pattern
, 0);
436 fmt
= GET_RTX_FORMAT (code
);
437 len
= GET_RTX_LENGTH (code
);
438 for (i
= 0; i
< len
; i
++)
443 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
447 if (XVEC (pattern
, i
) == NULL
)
451 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
452 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
455 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
465 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
471 code
= GET_CODE (pattern
);
476 const char *c
= XSTR (pattern
, 2);
478 if (n_alternatives (c
) != 1)
480 error_with_line (lineno
, "too many alternatives for operand %d",
485 /* Replicate C as needed to fill out ALT alternatives. */
486 if (c
&& *c
&& alt
> 1)
488 size_t c_len
= strlen (c
);
489 size_t len
= alt
* (c_len
+ 1);
490 char *new_c
= XNEWVEC(char, len
);
492 memcpy (new_c
, c
, c_len
);
493 for (i
= 1; i
< alt
; ++i
)
495 new_c
[i
* (c_len
+ 1) - 1] = ',';
496 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
498 new_c
[len
- 1] = '\0';
499 XSTR (pattern
, 2) = new_c
;
507 XINT (pattern
, 0) += max_op
;
514 fmt
= GET_RTX_FORMAT (code
);
515 len
= GET_RTX_LENGTH (code
);
516 for (i
= 0; i
< len
; i
++)
523 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
530 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
532 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
533 alt
, max_op
, lineno
);
539 case 'i': case 'w': case '0': case 's':
551 alter_test_for_insn (struct queue_elem
*ce_elem
,
552 struct queue_elem
*insn_elem
)
554 return join_c_conditions (XSTR (ce_elem
->data
, 1),
555 XSTR (insn_elem
->data
, 2));
558 /* Adjust all of the operand numbers in SRC to match the shift they'll
559 get from an operand displacement of DISP. Return a pointer after the
563 shift_output_template (char *dest
, const char *src
, int disp
)
572 if (ISDIGIT ((unsigned char) c
))
574 else if (ISALPHA (c
))
587 alter_output_for_insn (struct queue_elem
*ce_elem
,
588 struct queue_elem
*insn_elem
,
591 const char *ce_out
, *insn_out
;
593 size_t len
, ce_len
, insn_len
;
595 /* ??? Could coordinate with genoutput to not duplicate code here. */
597 ce_out
= XSTR (ce_elem
->data
, 2);
598 insn_out
= XTMPL (insn_elem
->data
, 3);
599 if (!ce_out
|| *ce_out
== '\0')
602 ce_len
= strlen (ce_out
);
603 insn_len
= strlen (insn_out
);
605 if (*insn_out
== '*')
606 /* You must take care of the predicate yourself. */
609 if (*insn_out
== '@')
611 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
612 p
= result
= XNEWVEC(char, len
);
618 while (ISSPACE ((unsigned char) *insn_out
));
620 if (*insn_out
!= '#')
622 p
= shift_output_template (p
, ce_out
, max_op
);
628 while (*insn_out
&& *insn_out
!= '\n');
635 len
= ce_len
+ 1 + insn_len
+ 1;
636 result
= XNEWVEC (char, len
);
638 p
= shift_output_template (result
, ce_out
, max_op
);
640 memcpy (p
, insn_out
, insn_len
+ 1);
646 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
649 process_one_cond_exec (struct queue_elem
*ce_elem
)
651 struct queue_elem
*insn_elem
;
652 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
654 int alternatives
, max_operand
;
655 rtx pred
, insn
, pattern
, split
;
659 if (! is_predicable (insn_elem
))
664 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
667 if (XVECLEN (ce_elem
->data
, 0) != 1)
669 error_with_line (ce_elem
->lineno
, "too many patterns in predicate");
673 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
674 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
679 /* Construct a new pattern for the new insn. */
680 insn
= copy_rtx (insn_elem
->data
);
681 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
682 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
683 XSTR (insn
, 0) = new_name
;
684 pattern
= rtx_alloc (COND_EXEC
);
685 XEXP (pattern
, 0) = pred
;
686 if (XVECLEN (insn
, 1) == 1)
688 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
689 XVECEXP (insn
, 1, 0) = pattern
;
690 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
694 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
695 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
696 XVEC (insn
, 1) = rtvec_alloc (1);
697 XVECEXP (insn
, 1, 0) = pattern
;
700 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
701 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
702 alternatives
, max_operand
);
704 /* ??? Set `predicable' to false. Not crucial since it's really
705 only used here, and we won't reprocess this new pattern. */
707 /* Put the new pattern on the `other' list so that it
708 (a) is not reprocessed by other define_cond_exec patterns
709 (b) appears after all normal define_insn patterns.
711 ??? B is debatable. If one has normal insns that match
712 cond_exec patterns, they will be preferred over these
713 generated patterns. Whether this matters in practice, or if
714 it's a good thing, or whether we should thread these new
715 patterns into the define_insn chain just after their generator
716 is something we'll have to experiment with. */
718 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
721 if (!insn_elem
->split
)
724 /* If the original insn came from a define_insn_and_split,
725 generate a new split to handle the predicated insn. */
726 split
= copy_rtx (insn_elem
->split
->data
);
727 /* Predicate the pattern matched by the split. */
728 pattern
= rtx_alloc (COND_EXEC
);
729 XEXP (pattern
, 0) = pred
;
730 if (XVECLEN (split
, 0) == 1)
732 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
733 XVECEXP (split
, 0, 0) = pattern
;
734 PUT_NUM_ELEM (XVEC (split
, 0), 1);
738 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
739 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
740 XVEC (split
, 0) = rtvec_alloc (1);
741 XVECEXP (split
, 0, 0) = pattern
;
743 /* Predicate all of the insns generated by the split. */
744 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
746 pattern
= rtx_alloc (COND_EXEC
);
747 XEXP (pattern
, 0) = pred
;
748 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
749 XVECEXP (split
, 2, i
) = pattern
;
751 /* Add the new split to the queue. */
752 queue_pattern (split
, &other_tail
, read_md_filename
,
753 insn_elem
->split
->lineno
);
757 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
758 patterns appropriately. */
761 process_define_cond_exec (void)
763 struct queue_elem
*elem
;
765 identify_predicable_attribute ();
769 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
770 process_one_cond_exec (elem
);
773 /* A read_md_files callback for reading an rtx. */
776 rtx_handle_directive (int lineno
, const char *rtx_name
)
780 if (read_rtx (rtx_name
, &queue
))
781 for (x
= queue
; x
; x
= XEXP (x
, 1))
782 process_rtx (XEXP (x
, 0), lineno
);
785 /* The entry point for initializing the reader. */
788 init_rtx_reader_args_cb (int argc
, char **argv
,
789 bool (*parse_opt
) (const char *))
791 /* Prepare to read input. */
792 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
793 init_predicate_table ();
794 obstack_init (rtl_obstack
);
797 read_md_files (argc
, argv
, parse_opt
, rtx_handle_directive
);
799 /* Process define_cond_exec patterns. */
800 if (define_cond_exec_queue
!= NULL
)
801 process_define_cond_exec ();
806 /* Programs that don't have their own options can use this entry point
809 init_rtx_reader_args (int argc
, char **argv
)
811 return init_rtx_reader_args_cb (argc
, argv
, 0);
814 /* The entry point for reading a single rtx from an md file. */
817 read_md_rtx (int *lineno
, int *seqnr
)
819 struct queue_elem
**queue
, *elem
;
824 /* Read all patterns from a given queue before moving on to the next. */
825 if (define_attr_queue
!= NULL
)
826 queue
= &define_attr_queue
;
827 else if (define_pred_queue
!= NULL
)
828 queue
= &define_pred_queue
;
829 else if (define_insn_queue
!= NULL
)
830 queue
= &define_insn_queue
;
831 else if (other_queue
!= NULL
)
832 queue
= &other_queue
;
839 read_md_filename
= elem
->filename
;
840 *lineno
= elem
->lineno
;
841 *seqnr
= sequence_num
;
845 /* Discard insn patterns which we know can never match (because
846 their C test is provably always false). If insn_elision is
847 false, our caller needs to see all the patterns. Note that the
848 elided patterns are never counted by the sequence numbering; it
849 it is the caller's responsibility, when insn_elision is false, not
850 to use elided pattern numbers for anything. */
851 switch (GET_CODE (desc
))
855 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
857 else if (insn_elision
)
860 /* *seqnr is used here so the name table will match caller's
861 idea of insn numbering, whether or not elision is active. */
862 record_insn_name (*seqnr
, XSTR (desc
, 0));
866 case DEFINE_PEEPHOLE
:
867 case DEFINE_PEEPHOLE2
:
868 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
870 else if (insn_elision
)
881 /* Helper functions for insn elision. */
883 /* Compute a hash function of a c_test structure, which is keyed
884 by its ->expr field. */
886 hash_c_test (const void *x
)
888 const struct c_test
*a
= (const struct c_test
*) x
;
889 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
897 while ((c
= *s
++) != '\0')
899 hash
+= c
+ (c
<< 17);
904 hash
+= len
+ (len
<< 17);
910 /* Compare two c_test expression structures. */
912 cmp_c_test (const void *x
, const void *y
)
914 const struct c_test
*a
= (const struct c_test
*) x
;
915 const struct c_test
*b
= (const struct c_test
*) y
;
917 return !strcmp (a
->expr
, b
->expr
);
920 /* Given a string representing a C test expression, look it up in the
921 condition_table and report whether or not its value is known
922 at compile time. Returns a tristate: 1 for known true, 0 for
923 known false, -1 for unknown. */
925 maybe_eval_c_test (const char *expr
)
927 const struct c_test
*test
;
934 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
940 /* Record the C test expression EXPR in the condition_table, with
941 value VAL. Duplicates clobber previous entries. */
944 add_c_test (const char *expr
, int value
)
951 test
= XNEW (struct c_test
);
955 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
958 /* For every C test, call CALLBACK with two arguments: a pointer to
959 the condition structure and INFO. Stops when CALLBACK returns zero. */
961 traverse_c_tests (htab_trav callback
, void *info
)
964 htab_traverse (condition_table
, callback
, info
);
967 /* Helper functions for define_predicate and define_special_predicate
968 processing. Shared between genrecog.c and genpreds.c. */
970 static htab_t predicate_table
;
971 struct pred_data
*first_predicate
;
972 static struct pred_data
**last_predicate
= &first_predicate
;
975 hash_struct_pred_data (const void *ptr
)
977 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
981 eq_struct_pred_data (const void *a
, const void *b
)
983 return !strcmp (((const struct pred_data
*)a
)->name
,
984 ((const struct pred_data
*)b
)->name
);
988 lookup_predicate (const char *name
)
990 struct pred_data key
;
992 return (struct pred_data
*) htab_find (predicate_table
, &key
);
995 /* Record that predicate PRED can accept CODE. */
998 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
1000 if (!pred
->codes
[code
])
1003 pred
->codes
[code
] = true;
1005 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
1006 pred
->allows_non_const
= true;
1013 && code
!= STRICT_LOW_PART
)
1014 pred
->allows_non_lvalue
= true;
1016 if (pred
->num_codes
== 1)
1017 pred
->singleton
= code
;
1018 else if (pred
->num_codes
== 2)
1019 pred
->singleton
= UNKNOWN
;
1024 add_predicate (struct pred_data
*pred
)
1026 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
1029 error ("duplicate predicate definition for '%s'", pred
->name
);
1033 *last_predicate
= pred
;
1034 last_predicate
= &pred
->next
;
1037 /* This array gives the initial content of the predicate table. It
1038 has entries for all predicates defined in recog.c. */
1040 struct std_pred_table
1044 bool allows_const_p
;
1045 RTX_CODE codes
[NUM_RTX_CODE
];
1048 static const struct std_pred_table std_preds
[] = {
1049 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
1050 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
}},
1051 {"register_operand", false, false, {SUBREG
, REG
}},
1052 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
1053 {"scratch_operand", false, false, {SCRATCH
, REG
}},
1054 {"immediate_operand", false, true, {UNKNOWN
}},
1055 {"const_int_operand", false, false, {CONST_INT
}},
1056 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
1057 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
1058 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
1059 {"push_operand", false, false, {MEM
}},
1060 {"pop_operand", false, false, {MEM
}},
1061 {"memory_operand", false, false, {SUBREG
, MEM
}},
1062 {"indirect_operand", false, false, {SUBREG
, MEM
}},
1063 {"ordered_comparison_operator", false, false, {EQ
, NE
,
1065 LEU
, LTU
, GEU
, GTU
}},
1066 {"comparison_operator", false, false, {EQ
, NE
,
1073 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1075 /* Initialize the table of predicate definitions, starting with
1076 the information we have on generic predicates. */
1079 init_predicate_table (void)
1082 struct pred_data
*pred
;
1084 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
1085 eq_struct_pred_data
, 0,
1088 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
1090 pred
= XCNEW (struct pred_data
);
1091 pred
->name
= std_preds
[i
].name
;
1092 pred
->special
= std_preds
[i
].special
;
1094 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
1095 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
1097 if (std_preds
[i
].allows_const_p
)
1098 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
1099 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
1100 add_predicate_code (pred
, (enum rtx_code
) j
);
1102 add_predicate (pred
);
1106 /* These functions allow linkage with print-rtl.c. Also, some generators
1107 like to annotate their output with insn names. */
1109 /* Holds an array of names indexed by insn_code_number. */
1110 static char **insn_name_ptr
= 0;
1111 static int insn_name_ptr_size
= 0;
1114 get_insn_name (int code
)
1116 if (code
< insn_name_ptr_size
)
1117 return insn_name_ptr
[code
];
1123 record_insn_name (int code
, const char *name
)
1125 static const char *last_real_name
= "insn";
1126 static int last_real_code
= 0;
1129 if (insn_name_ptr_size
<= code
)
1132 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
1133 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
1134 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
1135 sizeof(char *) * (new_size
- insn_name_ptr_size
));
1136 insn_name_ptr_size
= new_size
;
1139 if (!name
|| name
[0] == '\0')
1141 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
1142 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
1146 last_real_name
= new_name
= xstrdup (name
);
1147 last_real_code
= code
;
1150 insn_name_ptr
[code
] = new_name
;