1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "gensupport.h"
31 #define MAX_OPERANDS 40
33 static rtx operand_data
[MAX_OPERANDS
];
34 static rtx match_operand_entries_in_pattern
[MAX_OPERANDS
];
35 static char used_operands_numbers
[MAX_OPERANDS
];
38 /* In case some macros used by files we include need it, define this here. */
43 static struct obstack obstack
;
44 struct obstack
*rtl_obstack
= &obstack
;
46 /* Counter for named patterns and INSN_CODEs. */
47 static int insn_sequence_num
;
49 /* Counter for define_splits. */
50 static int split_sequence_num
;
52 /* Counter for define_peephole2s. */
53 static int peephole2_sequence_num
;
55 static int predicable_default
;
56 static const char *predicable_true
;
57 static const char *predicable_false
;
59 static const char *subst_true
= "yes";
60 static const char *subst_false
= "no";
62 static htab_t condition_table
;
64 /* We initially queue all patterns, process the define_insn,
65 define_cond_exec and define_subst patterns, then return
66 them one at a time. */
72 struct queue_elem
*next
;
73 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
74 points to the generated DEFINE_SPLIT. */
75 struct queue_elem
*split
;
78 #define MNEMONIC_ATTR_NAME "mnemonic"
79 #define MNEMONIC_HTAB_SIZE 1024
81 static struct queue_elem
*define_attr_queue
;
82 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
83 static struct queue_elem
*define_pred_queue
;
84 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
85 static struct queue_elem
*define_insn_queue
;
86 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
87 static struct queue_elem
*define_cond_exec_queue
;
88 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
89 static struct queue_elem
*define_subst_queue
;
90 static struct queue_elem
**define_subst_tail
= &define_subst_queue
;
91 static struct queue_elem
*other_queue
;
92 static struct queue_elem
**other_tail
= &other_queue
;
93 static struct queue_elem
*define_subst_attr_queue
;
94 static struct queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
96 static void remove_constraints (rtx
);
98 static int is_predicable (struct queue_elem
*);
99 static void identify_predicable_attribute (void);
100 static int n_alternatives (const char *);
101 static void collect_insn_data (rtx
, int *, int *);
102 static const char *alter_test_for_insn (struct queue_elem
*,
103 struct queue_elem
*);
104 static char *shift_output_template (char *, const char *, int);
105 static const char *alter_output_for_insn (struct queue_elem
*,
108 static void process_one_cond_exec (struct queue_elem
*);
109 static void process_define_cond_exec (void);
110 static void init_predicate_table (void);
111 static void record_insn_name (int, const char *);
113 static bool has_subst_attribute (struct queue_elem
*, struct queue_elem
*);
114 static const char * alter_output_for_subst_insn (rtx
, int);
115 static void alter_attrs_for_subst_insn (struct queue_elem
*, int);
116 static void process_substs_on_one_elem (struct queue_elem
*,
117 struct queue_elem
*);
118 static rtx
subst_dup (rtx
, int, int);
119 static void process_define_subst (void);
121 static const char * duplicate_alternatives (const char *, int);
122 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
124 typedef const char * (*constraints_handler_t
) (const char *, int);
125 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
126 static rtx
adjust_operands_numbers (rtx
);
127 static rtx
replace_duplicating_operands_in_pattern (rtx
);
129 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
130 the gensupport programs. */
133 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
136 rtx rt
= rtx_alloc (CONST_INT
);
142 /* Return the rtx pattern specified by the list of rtxes in a
143 define_insn or define_split. */
146 add_implicit_parallel (rtvec vec
)
148 if (GET_NUM_ELEM (vec
) == 1)
149 return RTVEC_ELT (vec
, 0);
152 rtx pattern
= rtx_alloc (PARALLEL
);
153 XVEC (pattern
, 0) = vec
;
158 /* Predicate handling.
160 We construct from the machine description a table mapping each
161 predicate to a list of the rtl codes it can possibly match. The
162 function 'maybe_both_true' uses it to deduce that there are no
163 expressions that can be matches by certain pairs of tree nodes.
164 Also, if a predicate can match only one code, we can hardwire that
165 code into the node testing the predicate.
167 Some predicates are flagged as special. validate_pattern will not
168 warn about modeless match_operand expressions if they have a
169 special predicate. Predicates that allow only constants are also
170 treated as special, for this purpose.
172 validate_pattern will warn about predicates that allow non-lvalues
173 when they appear in destination operands.
175 Calculating the set of rtx codes that can possibly be accepted by a
176 predicate expression EXP requires a three-state logic: any given
177 subexpression may definitively accept a code C (Y), definitively
178 reject a code C (N), or may have an indeterminate effect (I). N
179 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
190 We represent Y with 1, N with 0, I with 2. If any code is left in
191 an I state by the complete expression, we must assume that that
192 code can be accepted. */
198 #define TRISTATE_AND(a,b) \
199 ((a) == I ? ((b) == N ? N : I) : \
200 (b) == I ? ((a) == N ? N : I) : \
203 #define TRISTATE_OR(a,b) \
204 ((a) == I ? ((b) == Y ? Y : I) : \
205 (b) == I ? ((a) == Y ? Y : I) : \
208 #define TRISTATE_NOT(a) \
209 ((a) == I ? I : !(a))
211 /* 0 means no warning about that code yet, 1 means warned. */
212 static char did_you_mean_codes
[NUM_RTX_CODE
];
214 /* Recursively calculate the set of rtx codes accepted by the
215 predicate expression EXP, writing the result to CODES. LOC is
216 the .md file location of the directive containing EXP. */
219 compute_test_codes (rtx exp
, file_location loc
, char *codes
)
221 char op0_codes
[NUM_RTX_CODE
];
222 char op1_codes
[NUM_RTX_CODE
];
223 char op2_codes
[NUM_RTX_CODE
];
226 switch (GET_CODE (exp
))
229 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
230 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
231 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
232 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
236 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
237 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
238 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
239 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
242 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
243 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
244 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
248 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
249 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
250 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
251 compute_test_codes (XEXP (exp
, 2), loc
, op2_codes
);
252 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
253 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
254 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
259 /* MATCH_CODE allows a specified list of codes. However, if it
260 does not apply to the top level of the expression, it does not
261 constrain the set of codes for the top level. */
262 if (XSTR (exp
, 1)[0] != '\0')
264 memset (codes
, Y
, NUM_RTX_CODE
);
268 memset (codes
, N
, NUM_RTX_CODE
);
270 const char *next_code
= XSTR (exp
, 0);
273 if (*next_code
== '\0')
275 error_at (loc
, "empty match_code expression");
279 while ((code
= scan_comma_elt (&next_code
)) != 0)
281 size_t n
= next_code
- code
;
284 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
285 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
286 && GET_RTX_NAME (i
)[n
] == '\0')
294 error_at (loc
, "match_code \"%.*s\" matches nothing",
296 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
297 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
298 && GET_RTX_NAME (i
)[n
] == '\0'
299 && !did_you_mean_codes
[i
])
301 did_you_mean_codes
[i
] = 1;
302 message_at (loc
, "(did you mean \"%s\"?)",
311 /* MATCH_OPERAND disallows the set of codes that the named predicate
312 disallows, and is indeterminate for the codes that it does allow. */
314 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
317 error_at (loc
, "reference to unknown predicate '%s'",
321 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
322 codes
[i
] = p
->codes
[i
] ? I
: N
;
328 /* (match_test WHATEVER) is completely indeterminate. */
329 memset (codes
, I
, NUM_RTX_CODE
);
333 error_at (loc
, "'%s' cannot be used in predicates or constraints",
334 GET_RTX_NAME (GET_CODE (exp
)));
335 memset (codes
, I
, NUM_RTX_CODE
);
344 /* Return true if NAME is a valid predicate name. */
347 valid_predicate_name_p (const char *name
)
351 if (!ISALPHA (name
[0]) && name
[0] != '_')
353 for (p
= name
+ 1; *p
; p
++)
354 if (!ISALNUM (*p
) && *p
!= '_')
359 /* Process define_predicate directive DESC, which appears at location LOC.
360 Compute the set of codes that can be matched, and record this as a known
364 process_define_predicate (rtx desc
, file_location loc
)
366 struct pred_data
*pred
;
367 char codes
[NUM_RTX_CODE
];
370 if (!valid_predicate_name_p (XSTR (desc
, 0)))
372 error_at (loc
, "%s: predicate name must be a valid C function name",
377 pred
= XCNEW (struct pred_data
);
378 pred
->name
= XSTR (desc
, 0);
379 pred
->exp
= XEXP (desc
, 1);
380 pred
->c_block
= XSTR (desc
, 2);
381 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
382 pred
->special
= true;
384 compute_test_codes (XEXP (desc
, 1), loc
, codes
);
386 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
388 add_predicate_code (pred
, (enum rtx_code
) i
);
390 add_predicate (pred
);
396 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
399 static struct queue_elem
*
400 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
403 struct queue_elem
*e
= XNEW (struct queue_elem
);
409 *list_tail
= &e
->next
;
413 /* Remove element ELEM from QUEUE. */
415 remove_from_queue (struct queue_elem
*elem
, struct queue_elem
**queue
)
417 struct queue_elem
*prev
, *e
;
419 for (e
= *queue
; e
; e
= e
->next
)
429 prev
->next
= elem
->next
;
434 /* Build a define_attr for an binary attribute with name NAME and
435 possible values "yes" and "no", and queue it. */
437 add_define_attr (const char *name
)
439 struct queue_elem
*e
= XNEW (struct queue_elem
);
440 rtx t1
= rtx_alloc (DEFINE_ATTR
);
442 XSTR (t1
, 1) = "no,yes";
443 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
444 XSTR (XEXP (t1
, 2), 0) = "yes";
446 e
->loc
= file_location ("built-in", -1);
447 e
->next
= define_attr_queue
;
448 define_attr_queue
= e
;
452 /* Recursively remove constraints from an rtx. */
455 remove_constraints (rtx part
)
458 const char *format_ptr
;
463 if (GET_CODE (part
) == MATCH_OPERAND
)
465 else if (GET_CODE (part
) == MATCH_SCRATCH
)
468 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
470 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
471 switch (*format_ptr
++)
475 remove_constraints (XEXP (part
, i
));
478 if (XVEC (part
, i
) != NULL
)
479 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
480 remove_constraints (XVECEXP (part
, i
, j
));
485 /* Process a top level rtx in some way, queuing as appropriate. */
488 process_rtx (rtx desc
, file_location loc
)
490 switch (GET_CODE (desc
))
493 queue_pattern (desc
, &define_insn_tail
, loc
);
496 case DEFINE_COND_EXEC
:
497 queue_pattern (desc
, &define_cond_exec_tail
, loc
);
501 queue_pattern (desc
, &define_subst_tail
, loc
);
504 case DEFINE_SUBST_ATTR
:
505 queue_pattern (desc
, &define_subst_attr_tail
, loc
);
509 case DEFINE_ENUM_ATTR
:
510 queue_pattern (desc
, &define_attr_tail
, loc
);
513 case DEFINE_PREDICATE
:
514 case DEFINE_SPECIAL_PREDICATE
:
515 process_define_predicate (desc
, loc
);
518 case DEFINE_CONSTRAINT
:
519 case DEFINE_REGISTER_CONSTRAINT
:
520 case DEFINE_MEMORY_CONSTRAINT
:
521 case DEFINE_ADDRESS_CONSTRAINT
:
522 queue_pattern (desc
, &define_pred_tail
, loc
);
525 case DEFINE_INSN_AND_SPLIT
:
527 const char *split_cond
;
531 struct queue_elem
*insn_elem
;
532 struct queue_elem
*split_elem
;
534 /* Create a split with values from the insn_and_split. */
535 split
= rtx_alloc (DEFINE_SPLIT
);
537 i
= XVECLEN (desc
, 1);
538 XVEC (split
, 0) = rtvec_alloc (i
);
541 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
542 remove_constraints (XVECEXP (split
, 0, i
));
545 /* If the split condition starts with "&&", append it to the
546 insn condition to create the new split condition. */
547 split_cond
= XSTR (desc
, 4);
548 if (split_cond
[0] == '&' && split_cond
[1] == '&')
550 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
551 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
553 XSTR (split
, 1) = split_cond
;
554 XVEC (split
, 2) = XVEC (desc
, 5);
555 XSTR (split
, 3) = XSTR (desc
, 6);
557 /* Fix up the DEFINE_INSN. */
558 attr
= XVEC (desc
, 7);
559 PUT_CODE (desc
, DEFINE_INSN
);
560 XVEC (desc
, 4) = attr
;
563 insn_elem
= queue_pattern (desc
, &define_insn_tail
, loc
);
564 split_elem
= queue_pattern (split
, &other_tail
, loc
);
565 insn_elem
->split
= split_elem
;
570 queue_pattern (desc
, &other_tail
, loc
);
575 /* Return true if attribute PREDICABLE is true for ELEM, which holds
579 is_predicable (struct queue_elem
*elem
)
581 rtvec vec
= XVEC (elem
->data
, 4);
586 return predicable_default
;
588 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
590 rtx sub
= RTVEC_ELT (vec
, i
);
591 switch (GET_CODE (sub
))
594 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
596 value
= XSTR (sub
, 1);
601 case SET_ATTR_ALTERNATIVE
:
602 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
604 error_at (elem
->loc
, "multiple alternatives for `predicable'");
610 if (GET_CODE (SET_DEST (sub
)) != ATTR
611 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
614 if (GET_CODE (sub
) == CONST_STRING
)
616 value
= XSTR (sub
, 0);
620 /* ??? It would be possible to handle this if we really tried.
621 It's not easy though, and I'm not going to bother until it
622 really proves necessary. */
623 error_at (elem
->loc
, "non-constant value for `predicable'");
631 return predicable_default
;
634 /* Find out which value we're looking at. Multiple alternatives means at
635 least one is predicable. */
636 if (strchr (value
, ',') != NULL
)
638 if (strcmp (value
, predicable_true
) == 0)
640 if (strcmp (value
, predicable_false
) == 0)
643 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute", value
);
647 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
649 change_subst_attribute (struct queue_elem
*elem
,
650 struct queue_elem
*subst_elem
,
651 const char *new_value
)
653 rtvec attrs_vec
= XVEC (elem
->data
, 4);
654 const char *subst_name
= XSTR (subst_elem
->data
, 0);
660 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
662 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
663 if (GET_CODE (cur_attr
) != SET_ATTR
)
665 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
667 XSTR (cur_attr
, 1) = new_value
;
673 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
674 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
675 DEFINE_SUBST isn't applied to patterns without such attribute. In other
676 words, we suppose the default value of the attribute to be 'no' since it is
677 always generated automaticaly in read-rtl.c. */
679 has_subst_attribute (struct queue_elem
*elem
, struct queue_elem
*subst_elem
)
681 rtvec attrs_vec
= XVEC (elem
->data
, 4);
682 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
688 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
690 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
691 switch (GET_CODE (cur_attr
))
694 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
696 value
= XSTR (cur_attr
, 1);
702 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
703 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
705 cur_attr
= SET_SRC (cur_attr
);
706 if (GET_CODE (cur_attr
) == CONST_STRING
)
708 value
= XSTR (cur_attr
, 0);
712 /* Only (set_attr "subst" "yes/no") and
713 (set (attr "subst" (const_string "yes/no")))
714 are currently allowed. */
715 error_at (elem
->loc
, "unsupported value for `%s'", subst_name
);
718 case SET_ATTR_ALTERNATIVE
:
720 "%s: `set_attr_alternative' is unsupported by "
721 "`define_subst'", XSTR (elem
->data
, 0));
733 if (strcmp (value
, subst_true
) == 0)
735 if (strcmp (value
, subst_false
) == 0)
738 error_at (elem
->loc
, "unknown value `%s' for `%s' attribute",
743 /* Compare RTL-template of original define_insn X to input RTL-template of
744 define_subst PT. Return 1 if the templates match, 0 otherwise.
745 During the comparison, the routine also fills global_array OPERAND_DATA. */
747 subst_pattern_match (rtx x
, rtx pt
, file_location loc
)
749 RTX_CODE code
, code_pt
;
751 const char *fmt
, *pred_name
;
754 code_pt
= GET_CODE (pt
);
756 if (code_pt
== MATCH_OPERAND
)
758 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
759 always accept them. */
760 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
761 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
762 return false; /* Modes don't match. */
764 if (code
== MATCH_OPERAND
)
766 pred_name
= XSTR (pt
, 1);
767 if (pred_name
[0] != 0)
769 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
770 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
771 return false; /* Predicates don't match. */
775 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
776 operand_data
[XINT (pt
, 0)] = x
;
780 if (code_pt
== MATCH_OPERATOR
)
782 int x_vecexp_pos
= -1;
785 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
788 /* In case X is also match_operator, compare predicates. */
789 if (code
== MATCH_OPERATOR
)
791 pred_name
= XSTR (pt
, 1);
792 if (pred_name
[0] != 0)
794 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
795 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
801 MATCH_OPERATOR in input template could match in original template
802 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
803 In the first case operands are at (XVECEXP (x, 2, j)), in the second
804 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
805 X_VECEXP_POS variable shows, where to look for these operands. */
807 || code
== UNSPEC_VOLATILE
)
809 else if (code
== MATCH_OPERATOR
)
814 /* MATCH_OPERATOR or UNSPEC case. */
815 if (x_vecexp_pos
>= 0)
817 /* Compare operands number in X and PT. */
818 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
820 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
821 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
822 XVECEXP (pt
, 2, j
), loc
))
826 /* Ordinary operator. */
829 /* Compare operands number in X and PT.
830 We count operands differently for X and PT since we compare
831 an operator (with operands directly in RTX) and MATCH_OPERATOR
832 (that has a vector with operands). */
833 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
835 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
836 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), loc
))
840 /* Store the operand to OPERAND_DATA array. */
841 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
842 operand_data
[XINT (pt
, 0)] = x
;
846 if (code_pt
== MATCH_PAR_DUP
847 || code_pt
== MATCH_DUP
848 || code_pt
== MATCH_OP_DUP
849 || code_pt
== MATCH_SCRATCH
850 || code_pt
== MATCH_PARALLEL
)
852 /* Currently interface for these constructions isn't defined -
853 probably they aren't needed in input template of define_subst at all.
854 So, for now their usage in define_subst is forbidden. */
855 error_at (loc
, "%s cannot be used in define_subst",
856 GET_RTX_NAME (code_pt
));
859 gcc_assert (code
!= MATCH_PAR_DUP
860 && code_pt
!= MATCH_DUP
861 && code_pt
!= MATCH_OP_DUP
862 && code_pt
!= MATCH_SCRATCH
863 && code_pt
!= MATCH_PARALLEL
864 && code_pt
!= MATCH_OPERAND
865 && code_pt
!= MATCH_OPERATOR
);
866 /* If PT is none of the handled above, then we match only expressions with
867 the same code in X. */
871 fmt
= GET_RTX_FORMAT (code_pt
);
872 len
= GET_RTX_LENGTH (code_pt
);
874 for (i
= 0; i
< len
; i
++)
881 case 'i': case 'r': case 'w': case 's':
885 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), loc
))
890 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
892 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
893 if (!subst_pattern_match (XVECEXP (x
, i
, j
),
894 XVECEXP (pt
, i
, j
), loc
))
906 /* Examine the attribute "predicable"; discover its boolean values
910 identify_predicable_attribute (void)
912 struct queue_elem
*elem
;
913 char *p_true
, *p_false
;
916 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
917 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
918 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
921 error_at (define_cond_exec_queue
->loc
,
922 "attribute `predicable' not defined");
926 value
= XSTR (elem
->data
, 1);
927 p_false
= xstrdup (value
);
928 p_true
= strchr (p_false
, ',');
929 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
931 error_at (elem
->loc
, "attribute `predicable' is not a boolean");
937 predicable_true
= p_true
;
938 predicable_false
= p_false
;
940 switch (GET_CODE (XEXP (elem
->data
, 2)))
943 value
= XSTR (XEXP (elem
->data
, 2), 0);
947 error_at (elem
->loc
, "attribute `predicable' cannot be const");
953 "attribute `predicable' must have a constant default");
958 if (strcmp (value
, p_true
) == 0)
959 predicable_default
= 1;
960 else if (strcmp (value
, p_false
) == 0)
961 predicable_default
= 0;
964 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute",
970 /* Return the number of alternatives in constraint S. */
973 n_alternatives (const char *s
)
984 /* The routine scans rtl PATTERN, find match_operand in it and counts
985 number of alternatives. If PATTERN contains several match_operands
986 with different number of alternatives, error is emitted, and the
987 routine returns 0. If all match_operands in PATTERN have the same
988 number of alternatives, it's stored in N_ALT, and the routine returns 1.
989 LOC is the location of PATTERN, for error reporting. */
991 get_alternatives_number (rtx pattern
, int *n_alt
, file_location loc
)
1000 code
= GET_CODE (pattern
);
1004 i
= n_alternatives (XSTR (pattern
, 2));
1005 /* n_alternatives returns 1 if constraint string is empty -
1006 here we fix it up. */
1007 if (!*(XSTR (pattern
, 2)))
1012 else if (i
&& i
!= *n_alt
)
1014 error_at (loc
, "wrong number of alternatives in operand %d",
1023 fmt
= GET_RTX_FORMAT (code
);
1024 len
= GET_RTX_LENGTH (code
);
1025 for (i
= 0; i
< len
; i
++)
1030 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, loc
))
1035 if (XVEC (pattern
, i
) == NULL
)
1039 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1040 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
), n_alt
, loc
))
1044 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1054 /* Determine how many alternatives there are in INSN, and how many
1058 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1064 code
= GET_CODE (pattern
);
1068 i
= n_alternatives (XSTR (pattern
, 2));
1069 *palt
= (i
> *palt
? i
: *palt
);
1072 case MATCH_OPERATOR
:
1074 case MATCH_PARALLEL
:
1075 i
= XINT (pattern
, 0);
1084 fmt
= GET_RTX_FORMAT (code
);
1085 len
= GET_RTX_LENGTH (code
);
1086 for (i
= 0; i
< len
; i
++)
1091 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1095 if (XVEC (pattern
, i
) == NULL
)
1099 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1100 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1103 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1113 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
,
1120 code
= GET_CODE (pattern
);
1125 const char *c
= XSTR (pattern
, 2);
1127 if (n_alternatives (c
) != 1)
1129 error_at (loc
, "too many alternatives for operand %d",
1134 /* Replicate C as needed to fill out ALT alternatives. */
1135 if (c
&& *c
&& alt
> 1)
1137 size_t c_len
= strlen (c
);
1138 size_t len
= alt
* (c_len
+ 1);
1139 char *new_c
= XNEWVEC (char, len
);
1141 memcpy (new_c
, c
, c_len
);
1142 for (i
= 1; i
< alt
; ++i
)
1144 new_c
[i
* (c_len
+ 1) - 1] = ',';
1145 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1147 new_c
[len
- 1] = '\0';
1148 XSTR (pattern
, 2) = new_c
;
1153 case MATCH_OPERATOR
:
1155 case MATCH_PARALLEL
:
1156 XINT (pattern
, 0) += max_op
;
1163 fmt
= GET_RTX_FORMAT (code
);
1164 len
= GET_RTX_LENGTH (code
);
1165 for (i
= 0; i
< len
; i
++)
1172 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
, max_op
, loc
);
1178 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1180 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1187 case 'i': case 'r': case 'w': case '0': case 's':
1198 /* Duplicate constraints in PATTERN. If pattern is from original
1199 rtl-template, we need to duplicate each alternative - for that we
1200 need to use duplicate_each_alternative () as a functor ALTER.
1201 If pattern is from output-pattern of define_subst, we need to
1202 duplicate constraints in another way - with duplicate_alternatives ().
1203 N_DUP is multiplication factor. */
1205 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1211 code
= GET_CODE (pattern
);
1215 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1222 fmt
= GET_RTX_FORMAT (code
);
1223 len
= GET_RTX_LENGTH (code
);
1224 for (i
= 0; i
< len
; i
++)
1231 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1237 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1239 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1245 case 'i': case 'r': case 'w': case '0': case 's':
1257 alter_test_for_insn (struct queue_elem
*ce_elem
,
1258 struct queue_elem
*insn_elem
)
1260 return join_c_conditions (XSTR (ce_elem
->data
, 1),
1261 XSTR (insn_elem
->data
, 2));
1264 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1265 to take "ce_enabled" into account. Return the new expression. */
1267 modify_attr_enabled_ce (rtx val
)
1271 eq_attr
= rtx_alloc (EQ_ATTR
);
1272 ite
= rtx_alloc (IF_THEN_ELSE
);
1273 str
= rtx_alloc (CONST_STRING
);
1275 XSTR (eq_attr
, 0) = "ce_enabled";
1276 XSTR (eq_attr
, 1) = "yes";
1277 XSTR (str
, 0) = "no";
1278 XEXP (ite
, 0) = eq_attr
;
1279 XEXP (ite
, 1) = val
;
1280 XEXP (ite
, 2) = str
;
1285 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1286 from a define_insn pattern. We must modify the "predicable" attribute
1287 to be named "ce_enabled", and also change any "enabled" attribute that's
1288 present so that it takes ce_enabled into account.
1289 We rely on the fact that INSN was created with copy_rtx, and modify data
1293 alter_attrs_for_insn (rtx insn
)
1295 static bool global_changes_made
= false;
1296 rtvec vec
= XVEC (insn
, 4);
1300 int predicable_idx
= -1;
1301 int enabled_idx
= -1;
1307 num_elem
= GET_NUM_ELEM (vec
);
1308 for (i
= num_elem
- 1; i
>= 0; --i
)
1310 rtx sub
= RTVEC_ELT (vec
, i
);
1311 switch (GET_CODE (sub
))
1314 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1317 XSTR (sub
, 0) = "ce_enabled";
1319 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1322 XSTR (sub
, 0) = "nonce_enabled";
1326 case SET_ATTR_ALTERNATIVE
:
1327 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1328 /* We already give an error elsewhere. */
1330 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1333 XSTR (sub
, 0) = "nonce_enabled";
1338 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1340 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1342 sub
= SET_SRC (sub
);
1343 if (GET_CODE (sub
) == CONST_STRING
)
1346 XSTR (sub
, 0) = "ce_enabled";
1349 /* We already give an error elsewhere. */
1353 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1356 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1364 if (predicable_idx
== -1)
1367 if (!global_changes_made
)
1369 struct queue_elem
*elem
;
1371 global_changes_made
= true;
1372 add_define_attr ("ce_enabled");
1373 add_define_attr ("nonce_enabled");
1375 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1376 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1378 XEXP (elem
->data
, 2)
1379 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1382 if (enabled_idx
== -1)
1385 new_vec
= rtvec_alloc (num_elem
+ 1);
1386 for (i
= 0; i
< num_elem
; i
++)
1387 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1388 val
= rtx_alloc (IF_THEN_ELSE
);
1389 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1390 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1391 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1392 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1393 XSTR (XEXP (val
, 0), 1) = "yes";
1394 XSTR (XEXP (val
, 1), 0) = "yes";
1395 XSTR (XEXP (val
, 2), 0) = "no";
1396 set
= rtx_alloc (SET
);
1397 SET_DEST (set
) = rtx_alloc (ATTR
);
1398 XSTR (SET_DEST (set
), 0) = "enabled";
1399 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1400 RTVEC_ELT (new_vec
, i
) = set
;
1401 XVEC (insn
, 4) = new_vec
;
1404 /* As number of constraints is changed after define_subst, we need to
1405 process attributes as well - we need to duplicate them the same way
1406 that we duplicated constraints in original pattern
1407 ELEM is a queue element, containing our rtl-template,
1408 N_DUP - multiplication factor. */
1410 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1412 rtvec vec
= XVEC (elem
->data
, 4);
1416 if (n_dup
< 2 || ! vec
)
1419 num_elem
= GET_NUM_ELEM (vec
);
1420 for (i
= num_elem
- 1; i
>= 0; --i
)
1422 rtx sub
= RTVEC_ELT (vec
, i
);
1423 switch (GET_CODE (sub
))
1426 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1427 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1430 case SET_ATTR_ALTERNATIVE
:
1432 error_at (elem
->loc
,
1433 "%s: `define_subst' does not support attributes "
1434 "assigned by `set' and `set_attr_alternative'",
1435 XSTR (elem
->data
, 0));
1444 /* Adjust all of the operand numbers in SRC to match the shift they'll
1445 get from an operand displacement of DISP. Return a pointer after the
1449 shift_output_template (char *dest
, const char *src
, int disp
)
1458 if (ISDIGIT ((unsigned char) c
))
1460 else if (ISALPHA (c
))
1473 alter_output_for_insn (struct queue_elem
*ce_elem
,
1474 struct queue_elem
*insn_elem
,
1475 int alt
, int max_op
)
1477 const char *ce_out
, *insn_out
;
1479 size_t len
, ce_len
, insn_len
;
1481 /* ??? Could coordinate with genoutput to not duplicate code here. */
1483 ce_out
= XSTR (ce_elem
->data
, 2);
1484 insn_out
= XTMPL (insn_elem
->data
, 3);
1485 if (!ce_out
|| *ce_out
== '\0')
1488 ce_len
= strlen (ce_out
);
1489 insn_len
= strlen (insn_out
);
1491 if (*insn_out
== '*')
1492 /* You must take care of the predicate yourself. */
1495 if (*insn_out
== '@')
1497 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1498 p
= result
= XNEWVEC (char, len
);
1504 while (ISSPACE ((unsigned char) *insn_out
));
1506 if (*insn_out
!= '#')
1508 p
= shift_output_template (p
, ce_out
, max_op
);
1514 while (*insn_out
&& *insn_out
!= '\n');
1521 len
= ce_len
+ 1 + insn_len
+ 1;
1522 result
= XNEWVEC (char, len
);
1524 p
= shift_output_template (result
, ce_out
, max_op
);
1526 memcpy (p
, insn_out
, insn_len
+ 1);
1532 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1533 string, duplicated N_DUP times. */
1536 duplicate_alternatives (const char * str
, int n_dup
)
1538 int i
, len
, new_len
;
1545 while (ISSPACE (*str
))
1553 new_len
= (len
+ 1) * n_dup
;
1555 sp
= result
= XNEWVEC (char, new_len
);
1557 /* Global modifier characters mustn't be duplicated: skip if found. */
1558 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1564 /* Copy original constraints N_DUP times. */
1565 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1567 memcpy (sp
, cp
, len
);
1568 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1574 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1575 each alternative from the original string is duplicated N_DUP times. */
1577 duplicate_each_alternative (const char * str
, int n_dup
)
1579 int i
, len
, new_len
;
1580 char *result
, *sp
, *ep
, *cp
;
1585 while (ISSPACE (*str
))
1593 new_len
= (strlen (cp
) + 1) * n_dup
;
1595 sp
= result
= XNEWVEC (char, new_len
);
1597 /* Global modifier characters mustn't be duplicated: skip if found. */
1598 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1603 if ((ep
= strchr (cp
, ',')) != NULL
)
1607 /* Copy a constraint N_DUP times. */
1608 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1610 memcpy (sp
, cp
, len
);
1611 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1621 /* Alter the output of INSN whose pattern was modified by
1622 DEFINE_SUBST. We must replicate output strings according
1623 to the new number of alternatives ALT in substituted pattern.
1624 If ALT equals 1, output has one alternative or defined by C
1625 code, then output is returned without any changes. */
1628 alter_output_for_subst_insn (rtx insn
, int alt
)
1630 const char *insn_out
, *sp
;
1631 char *old_out
, *new_out
, *cp
;
1634 insn_out
= XTMPL (insn
, 3);
1636 if (alt
< 2 || *insn_out
== '*' || *insn_out
!= '@')
1639 old_out
= XNEWVEC (char, strlen (insn_out
)),
1642 while (ISSPACE (*sp
) || *sp
== '@')
1646 old_out
[i
++] = *sp
++;
1648 new_len
= alt
* (i
+ 1) + 1;
1650 new_out
= XNEWVEC (char, new_len
);
1653 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= i
+ 1)
1655 memcpy (cp
, old_out
, i
);
1656 *(cp
+i
) = (j
== alt
- 1) ? '\0' : '\n';
1662 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1665 process_one_cond_exec (struct queue_elem
*ce_elem
)
1667 struct queue_elem
*insn_elem
;
1668 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1670 int alternatives
, max_operand
;
1671 rtx pred
, insn
, pattern
, split
;
1675 if (! is_predicable (insn_elem
))
1680 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1683 if (XVECLEN (ce_elem
->data
, 0) != 1)
1685 error_at (ce_elem
->loc
, "too many patterns in predicate");
1689 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1690 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1695 /* Construct a new pattern for the new insn. */
1696 insn
= copy_rtx (insn_elem
->data
);
1697 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1698 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1699 XSTR (insn
, 0) = new_name
;
1700 pattern
= rtx_alloc (COND_EXEC
);
1701 XEXP (pattern
, 0) = pred
;
1702 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
1703 XVEC (insn
, 1) = rtvec_alloc (1);
1704 XVECEXP (insn
, 1, 0) = pattern
;
1706 if (XVEC (ce_elem
->data
, 3) != NULL
)
1708 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1709 + XVECLEN (ce_elem
->data
, 3));
1712 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1713 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1715 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1716 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1718 XVEC (insn
, 4) = attributes
;
1721 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1722 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1723 alternatives
, max_operand
);
1724 alter_attrs_for_insn (insn
);
1726 /* Put the new pattern on the `other' list so that it
1727 (a) is not reprocessed by other define_cond_exec patterns
1728 (b) appears after all normal define_insn patterns.
1730 ??? B is debatable. If one has normal insns that match
1731 cond_exec patterns, they will be preferred over these
1732 generated patterns. Whether this matters in practice, or if
1733 it's a good thing, or whether we should thread these new
1734 patterns into the define_insn chain just after their generator
1735 is something we'll have to experiment with. */
1737 queue_pattern (insn
, &other_tail
, insn_elem
->loc
);
1739 if (!insn_elem
->split
)
1742 /* If the original insn came from a define_insn_and_split,
1743 generate a new split to handle the predicated insn. */
1744 split
= copy_rtx (insn_elem
->split
->data
);
1745 /* Predicate the pattern matched by the split. */
1746 pattern
= rtx_alloc (COND_EXEC
);
1747 XEXP (pattern
, 0) = pred
;
1748 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
1749 XVEC (split
, 0) = rtvec_alloc (1);
1750 XVECEXP (split
, 0, 0) = pattern
;
1752 /* Predicate all of the insns generated by the split. */
1753 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1755 pattern
= rtx_alloc (COND_EXEC
);
1756 XEXP (pattern
, 0) = pred
;
1757 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1758 XVECEXP (split
, 2, i
) = pattern
;
1760 /* Add the new split to the queue. */
1761 queue_pattern (split
, &other_tail
, insn_elem
->split
->loc
);
1765 /* Try to apply define_substs to the given ELEM.
1766 Only define_substs, specified via attributes would be applied.
1767 If attribute, requiring define_subst, is set, but no define_subst
1768 was applied, ELEM would be deleted. */
1771 process_substs_on_one_elem (struct queue_elem
*elem
,
1772 struct queue_elem
*queue
)
1774 struct queue_elem
*subst_elem
;
1775 int i
, j
, patterns_match
;
1777 for (subst_elem
= define_subst_queue
;
1778 subst_elem
; subst_elem
= subst_elem
->next
)
1780 int alternatives
, alternatives_subst
;
1782 rtvec subst_pattern_vec
;
1784 if (!has_subst_attribute (elem
, subst_elem
))
1787 /* Compare original rtl-pattern from define_insn with input
1788 pattern from define_subst.
1789 Also, check if numbers of alternatives are the same in all
1791 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1795 alternatives_subst
= -1;
1796 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1798 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1799 XVECEXP (subst_elem
->data
, 1, j
),
1806 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1807 &alternatives
, subst_elem
->loc
))
1814 /* Check if numbers of alternatives are the same in all
1815 match_operands in output template of define_subst. */
1816 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1818 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1819 &alternatives_subst
,
1827 if (!patterns_match
)
1830 /* Clear array in which we save occupied indexes of operands. */
1831 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1833 /* Create a pattern, based on the output one from define_subst. */
1834 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1835 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1837 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1839 /* Duplicate constraints in substitute-pattern. */
1840 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1841 duplicate_each_alternative
);
1843 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1845 /* Substitute match_dup and match_op_dup in the new pattern and
1846 duplicate constraints. */
1847 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1848 alternatives_subst
);
1850 replace_duplicating_operands_in_pattern (subst_pattern
);
1852 /* We don't need any constraints in DEFINE_EXPAND. */
1853 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1854 remove_constraints (subst_pattern
);
1856 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1858 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1860 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1861 match_operand_entries_in_pattern
[i
] = NULL
;
1863 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1865 XTMPL (elem
->data
, 3) =
1866 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1867 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1870 /* Recalculate condition, joining conditions from original and
1871 DEFINE_SUBST input patterns. */
1872 XSTR (elem
->data
, 2) = join_c_conditions (XSTR (subst_elem
->data
, 2),
1873 XSTR (elem
->data
, 2));
1874 /* Mark that subst was applied by changing attribute from "yes"
1876 change_subst_attribute (elem
, subst_elem
, subst_false
);
1879 /* If ELEM contains a subst attribute with value "yes", then we
1880 expected that a subst would be applied, but it wasn't - so,
1881 we need to remove that elementto avoid duplicating. */
1882 for (subst_elem
= define_subst_queue
;
1883 subst_elem
; subst_elem
= subst_elem
->next
)
1885 if (has_subst_attribute (elem
, subst_elem
))
1887 remove_from_queue (elem
, &queue
);
1893 /* This is a subroutine of mark_operands_used_in_match_dup.
1894 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1896 mark_operands_from_match_dup (rtx pattern
)
1899 int i
, j
, len
, opno
;
1901 if (GET_CODE (pattern
) == MATCH_OPERAND
1902 || GET_CODE (pattern
) == MATCH_OPERATOR
1903 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1905 opno
= XINT (pattern
, 0);
1906 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1907 used_operands_numbers
[opno
] = 1;
1909 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1910 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1911 for (i
= 0; i
< len
; i
++)
1916 mark_operands_from_match_dup (XEXP (pattern
, i
));
1919 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1920 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1926 /* This is a subroutine of adjust_operands_numbers.
1927 It goes through all expressions in PATTERN and when MATCH_DUP is
1928 met, all MATCH_OPERANDs inside it is marked as occupied. The
1929 process of marking is done by routin mark_operands_from_match_dup. */
1931 mark_operands_used_in_match_dup (rtx pattern
)
1934 int i
, j
, len
, opno
;
1936 if (GET_CODE (pattern
) == MATCH_DUP
)
1938 opno
= XINT (pattern
, 0);
1939 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1940 mark_operands_from_match_dup (operand_data
[opno
]);
1943 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1944 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1945 for (i
= 0; i
< len
; i
++)
1950 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1953 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1954 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1960 /* This is subroutine of renumerate_operands_in_pattern.
1961 It finds first not-occupied operand-index. */
1963 find_first_unused_number_of_operand ()
1966 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1967 if (!used_operands_numbers
[i
])
1969 return MAX_OPERANDS
;
1972 /* This is subroutine of adjust_operands_numbers.
1973 It visits all expressions in PATTERN and assigns not-occupied
1974 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1977 renumerate_operands_in_pattern (rtx pattern
)
1981 int i
, j
, len
, new_opno
;
1982 code
= GET_CODE (pattern
);
1984 if (code
== MATCH_OPERAND
1985 || code
== MATCH_OPERATOR
)
1987 new_opno
= find_first_unused_number_of_operand ();
1988 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
1989 XINT (pattern
, 0) = new_opno
;
1990 used_operands_numbers
[new_opno
] = 1;
1993 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1994 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1995 for (i
= 0; i
< len
; i
++)
2000 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2003 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2004 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2010 /* If output pattern of define_subst contains MATCH_DUP, then this
2011 expression would be replaced with the pattern, matched with
2012 MATCH_OPERAND from input pattern. This pattern could contain any
2013 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2014 that a MATCH_OPERAND from output_pattern (if any) would have the
2015 same number, as MATCH_OPERAND from copied pattern. To avoid such
2016 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2017 laying in the output pattern outside of MATCH_DUPs. */
2019 adjust_operands_numbers (rtx pattern
)
2021 mark_operands_used_in_match_dup (pattern
);
2023 renumerate_operands_in_pattern (pattern
);
2028 /* Generate RTL expression
2032 generate_match_dup (int opno
)
2034 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2035 PUT_CODE (return_rtx
, MATCH_DUP
);
2036 XINT (return_rtx
, 0) = opno
;
2040 /* This routine checks all match_operands in PATTERN and if some of
2041 have the same index, it replaces all of them except the first one to
2043 Usually, match_operands with the same indexes are forbidden, but
2044 after define_subst copy an RTL-expression from original template,
2045 indexes of existed and just-copied match_operands could coincide.
2046 To fix it, we replace one of them with match_dup. */
2048 replace_duplicating_operands_in_pattern (rtx pattern
)
2051 int i
, j
, len
, opno
;
2054 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2056 opno
= XINT (pattern
, 0);
2057 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2058 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2060 match_operand_entries_in_pattern
[opno
] = pattern
;
2065 /* Compare predicates before replacing with match_dup. */
2066 if (strcmp (XSTR (pattern
, 1),
2067 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2069 error ("duplicated match_operands with different predicates were"
2073 return generate_match_dup (opno
);
2076 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2077 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2078 for (i
= 0; i
< len
; i
++)
2083 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2085 XEXP (pattern
, i
) = mdup
;
2088 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2091 replace_duplicating_operands_in_pattern (XVECEXP
2094 XVECEXP (pattern
, i
, j
) = mdup
;
2102 /* The routine modifies given input PATTERN of define_subst, replacing
2103 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2104 pattern, whose operands are stored in OPERAND_DATA array.
2105 It also duplicates constraints in operands - constraints from
2106 define_insn operands are duplicated N_SUBST_ALT times, constraints
2107 from define_subst operands are duplicated N_ALT times.
2108 After the duplication, returned output rtl-pattern contains every
2109 combination of input constraints Vs constraints from define_subst
2112 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2116 int i
, j
, len
, opno
;
2118 code
= GET_CODE (pattern
);
2123 opno
= XINT (pattern
, 0);
2125 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2127 if (operand_data
[opno
])
2129 pattern
= copy_rtx (operand_data
[opno
]);
2131 /* Duplicate constraints. */
2132 pattern
= alter_constraints (pattern
, n_subst_alt
,
2133 duplicate_alternatives
);
2141 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2142 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2143 for (i
= 0; i
< len
; i
++)
2148 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2149 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2150 n_alt
, n_subst_alt
);
2153 if (XVEC (pattern
, i
) == NULL
)
2156 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2157 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2158 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2159 n_alt
, n_subst_alt
);
2162 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2172 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2173 patterns appropriately. */
2176 process_define_cond_exec (void)
2178 struct queue_elem
*elem
;
2180 identify_predicable_attribute ();
2184 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2185 process_one_cond_exec (elem
);
2188 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2189 DEFINE_EXPAND patterns appropriately. */
2192 process_define_subst (void)
2194 struct queue_elem
*elem
, *elem_attr
;
2196 /* Check if each define_subst has corresponding define_subst_attr. */
2197 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2199 for (elem_attr
= define_subst_attr_queue
;
2201 elem_attr
= elem_attr
->next
)
2202 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2205 error_at (elem
->loc
,
2206 "%s: `define_subst' must have at least one "
2207 "corresponding `define_subst_attr'",
2208 XSTR (elem
->data
, 0));
2215 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2216 process_substs_on_one_elem (elem
, define_insn_queue
);
2217 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2219 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2221 process_substs_on_one_elem (elem
, other_queue
);
2225 /* A read_md_files callback for reading an rtx. */
2228 rtx_handle_directive (file_location loc
, const char *rtx_name
)
2230 auto_vec
<rtx
, 32> subrtxs
;
2231 if (!read_rtx (rtx_name
, &subrtxs
))
2236 FOR_EACH_VEC_ELT (subrtxs
, i
, x
)
2237 process_rtx (x
, loc
);
2240 /* Comparison function for the mnemonic hash table. */
2243 htab_eq_string (const void *s1
, const void *s2
)
2245 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2248 /* Add mnemonic STR with length LEN to the mnemonic hash table
2249 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2250 and a permanent heap copy of STR is created. */
2253 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, int len
)
2257 char *str_zero
= (char*)alloca (len
+ 1);
2259 memcpy (str_zero
, str
, len
);
2260 str_zero
[len
] = '\0';
2262 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2267 /* Not found; create a permanent copy and add it to the hash table. */
2268 new_str
= XNEWVAR (char, len
+ 1);
2269 memcpy (new_str
, str_zero
, len
+ 1);
2273 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2274 table in MNEMONIC_HTAB.
2276 The mnemonics cannot be found if they are emitted using C code.
2278 If a mnemonic string contains ';' or a newline the string assumed
2279 to consist of more than a single instruction. The attribute value
2280 will then be set to the user defined default value. */
2283 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2285 const char *template_code
, *cp
;
2292 template_code
= XTMPL (insn
, 3);
2294 /* Skip patterns which use C code to emit the template. */
2295 if (template_code
[0] == '*')
2298 if (template_code
[0] == '@')
2299 cp
= &template_code
[1];
2301 cp
= &template_code
[0];
2305 const char *ep
, *sp
;
2308 while (ISSPACE (*cp
))
2311 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2316 obstack_1grow (&string_obstack
, ',');
2318 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2319 || (*cp
>= 'a' && *cp
<= 'z')))
2322 obstack_1grow (&string_obstack
, *cp
);
2329 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2331 /* Don't set a value if there are more than one
2332 instruction in the string. */
2333 obstack_next_free (&string_obstack
) =
2334 obstack_next_free (&string_obstack
) - size
;
2343 obstack_1grow (&string_obstack
, '*');
2345 add_mnemonic_string (mnemonic_htab
,
2346 obstack_next_free (&string_obstack
) - size
,
2351 /* An insn definition might emit an empty string. */
2352 if (obstack_object_size (&string_obstack
) == 0)
2355 obstack_1grow (&string_obstack
, '\0');
2357 set_attr
= rtx_alloc (SET_ATTR
);
2358 XSTR (set_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2359 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2360 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2361 XSTR (set_attr
, 0) = attr_name
;
2363 if (!XVEC (insn
, 4))
2366 vec_len
= XVECLEN (insn
, 4);
2368 new_vec
= rtvec_alloc (vec_len
+ 1);
2369 for (i
= 0; i
< vec_len
; i
++)
2370 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2371 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2372 XVEC (insn
, 4) = new_vec
;
2375 /* This function is called for the elements in the mnemonic hashtable
2376 and generates a comma separated list of the mnemonics. */
2379 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
2381 obstack_grow (&string_obstack
, (char*)*slot
, strlen ((char*)*slot
));
2382 obstack_1grow (&string_obstack
, ',');
2386 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2387 insn definition in case the back end requests it by defining the
2388 mnemonic attribute. The values for the attribute will be extracted
2389 from the output patterns of the insn definitions as far as
2393 gen_mnemonic_attr (void)
2395 struct queue_elem
*elem
;
2396 rtx mnemonic_attr
= NULL
;
2397 htab_t mnemonic_htab
;
2398 const char *str
, *p
;
2404 /* Look for the DEFINE_ATTR for `mnemonic'. */
2405 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2406 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2407 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2409 mnemonic_attr
= elem
->data
;
2413 /* A (define_attr "mnemonic" "...") indicates that the back-end
2414 wants a mnemonic attribute to be generated. */
2418 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2419 htab_eq_string
, 0, xcalloc
, free
);
2421 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2423 rtx insn
= elem
->data
;
2426 /* Check if the insn definition already has
2427 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2429 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2431 rtx set_attr
= XVECEXP (insn
, 4, i
);
2433 switch (GET_CODE (set_attr
))
2436 case SET_ATTR_ALTERNATIVE
:
2437 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2441 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2442 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2443 MNEMONIC_ATTR_NAME
) == 0)
2452 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2455 /* Add the user defined values to the hash table. */
2456 str
= XSTR (mnemonic_attr
, 1);
2457 while ((p
= scan_comma_elt (&str
)) != NULL
)
2458 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2460 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2462 /* Replace the last ',' with the zero end character. */
2463 *((char *)obstack_next_free (&string_obstack
) - 1) = '\0';
2464 XSTR (mnemonic_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2467 /* Check if there are DEFINE_ATTRs with the same name. */
2469 check_define_attr_duplicates ()
2471 struct queue_elem
*elem
;
2476 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2478 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2480 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2482 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2487 error_at (elem
->loc
, "redefinition of attribute '%s'", attr_name
);
2488 htab_delete (attr_htab
);
2495 htab_delete (attr_htab
);
2498 /* The entry point for initializing the reader. */
2501 init_rtx_reader_args_cb (int argc
, char **argv
,
2502 bool (*parse_opt
) (const char *))
2504 /* Prepare to read input. */
2505 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
2506 init_predicate_table ();
2507 obstack_init (rtl_obstack
);
2509 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2510 insn_sequence_num
= 1;
2512 /* These sequences are not used as indices, so can start at 1 also. */
2513 split_sequence_num
= 1;
2514 peephole2_sequence_num
= 1;
2516 read_md_files (argc
, argv
, parse_opt
, rtx_handle_directive
);
2518 if (define_attr_queue
!= NULL
)
2519 check_define_attr_duplicates ();
2521 /* Process define_cond_exec patterns. */
2522 if (define_cond_exec_queue
!= NULL
)
2523 process_define_cond_exec ();
2525 /* Process define_subst patterns. */
2526 if (define_subst_queue
!= NULL
)
2527 process_define_subst ();
2529 if (define_attr_queue
!= NULL
)
2530 gen_mnemonic_attr ();
2535 /* Programs that don't have their own options can use this entry point
2538 init_rtx_reader_args (int argc
, char **argv
)
2540 return init_rtx_reader_args_cb (argc
, argv
, 0);
2543 /* Try to read a single rtx from the file. Return true on success,
2544 describing it in *INFO. */
2547 read_md_rtx (md_rtx_info
*info
)
2549 int truth
, *counter
;
2552 /* Discard insn patterns which we know can never match (because
2553 their C test is provably always false). If insn_elision is
2554 false, our caller needs to see all the patterns. Note that the
2555 elided patterns are never counted by the sequence numbering; it
2556 is the caller's responsibility, when insn_elision is false, not
2557 to use elided pattern numbers for anything. */
2560 struct queue_elem
**queue
, *elem
;
2562 /* Read all patterns from a given queue before moving on to the next. */
2563 if (define_attr_queue
!= NULL
)
2564 queue
= &define_attr_queue
;
2565 else if (define_pred_queue
!= NULL
)
2566 queue
= &define_pred_queue
;
2567 else if (define_insn_queue
!= NULL
)
2568 queue
= &define_insn_queue
;
2569 else if (other_queue
!= NULL
)
2570 queue
= &other_queue
;
2575 *queue
= elem
->next
;
2578 info
->loc
= elem
->loc
;
2581 truth
= maybe_eval_c_test (get_c_test (def
));
2583 while (truth
== 0 && insn_elision
);
2585 /* Perform code-specific processing and pick the appropriate sequence
2587 switch (GET_CODE (def
))
2591 /* insn_sequence_num is used here so the name table will match caller's
2592 idea of insn numbering, whether or not elision is active. */
2593 record_insn_name (insn_sequence_num
, XSTR (def
, 0));
2596 case DEFINE_PEEPHOLE
:
2597 counter
= &insn_sequence_num
;
2601 counter
= &split_sequence_num
;
2604 case DEFINE_PEEPHOLE2
:
2605 counter
= &peephole2_sequence_num
;
2615 info
->index
= *counter
;
2625 /* Return the number of possible INSN_CODEs. Only meaningful once the
2626 whole file has been processed. */
2628 get_num_insn_codes ()
2630 return insn_sequence_num
;
2633 /* Return the C test that says whether definition rtx DEF can be used,
2634 or "" if it can be used unconditionally. */
2639 switch (GET_CODE (x
))
2647 case DEFINE_PEEPHOLE
:
2648 case DEFINE_PEEPHOLE2
:
2656 /* Helper functions for insn elision. */
2658 /* Compute a hash function of a c_test structure, which is keyed
2659 by its ->expr field. */
2661 hash_c_test (const void *x
)
2663 const struct c_test
*a
= (const struct c_test
*) x
;
2664 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2672 while ((c
= *s
++) != '\0')
2674 hash
+= c
+ (c
<< 17);
2679 hash
+= len
+ (len
<< 17);
2685 /* Compare two c_test expression structures. */
2687 cmp_c_test (const void *x
, const void *y
)
2689 const struct c_test
*a
= (const struct c_test
*) x
;
2690 const struct c_test
*b
= (const struct c_test
*) y
;
2692 return !strcmp (a
->expr
, b
->expr
);
2695 /* Given a string representing a C test expression, look it up in the
2696 condition_table and report whether or not its value is known
2697 at compile time. Returns a tristate: 1 for known true, 0 for
2698 known false, -1 for unknown. */
2700 maybe_eval_c_test (const char *expr
)
2702 const struct c_test
*test
;
2703 struct c_test dummy
;
2709 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2715 /* Record the C test expression EXPR in the condition_table, with
2716 value VAL. Duplicates clobber previous entries. */
2719 add_c_test (const char *expr
, int value
)
2721 struct c_test
*test
;
2726 test
= XNEW (struct c_test
);
2728 test
->value
= value
;
2730 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2733 /* For every C test, call CALLBACK with two arguments: a pointer to
2734 the condition structure and INFO. Stops when CALLBACK returns zero. */
2736 traverse_c_tests (htab_trav callback
, void *info
)
2738 if (condition_table
)
2739 htab_traverse (condition_table
, callback
, info
);
2742 /* Helper functions for define_predicate and define_special_predicate
2743 processing. Shared between genrecog.c and genpreds.c. */
2745 static htab_t predicate_table
;
2746 struct pred_data
*first_predicate
;
2747 static struct pred_data
**last_predicate
= &first_predicate
;
2750 hash_struct_pred_data (const void *ptr
)
2752 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2756 eq_struct_pred_data (const void *a
, const void *b
)
2758 return !strcmp (((const struct pred_data
*)a
)->name
,
2759 ((const struct pred_data
*)b
)->name
);
2763 lookup_predicate (const char *name
)
2765 struct pred_data key
;
2767 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2770 /* Record that predicate PRED can accept CODE. */
2773 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2775 if (!pred
->codes
[code
])
2778 pred
->codes
[code
] = true;
2780 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2781 pred
->allows_non_const
= true;
2788 && code
!= STRICT_LOW_PART
2790 pred
->allows_non_lvalue
= true;
2792 if (pred
->num_codes
== 1)
2793 pred
->singleton
= code
;
2794 else if (pred
->num_codes
== 2)
2795 pred
->singleton
= UNKNOWN
;
2800 add_predicate (struct pred_data
*pred
)
2802 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2805 error ("duplicate predicate definition for '%s'", pred
->name
);
2809 *last_predicate
= pred
;
2810 last_predicate
= &pred
->next
;
2813 /* This array gives the initial content of the predicate table. It
2814 has entries for all predicates defined in recog.c. */
2816 struct std_pred_table
2820 bool allows_const_p
;
2821 RTX_CODE codes
[NUM_RTX_CODE
];
2824 static const struct std_pred_table std_preds
[] = {
2825 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2826 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
2827 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2828 {"register_operand", false, false, {SUBREG
, REG
}},
2829 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2830 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2831 {"immediate_operand", false, true, {UNKNOWN
}},
2832 {"const_int_operand", false, false, {CONST_INT
}},
2833 #if TARGET_SUPPORTS_WIDE_INT
2834 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2835 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2837 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2839 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2840 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2841 {"push_operand", false, false, {MEM
}},
2842 {"pop_operand", false, false, {MEM
}},
2843 {"memory_operand", false, false, {SUBREG
, MEM
}},
2844 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2845 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2847 LEU
, LTU
, GEU
, GTU
}},
2848 {"comparison_operator", false, false, {EQ
, NE
,
2855 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2857 /* Initialize the table of predicate definitions, starting with
2858 the information we have on generic predicates. */
2861 init_predicate_table (void)
2864 struct pred_data
*pred
;
2866 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2867 eq_struct_pred_data
, 0,
2870 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2872 pred
= XCNEW (struct pred_data
);
2873 pred
->name
= std_preds
[i
].name
;
2874 pred
->special
= std_preds
[i
].special
;
2876 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2877 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2879 if (std_preds
[i
].allows_const_p
)
2880 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2881 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2882 add_predicate_code (pred
, (enum rtx_code
) j
);
2884 add_predicate (pred
);
2888 /* These functions allow linkage with print-rtl.c. Also, some generators
2889 like to annotate their output with insn names. */
2891 /* Holds an array of names indexed by insn_code_number. */
2892 static char **insn_name_ptr
= 0;
2893 static int insn_name_ptr_size
= 0;
2896 get_insn_name (int code
)
2898 if (code
< insn_name_ptr_size
)
2899 return insn_name_ptr
[code
];
2905 record_insn_name (int code
, const char *name
)
2907 static const char *last_real_name
= "insn";
2908 static int last_real_code
= 0;
2911 if (insn_name_ptr_size
<= code
)
2914 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2915 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2916 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2917 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2918 insn_name_ptr_size
= new_size
;
2921 if (!name
|| name
[0] == '\0')
2923 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2924 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2928 last_real_name
= new_name
= xstrdup (name
);
2929 last_real_code
= code
;
2932 insn_name_ptr
[code
] = new_name
;
2935 /* Make STATS describe the operands that appear in rtx X. */
2938 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2948 code
= GET_CODE (x
);
2952 case MATCH_OPERATOR
:
2953 case MATCH_PARALLEL
:
2954 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
2961 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
2965 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
2972 fmt
= GET_RTX_FORMAT (code
);
2973 len
= GET_RTX_LENGTH (code
);
2974 for (i
= 0; i
< len
; i
++)
2976 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
2977 get_pattern_stats_1 (stats
, XEXP (x
, i
));
2978 else if (fmt
[i
] == 'E')
2981 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2982 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
2987 /* Make STATS describe the operands that appear in instruction pattern
2991 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
2995 stats
->max_opno
= -1;
2996 stats
->max_dup_opno
= -1;
2997 stats
->max_scratch_opno
= -1;
2998 stats
->num_dups
= 0;
3000 len
= GET_NUM_ELEM (pattern
);
3001 for (i
= 0; i
< len
; i
++)
3002 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
3004 stats
->num_generator_args
= stats
->max_opno
+ 1;
3005 stats
->num_insn_operands
= MAX (stats
->max_opno
,
3006 stats
->max_scratch_opno
) + 1;
3007 stats
->num_operand_vars
= MAX (stats
->max_opno
,
3008 MAX (stats
->max_dup_opno
,
3009 stats
->max_scratch_opno
)) + 1;
3012 /* Return the emit_* function that should be used for pattern X, or NULL
3013 if we can't pick a particular type at compile time and should instead
3014 fall back to "emit". */
3017 get_emit_function (rtx x
)
3019 switch (classify_insn (x
))
3025 return "emit_call_insn";
3028 return "emit_jump_insn";
3038 /* Return true if we must emit a barrier after pattern X. */
3041 needs_barrier_p (rtx x
)
3043 return (GET_CODE (x
) == SET
3044 && GET_CODE (SET_DEST (x
)) == PC
3045 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);