1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2014 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"
29 #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 patterns that generate code: define_insn, define_expand,
47 define_split, define_peephole, and define_peephole2. See read_md_rtx().
48 Any define_insn_and_splits are already in separate queues so that the
49 insn and the splitter get a unique number also. */
50 static int sequence_num
;
52 static int predicable_default
;
53 static const char *predicable_true
;
54 static const char *predicable_false
;
56 static const char *subst_true
= "yes";
57 static const char *subst_false
= "no";
59 static htab_t condition_table
;
61 /* We initially queue all patterns, process the define_insn,
62 define_cond_exec and define_subst patterns, then return
63 them one at a time. */
70 struct queue_elem
*next
;
71 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
72 points to the generated DEFINE_SPLIT. */
73 struct queue_elem
*split
;
76 #define MNEMONIC_ATTR_NAME "mnemonic"
77 #define MNEMONIC_HTAB_SIZE 1024
79 static struct queue_elem
*define_attr_queue
;
80 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
81 static struct queue_elem
*define_pred_queue
;
82 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
83 static struct queue_elem
*define_insn_queue
;
84 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
85 static struct queue_elem
*define_cond_exec_queue
;
86 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
87 static struct queue_elem
*define_subst_queue
;
88 static struct queue_elem
**define_subst_tail
= &define_subst_queue
;
89 static struct queue_elem
*other_queue
;
90 static struct queue_elem
**other_tail
= &other_queue
;
91 static struct queue_elem
*define_subst_attr_queue
;
92 static struct queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
94 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
97 static void remove_constraints (rtx
);
98 static void process_rtx (rtx
, int);
100 static int is_predicable (struct queue_elem
*);
101 static void identify_predicable_attribute (void);
102 static int n_alternatives (const char *);
103 static void collect_insn_data (rtx
, int *, int *);
104 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
105 static const char *alter_test_for_insn (struct queue_elem
*,
106 struct queue_elem
*);
107 static char *shift_output_template (char *, const char *, int);
108 static const char *alter_output_for_insn (struct queue_elem
*,
111 static void process_one_cond_exec (struct queue_elem
*);
112 static void process_define_cond_exec (void);
113 static void init_predicate_table (void);
114 static void record_insn_name (int, const char *);
116 static bool has_subst_attribute (struct queue_elem
*, struct queue_elem
*);
117 static bool subst_pattern_match (rtx
, rtx
, int);
118 static int get_alternatives_number (rtx
, int *, int);
119 static const char * alter_output_for_subst_insn (rtx
, int);
120 static void alter_attrs_for_subst_insn (struct queue_elem
*, int);
121 static void process_substs_on_one_elem (struct queue_elem
*,
122 struct queue_elem
*);
123 static rtx
subst_dup (rtx
, int, int);
124 static void process_define_subst (void);
126 static const char * duplicate_alternatives (const char *, int);
127 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
129 typedef const char * (*constraints_handler_t
) (const char *, int);
130 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
131 static rtx
adjust_operands_numbers (rtx
);
132 static rtx
replace_duplicating_operands_in_pattern (rtx
);
134 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
135 the gensupport programs. */
138 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
141 rtx rt
= rtx_alloc (CONST_INT
);
147 /* Predicate handling.
149 We construct from the machine description a table mapping each
150 predicate to a list of the rtl codes it can possibly match. The
151 function 'maybe_both_true' uses it to deduce that there are no
152 expressions that can be matches by certain pairs of tree nodes.
153 Also, if a predicate can match only one code, we can hardwire that
154 code into the node testing the predicate.
156 Some predicates are flagged as special. validate_pattern will not
157 warn about modeless match_operand expressions if they have a
158 special predicate. Predicates that allow only constants are also
159 treated as special, for this purpose.
161 validate_pattern will warn about predicates that allow non-lvalues
162 when they appear in destination operands.
164 Calculating the set of rtx codes that can possibly be accepted by a
165 predicate expression EXP requires a three-state logic: any given
166 subexpression may definitively accept a code C (Y), definitively
167 reject a code C (N), or may have an indeterminate effect (I). N
168 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
179 We represent Y with 1, N with 0, I with 2. If any code is left in
180 an I state by the complete expression, we must assume that that
181 code can be accepted. */
187 #define TRISTATE_AND(a,b) \
188 ((a) == I ? ((b) == N ? N : I) : \
189 (b) == I ? ((a) == N ? N : I) : \
192 #define TRISTATE_OR(a,b) \
193 ((a) == I ? ((b) == Y ? Y : I) : \
194 (b) == I ? ((a) == Y ? Y : I) : \
197 #define TRISTATE_NOT(a) \
198 ((a) == I ? I : !(a))
200 /* 0 means no warning about that code yet, 1 means warned. */
201 static char did_you_mean_codes
[NUM_RTX_CODE
];
203 /* Recursively calculate the set of rtx codes accepted by the
204 predicate expression EXP, writing the result to CODES. LINENO is
205 the line number on which the directive containing EXP appeared. */
208 compute_predicate_codes (rtx exp
, int lineno
, char codes
[NUM_RTX_CODE
])
210 char op0_codes
[NUM_RTX_CODE
];
211 char op1_codes
[NUM_RTX_CODE
];
212 char op2_codes
[NUM_RTX_CODE
];
215 switch (GET_CODE (exp
))
218 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
219 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
220 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
221 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
225 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
226 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
227 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
228 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
231 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
232 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
233 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
237 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
238 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
239 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
240 compute_predicate_codes (XEXP (exp
, 2), lineno
, op2_codes
);
241 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
242 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
243 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
248 /* MATCH_CODE allows a specified list of codes. However, if it
249 does not apply to the top level of the expression, it does not
250 constrain the set of codes for the top level. */
251 if (XSTR (exp
, 1)[0] != '\0')
253 memset (codes
, Y
, NUM_RTX_CODE
);
257 memset (codes
, N
, NUM_RTX_CODE
);
259 const char *next_code
= XSTR (exp
, 0);
262 if (*next_code
== '\0')
264 error_with_line (lineno
, "empty match_code expression");
268 while ((code
= scan_comma_elt (&next_code
)) != 0)
270 size_t n
= next_code
- code
;
273 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
274 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
275 && GET_RTX_NAME (i
)[n
] == '\0')
283 error_with_line (lineno
,
284 "match_code \"%.*s\" matches nothing",
286 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
287 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
288 && GET_RTX_NAME (i
)[n
] == '\0'
289 && !did_you_mean_codes
[i
])
291 did_you_mean_codes
[i
] = 1;
292 message_with_line (lineno
, "(did you mean \"%s\"?)",
301 /* MATCH_OPERAND disallows the set of codes that the named predicate
302 disallows, and is indeterminate for the codes that it does allow. */
304 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
307 error_with_line (lineno
, "reference to unknown predicate '%s'",
311 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
312 codes
[i
] = p
->codes
[i
] ? I
: N
;
318 /* (match_test WHATEVER) is completely indeterminate. */
319 memset (codes
, I
, NUM_RTX_CODE
);
323 error_with_line (lineno
,
324 "'%s' cannot be used in a define_predicate expression",
325 GET_RTX_NAME (GET_CODE (exp
)));
326 memset (codes
, I
, NUM_RTX_CODE
);
335 /* Return true if NAME is a valid predicate name. */
338 valid_predicate_name_p (const char *name
)
342 if (!ISALPHA (name
[0]) && name
[0] != '_')
344 for (p
= name
+ 1; *p
; p
++)
345 if (!ISALNUM (*p
) && *p
!= '_')
350 /* Process define_predicate directive DESC, which appears on line number
351 LINENO. Compute the set of codes that can be matched, and record this
352 as a known predicate. */
355 process_define_predicate (rtx desc
, int lineno
)
357 struct pred_data
*pred
;
358 char codes
[NUM_RTX_CODE
];
361 if (!valid_predicate_name_p (XSTR (desc
, 0)))
363 error_with_line (lineno
,
364 "%s: predicate name must be a valid C function name",
369 pred
= XCNEW (struct pred_data
);
370 pred
->name
= XSTR (desc
, 0);
371 pred
->exp
= XEXP (desc
, 1);
372 pred
->c_block
= XSTR (desc
, 2);
373 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
374 pred
->special
= true;
376 compute_predicate_codes (XEXP (desc
, 1), lineno
, codes
);
378 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
380 add_predicate_code (pred
, (enum rtx_code
) i
);
382 add_predicate (pred
);
388 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
391 static struct queue_elem
*
392 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
393 const char *filename
, int lineno
)
395 struct queue_elem
*e
= XNEW (struct queue_elem
);
397 e
->filename
= filename
;
402 *list_tail
= &e
->next
;
406 /* Remove element ELEM from QUEUE. */
408 remove_from_queue (struct queue_elem
*elem
, struct queue_elem
**queue
)
410 struct queue_elem
*prev
, *e
;
412 for (e
= *queue
; e
; e
= e
->next
)
422 prev
->next
= elem
->next
;
427 /* Build a define_attr for an binary attribute with name NAME and
428 possible values "yes" and "no", and queue it. */
430 add_define_attr (const char *name
)
432 struct queue_elem
*e
= XNEW (struct queue_elem
);
433 rtx t1
= rtx_alloc (DEFINE_ATTR
);
435 XSTR (t1
, 1) = "no,yes";
436 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
437 XSTR (XEXP (t1
, 2), 0) = "yes";
439 e
->filename
= "built-in";
441 e
->next
= define_attr_queue
;
442 define_attr_queue
= e
;
446 /* Recursively remove constraints from an rtx. */
449 remove_constraints (rtx part
)
452 const char *format_ptr
;
457 if (GET_CODE (part
) == MATCH_OPERAND
)
459 else if (GET_CODE (part
) == MATCH_SCRATCH
)
462 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
464 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
465 switch (*format_ptr
++)
469 remove_constraints (XEXP (part
, i
));
472 if (XVEC (part
, i
) != NULL
)
473 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
474 remove_constraints (XVECEXP (part
, i
, j
));
479 /* Process a top level rtx in some way, queuing as appropriate. */
482 process_rtx (rtx desc
, int lineno
)
484 switch (GET_CODE (desc
))
487 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
490 case DEFINE_COND_EXEC
:
491 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
495 queue_pattern (desc
, &define_subst_tail
, read_md_filename
, lineno
);
498 case DEFINE_SUBST_ATTR
:
499 queue_pattern (desc
, &define_subst_attr_tail
, read_md_filename
, lineno
);
503 case DEFINE_ENUM_ATTR
:
504 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
507 case DEFINE_PREDICATE
:
508 case DEFINE_SPECIAL_PREDICATE
:
509 process_define_predicate (desc
, lineno
);
512 case DEFINE_CONSTRAINT
:
513 case DEFINE_REGISTER_CONSTRAINT
:
514 case DEFINE_MEMORY_CONSTRAINT
:
515 case DEFINE_ADDRESS_CONSTRAINT
:
516 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
519 case DEFINE_INSN_AND_SPLIT
:
521 const char *split_cond
;
525 struct queue_elem
*insn_elem
;
526 struct queue_elem
*split_elem
;
528 /* Create a split with values from the insn_and_split. */
529 split
= rtx_alloc (DEFINE_SPLIT
);
531 i
= XVECLEN (desc
, 1);
532 XVEC (split
, 0) = rtvec_alloc (i
);
535 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
536 remove_constraints (XVECEXP (split
, 0, i
));
539 /* If the split condition starts with "&&", append it to the
540 insn condition to create the new split condition. */
541 split_cond
= XSTR (desc
, 4);
542 if (split_cond
[0] == '&' && split_cond
[1] == '&')
544 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
545 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
547 XSTR (split
, 1) = split_cond
;
548 XVEC (split
, 2) = XVEC (desc
, 5);
549 XSTR (split
, 3) = XSTR (desc
, 6);
551 /* Fix up the DEFINE_INSN. */
552 attr
= XVEC (desc
, 7);
553 PUT_CODE (desc
, DEFINE_INSN
);
554 XVEC (desc
, 4) = attr
;
558 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
561 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
562 insn_elem
->split
= split_elem
;
567 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
572 /* Return true if attribute PREDICABLE is true for ELEM, which holds
576 is_predicable (struct queue_elem
*elem
)
578 rtvec vec
= XVEC (elem
->data
, 4);
583 return predicable_default
;
585 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
587 rtx sub
= RTVEC_ELT (vec
, i
);
588 switch (GET_CODE (sub
))
591 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
593 value
= XSTR (sub
, 1);
598 case SET_ATTR_ALTERNATIVE
:
599 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
601 error_with_line (elem
->lineno
,
602 "multiple alternatives for `predicable'");
608 if (GET_CODE (SET_DEST (sub
)) != ATTR
609 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
612 if (GET_CODE (sub
) == CONST_STRING
)
614 value
= XSTR (sub
, 0);
618 /* ??? It would be possible to handle this if we really tried.
619 It's not easy though, and I'm not going to bother until it
620 really proves necessary. */
621 error_with_line (elem
->lineno
,
622 "non-constant value for `predicable'");
630 return predicable_default
;
633 /* Find out which value we're looking at. Multiple alternatives means at
634 least one is predicable. */
635 if (strchr (value
, ',') != NULL
)
637 if (strcmp (value
, predicable_true
) == 0)
639 if (strcmp (value
, predicable_false
) == 0)
642 error_with_line (elem
->lineno
,
643 "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_with_line (elem
->lineno
,
716 "unsupported value for `%s'", subst_name
);
719 case SET_ATTR_ALTERNATIVE
:
720 error_with_line (elem
->lineno
,
721 "%s: `set_attr_alternative' is unsupported by "
723 XSTR (elem
->data
, 0));
735 if (strcmp (value
, subst_true
) == 0)
737 if (strcmp (value
, subst_false
) == 0)
740 error_with_line (elem
->lineno
,
741 "unknown value `%s' for `%s' attribute", value
, subst_name
);
745 /* Compare RTL-template of original define_insn X to input RTL-template of
746 define_subst PT. Return 1 if the templates match, 0 otherwise.
747 During the comparison, the routine also fills global_array OPERAND_DATA. */
749 subst_pattern_match (rtx x
, rtx pt
, int lineno
)
751 RTX_CODE code
, code_pt
;
753 const char *fmt
, *pred_name
;
756 code_pt
= GET_CODE (pt
);
758 if (code_pt
== MATCH_OPERAND
)
760 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
761 always accept them. */
762 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
763 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
764 return false; /* Modes don't match. */
766 if (code
== MATCH_OPERAND
)
768 pred_name
= XSTR (pt
, 1);
769 if (pred_name
[0] != 0)
771 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
772 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
773 return false; /* Predicates don't match. */
777 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
778 operand_data
[XINT (pt
, 0)] = x
;
782 if (code_pt
== MATCH_OPERATOR
)
784 int x_vecexp_pos
= -1;
787 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
790 /* In case X is also match_operator, compare predicates. */
791 if (code
== MATCH_OPERATOR
)
793 pred_name
= XSTR (pt
, 1);
794 if (pred_name
[0] != 0)
796 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
797 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
803 MATCH_OPERATOR in input template could match in original template
804 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
805 In the first case operands are at (XVECEXP (x, 2, j)), in the second
806 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
807 X_VECEXP_POS variable shows, where to look for these operands. */
809 || code
== UNSPEC_VOLATILE
)
811 else if (code
== MATCH_OPERATOR
)
816 /* MATCH_OPERATOR or UNSPEC case. */
817 if (x_vecexp_pos
>= 0)
819 /* Compare operands number in X and PT. */
820 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
822 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
823 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
824 XVECEXP (pt
, 2, j
), lineno
))
828 /* Ordinary operator. */
831 /* Compare operands number in X and PT.
832 We count operands differently for X and PT since we compare
833 an operator (with operands directly in RTX) and MATCH_OPERATOR
834 (that has a vector with operands). */
835 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
837 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
838 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), lineno
))
842 /* Store the operand to OPERAND_DATA array. */
843 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
844 operand_data
[XINT (pt
, 0)] = x
;
848 if (code_pt
== MATCH_PAR_DUP
849 || code_pt
== MATCH_DUP
850 || code_pt
== MATCH_OP_DUP
851 || code_pt
== MATCH_SCRATCH
852 || code_pt
== MATCH_PARALLEL
)
854 /* Currently interface for these constructions isn't defined -
855 probably they aren't needed in input template of define_subst at all.
856 So, for now their usage in define_subst is forbidden. */
857 error_with_line (lineno
, "%s cannot be used in define_subst",
858 GET_RTX_NAME (code_pt
));
861 gcc_assert (code
!= MATCH_PAR_DUP
862 && code_pt
!= MATCH_DUP
863 && code_pt
!= MATCH_OP_DUP
864 && code_pt
!= MATCH_SCRATCH
865 && code_pt
!= MATCH_PARALLEL
866 && code_pt
!= MATCH_OPERAND
867 && code_pt
!= MATCH_OPERATOR
);
868 /* If PT is none of the handled above, then we match only expressions with
869 the same code in X. */
873 fmt
= GET_RTX_FORMAT (code_pt
);
874 len
= GET_RTX_LENGTH (code_pt
);
876 for (i
= 0; i
< len
; i
++)
883 case 'i': case 'w': case 's':
887 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), lineno
))
892 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
894 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
895 if (!subst_pattern_match (XVECEXP (x
, i
, j
), XVECEXP (pt
, i
, j
),
908 /* Examine the attribute "predicable"; discover its boolean values
912 identify_predicable_attribute (void)
914 struct queue_elem
*elem
;
915 char *p_true
, *p_false
;
918 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
919 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
920 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
923 error_with_line (define_cond_exec_queue
->lineno
,
924 "attribute `predicable' not defined");
928 value
= XSTR (elem
->data
, 1);
929 p_false
= xstrdup (value
);
930 p_true
= strchr (p_false
, ',');
931 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
933 error_with_line (elem
->lineno
, "attribute `predicable' is not a boolean");
939 predicable_true
= p_true
;
940 predicable_false
= p_false
;
942 switch (GET_CODE (XEXP (elem
->data
, 2)))
945 value
= XSTR (XEXP (elem
->data
, 2), 0);
949 error_with_line (elem
->lineno
, "attribute `predicable' cannot be const");
954 error_with_line (elem
->lineno
,
955 "attribute `predicable' must have a constant default");
960 if (strcmp (value
, p_true
) == 0)
961 predicable_default
= 1;
962 else if (strcmp (value
, p_false
) == 0)
963 predicable_default
= 0;
966 error_with_line (elem
->lineno
,
967 "unknown value `%s' for `predicable' attribute", value
);
972 /* Return the number of alternatives in constraint S. */
975 n_alternatives (const char *s
)
986 /* The routine scans rtl PATTERN, find match_operand in it and counts
987 number of alternatives. If PATTERN contains several match_operands
988 with different number of alternatives, error is emitted, and the
989 routine returns 0. If all match_operands in PATTERN have the same
990 number of alternatives, it's stored in N_ALT, and the routine returns 1.
991 Argument LINENO is used in when the error is emitted. */
993 get_alternatives_number (rtx pattern
, int *n_alt
, int lineno
)
1002 code
= GET_CODE (pattern
);
1006 i
= n_alternatives (XSTR (pattern
, 2));
1007 /* n_alternatives returns 1 if constraint string is empty -
1008 here we fix it up. */
1009 if (!*(XSTR (pattern
, 2)))
1014 else if (i
&& i
!= *n_alt
)
1016 error_with_line (lineno
,
1017 "wrong number of alternatives in operand %d",
1026 fmt
= GET_RTX_FORMAT (code
);
1027 len
= GET_RTX_LENGTH (code
);
1028 for (i
= 0; i
< len
; i
++)
1033 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, lineno
))
1038 if (XVEC (pattern
, i
) == NULL
)
1042 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1043 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
),
1048 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
1058 /* Determine how many alternatives there are in INSN, and how many
1062 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1068 code
= GET_CODE (pattern
);
1072 i
= n_alternatives (XSTR (pattern
, 2));
1073 *palt
= (i
> *palt
? i
: *palt
);
1076 case MATCH_OPERATOR
:
1078 case MATCH_PARALLEL
:
1079 i
= XINT (pattern
, 0);
1088 fmt
= GET_RTX_FORMAT (code
);
1089 len
= GET_RTX_LENGTH (code
);
1090 for (i
= 0; i
< len
; i
++)
1095 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1099 if (XVEC (pattern
, i
) == NULL
)
1103 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1104 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1107 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
1117 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
1123 code
= GET_CODE (pattern
);
1128 const char *c
= XSTR (pattern
, 2);
1130 if (n_alternatives (c
) != 1)
1132 error_with_line (lineno
, "too many alternatives for operand %d",
1137 /* Replicate C as needed to fill out ALT alternatives. */
1138 if (c
&& *c
&& alt
> 1)
1140 size_t c_len
= strlen (c
);
1141 size_t len
= alt
* (c_len
+ 1);
1142 char *new_c
= XNEWVEC (char, len
);
1144 memcpy (new_c
, c
, c_len
);
1145 for (i
= 1; i
< alt
; ++i
)
1147 new_c
[i
* (c_len
+ 1) - 1] = ',';
1148 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1150 new_c
[len
- 1] = '\0';
1151 XSTR (pattern
, 2) = new_c
;
1156 case MATCH_OPERATOR
:
1158 case MATCH_PARALLEL
:
1159 XINT (pattern
, 0) += max_op
;
1166 fmt
= GET_RTX_FORMAT (code
);
1167 len
= GET_RTX_LENGTH (code
);
1168 for (i
= 0; i
< len
; i
++)
1175 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
1182 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1184 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1185 alt
, max_op
, lineno
);
1191 case 'i': case 'w': case '0': case 's':
1202 /* Duplicate constraints in PATTERN. If pattern is from original
1203 rtl-template, we need to duplicate each alternative - for that we
1204 need to use duplicate_each_alternative () as a functor ALTER.
1205 If pattern is from output-pattern of define_subst, we need to
1206 duplicate constraints in another way - with duplicate_alternatives ().
1207 N_DUP is multiplication factor. */
1209 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1215 code
= GET_CODE (pattern
);
1219 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1226 fmt
= GET_RTX_FORMAT (code
);
1227 len
= GET_RTX_LENGTH (code
);
1228 for (i
= 0; i
< len
; i
++)
1235 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1241 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1243 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1249 case 'i': case 'w': case '0': case 's':
1261 alter_test_for_insn (struct queue_elem
*ce_elem
,
1262 struct queue_elem
*insn_elem
)
1264 return join_c_conditions (XSTR (ce_elem
->data
, 1),
1265 XSTR (insn_elem
->data
, 2));
1268 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1269 to take "ce_enabled" into account. Return the new expression. */
1271 modify_attr_enabled_ce (rtx val
)
1275 eq_attr
= rtx_alloc (EQ_ATTR
);
1276 ite
= rtx_alloc (IF_THEN_ELSE
);
1277 str
= rtx_alloc (CONST_STRING
);
1279 XSTR (eq_attr
, 0) = "ce_enabled";
1280 XSTR (eq_attr
, 1) = "yes";
1281 XSTR (str
, 0) = "no";
1282 XEXP (ite
, 0) = eq_attr
;
1283 XEXP (ite
, 1) = val
;
1284 XEXP (ite
, 2) = str
;
1289 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1290 from a define_insn pattern. We must modify the "predicable" attribute
1291 to be named "ce_enabled", and also change any "enabled" attribute that's
1292 present so that it takes ce_enabled into account.
1293 We rely on the fact that INSN was created with copy_rtx, and modify data
1297 alter_attrs_for_insn (rtx insn
)
1299 static bool global_changes_made
= false;
1300 rtvec vec
= XVEC (insn
, 4);
1304 int predicable_idx
= -1;
1305 int enabled_idx
= -1;
1311 num_elem
= GET_NUM_ELEM (vec
);
1312 for (i
= num_elem
- 1; i
>= 0; --i
)
1314 rtx sub
= RTVEC_ELT (vec
, i
);
1315 switch (GET_CODE (sub
))
1318 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1321 XSTR (sub
, 0) = "ce_enabled";
1323 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1326 XSTR (sub
, 0) = "nonce_enabled";
1330 case SET_ATTR_ALTERNATIVE
:
1331 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1332 /* We already give an error elsewhere. */
1334 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1337 XSTR (sub
, 0) = "nonce_enabled";
1342 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1344 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1346 sub
= SET_SRC (sub
);
1347 if (GET_CODE (sub
) == CONST_STRING
)
1350 XSTR (sub
, 0) = "ce_enabled";
1353 /* We already give an error elsewhere. */
1357 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1360 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1368 if (predicable_idx
== -1)
1371 if (!global_changes_made
)
1373 struct queue_elem
*elem
;
1375 global_changes_made
= true;
1376 add_define_attr ("ce_enabled");
1377 add_define_attr ("nonce_enabled");
1379 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1380 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1382 XEXP (elem
->data
, 2)
1383 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1386 if (enabled_idx
== -1)
1389 new_vec
= rtvec_alloc (num_elem
+ 1);
1390 for (i
= 0; i
< num_elem
; i
++)
1391 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1392 val
= rtx_alloc (IF_THEN_ELSE
);
1393 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1394 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1395 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1396 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1397 XSTR (XEXP (val
, 0), 1) = "yes";
1398 XSTR (XEXP (val
, 1), 0) = "yes";
1399 XSTR (XEXP (val
, 2), 0) = "no";
1400 set
= rtx_alloc (SET
);
1401 SET_DEST (set
) = rtx_alloc (ATTR
);
1402 XSTR (SET_DEST (set
), 0) = "enabled";
1403 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1404 RTVEC_ELT (new_vec
, i
) = set
;
1405 XVEC (insn
, 4) = new_vec
;
1408 /* As number of constraints is changed after define_subst, we need to
1409 process attributes as well - we need to duplicate them the same way
1410 that we duplicated constraints in original pattern
1411 ELEM is a queue element, containing our rtl-template,
1412 N_DUP - multiplication factor. */
1414 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1416 rtvec vec
= XVEC (elem
->data
, 4);
1420 if (n_dup
< 2 || ! vec
)
1423 num_elem
= GET_NUM_ELEM (vec
);
1424 for (i
= num_elem
- 1; i
>= 0; --i
)
1426 rtx sub
= RTVEC_ELT (vec
, i
);
1427 switch (GET_CODE (sub
))
1430 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1431 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1434 case SET_ATTR_ALTERNATIVE
:
1436 error_with_line (elem
->lineno
,
1437 "%s: `define_subst' does not support attributes "
1438 "assigned by `set' and `set_attr_alternative'",
1439 XSTR (elem
->data
, 0));
1448 /* Adjust all of the operand numbers in SRC to match the shift they'll
1449 get from an operand displacement of DISP. Return a pointer after the
1453 shift_output_template (char *dest
, const char *src
, int disp
)
1462 if (ISDIGIT ((unsigned char) c
))
1464 else if (ISALPHA (c
))
1477 alter_output_for_insn (struct queue_elem
*ce_elem
,
1478 struct queue_elem
*insn_elem
,
1479 int alt
, int max_op
)
1481 const char *ce_out
, *insn_out
;
1483 size_t len
, ce_len
, insn_len
;
1485 /* ??? Could coordinate with genoutput to not duplicate code here. */
1487 ce_out
= XSTR (ce_elem
->data
, 2);
1488 insn_out
= XTMPL (insn_elem
->data
, 3);
1489 if (!ce_out
|| *ce_out
== '\0')
1492 ce_len
= strlen (ce_out
);
1493 insn_len
= strlen (insn_out
);
1495 if (*insn_out
== '*')
1496 /* You must take care of the predicate yourself. */
1499 if (*insn_out
== '@')
1501 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1502 p
= result
= XNEWVEC (char, len
);
1508 while (ISSPACE ((unsigned char) *insn_out
));
1510 if (*insn_out
!= '#')
1512 p
= shift_output_template (p
, ce_out
, max_op
);
1518 while (*insn_out
&& *insn_out
!= '\n');
1525 len
= ce_len
+ 1 + insn_len
+ 1;
1526 result
= XNEWVEC (char, len
);
1528 p
= shift_output_template (result
, ce_out
, max_op
);
1530 memcpy (p
, insn_out
, insn_len
+ 1);
1536 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1537 string, duplicated N_DUP times. */
1540 duplicate_alternatives (const char * str
, int n_dup
)
1542 int i
, len
, new_len
;
1549 while (ISSPACE (*str
))
1557 new_len
= (len
+ 1) * n_dup
;
1559 sp
= result
= XNEWVEC (char, new_len
);
1561 /* Global modifier characters mustn't be duplicated: skip if found. */
1562 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1568 /* Copy original constraints N_DUP times. */
1569 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1571 memcpy (sp
, cp
, len
);
1572 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1578 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1579 each alternative from the original string is duplicated N_DUP times. */
1581 duplicate_each_alternative (const char * str
, int n_dup
)
1583 int i
, len
, new_len
;
1584 char *result
, *sp
, *ep
, *cp
;
1589 while (ISSPACE (*str
))
1597 new_len
= (strlen (cp
) + 1) * n_dup
;
1599 sp
= result
= XNEWVEC (char, new_len
);
1601 /* Global modifier characters mustn't be duplicated: skip if found. */
1602 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1607 if ((ep
= strchr (cp
, ',')) != NULL
)
1611 /* Copy a constraint N_DUP times. */
1612 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1614 memcpy (sp
, cp
, len
);
1615 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1625 /* Alter the output of INSN whose pattern was modified by
1626 DEFINE_SUBST. We must replicate output strings according
1627 to the new number of alternatives ALT in substituted pattern.
1628 If ALT equals 1, output has one alternative or defined by C
1629 code, then output is returned without any changes. */
1632 alter_output_for_subst_insn (rtx insn
, int alt
)
1634 const char *insn_out
, *sp
;
1635 char *old_out
, *new_out
, *cp
;
1638 insn_out
= XTMPL (insn
, 3);
1640 if (alt
< 2 || *insn_out
== '*' || *insn_out
!= '@')
1643 old_out
= XNEWVEC (char, strlen (insn_out
)),
1646 while (ISSPACE (*sp
) || *sp
== '@')
1650 old_out
[i
++] = *sp
++;
1652 new_len
= alt
* (i
+ 1) + 1;
1654 new_out
= XNEWVEC (char, new_len
);
1657 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= i
+ 1)
1659 memcpy (cp
, old_out
, i
);
1660 *(cp
+i
) = (j
== alt
- 1) ? '\0' : '\n';
1666 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1669 process_one_cond_exec (struct queue_elem
*ce_elem
)
1671 struct queue_elem
*insn_elem
;
1672 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1674 int alternatives
, max_operand
;
1675 rtx pred
, insn
, pattern
, split
;
1679 if (! is_predicable (insn_elem
))
1684 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1687 if (XVECLEN (ce_elem
->data
, 0) != 1)
1689 error_with_line (ce_elem
->lineno
, "too many patterns in predicate");
1693 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1694 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1699 /* Construct a new pattern for the new insn. */
1700 insn
= copy_rtx (insn_elem
->data
);
1701 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1702 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1703 XSTR (insn
, 0) = new_name
;
1704 pattern
= rtx_alloc (COND_EXEC
);
1705 XEXP (pattern
, 0) = pred
;
1706 if (XVECLEN (insn
, 1) == 1)
1708 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
1709 XVECEXP (insn
, 1, 0) = pattern
;
1710 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
1714 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1715 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
1716 XVEC (insn
, 1) = rtvec_alloc (1);
1717 XVECEXP (insn
, 1, 0) = pattern
;
1720 if (XVEC (ce_elem
->data
, 3) != NULL
)
1722 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1723 + XVECLEN (ce_elem
->data
, 3));
1726 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1727 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1729 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1730 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1732 XVEC (insn
, 4) = attributes
;
1735 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1736 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1737 alternatives
, max_operand
);
1738 alter_attrs_for_insn (insn
);
1740 /* Put the new pattern on the `other' list so that it
1741 (a) is not reprocessed by other define_cond_exec patterns
1742 (b) appears after all normal define_insn patterns.
1744 ??? B is debatable. If one has normal insns that match
1745 cond_exec patterns, they will be preferred over these
1746 generated patterns. Whether this matters in practice, or if
1747 it's a good thing, or whether we should thread these new
1748 patterns into the define_insn chain just after their generator
1749 is something we'll have to experiment with. */
1751 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
1754 if (!insn_elem
->split
)
1757 /* If the original insn came from a define_insn_and_split,
1758 generate a new split to handle the predicated insn. */
1759 split
= copy_rtx (insn_elem
->split
->data
);
1760 /* Predicate the pattern matched by the split. */
1761 pattern
= rtx_alloc (COND_EXEC
);
1762 XEXP (pattern
, 0) = pred
;
1763 if (XVECLEN (split
, 0) == 1)
1765 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
1766 XVECEXP (split
, 0, 0) = pattern
;
1767 PUT_NUM_ELEM (XVEC (split
, 0), 1);
1771 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1772 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
1773 XVEC (split
, 0) = rtvec_alloc (1);
1774 XVECEXP (split
, 0, 0) = pattern
;
1776 /* Predicate all of the insns generated by the split. */
1777 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1779 pattern
= rtx_alloc (COND_EXEC
);
1780 XEXP (pattern
, 0) = pred
;
1781 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1782 XVECEXP (split
, 2, i
) = pattern
;
1784 /* Add the new split to the queue. */
1785 queue_pattern (split
, &other_tail
, read_md_filename
,
1786 insn_elem
->split
->lineno
);
1790 /* Try to apply define_substs to the given ELEM.
1791 Only define_substs, specified via attributes would be applied.
1792 If attribute, requiring define_subst, is set, but no define_subst
1793 was applied, ELEM would be deleted. */
1796 process_substs_on_one_elem (struct queue_elem
*elem
,
1797 struct queue_elem
*queue
)
1799 struct queue_elem
*subst_elem
;
1800 int i
, j
, patterns_match
;
1802 for (subst_elem
= define_subst_queue
;
1803 subst_elem
; subst_elem
= subst_elem
->next
)
1805 int alternatives
, alternatives_subst
;
1807 rtvec subst_pattern_vec
;
1809 if (!has_subst_attribute (elem
, subst_elem
))
1812 /* Compare original rtl-pattern from define_insn with input
1813 pattern from define_subst.
1814 Also, check if numbers of alternatives are the same in all
1816 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1820 alternatives_subst
= -1;
1821 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1823 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1824 XVECEXP (subst_elem
->data
, 1, j
),
1825 subst_elem
->lineno
))
1831 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1832 &alternatives
, subst_elem
->lineno
))
1839 /* Check if numbers of alternatives are the same in all
1840 match_operands in output template of define_subst. */
1841 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1843 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1844 &alternatives_subst
,
1845 subst_elem
->lineno
))
1852 if (!patterns_match
)
1855 /* Clear array in which we save occupied indexes of operands. */
1856 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1858 /* Create a pattern, based on the output one from define_subst. */
1859 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1860 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1862 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1864 /* Duplicate constraints in substitute-pattern. */
1865 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1866 duplicate_each_alternative
);
1868 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1870 /* Substitute match_dup and match_op_dup in the new pattern and
1871 duplicate constraints. */
1872 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1873 alternatives_subst
);
1875 replace_duplicating_operands_in_pattern (subst_pattern
);
1877 /* We don't need any constraints in DEFINE_EXPAND. */
1878 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1879 remove_constraints (subst_pattern
);
1881 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1883 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1885 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1886 match_operand_entries_in_pattern
[i
] = NULL
;
1888 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1890 XTMPL (elem
->data
, 3) =
1891 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1892 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1895 /* Recalculate condition, joining conditions from original and
1896 DEFINE_SUBST input patterns. */
1897 XSTR (elem
->data
, 2) = join_c_conditions (XSTR (subst_elem
->data
, 2),
1898 XSTR (elem
->data
, 2));
1899 /* Mark that subst was applied by changing attribute from "yes"
1901 change_subst_attribute (elem
, subst_elem
, subst_false
);
1904 /* If ELEM contains a subst attribute with value "yes", then we
1905 expected that a subst would be applied, but it wasn't - so,
1906 we need to remove that elementto avoid duplicating. */
1907 for (subst_elem
= define_subst_queue
;
1908 subst_elem
; subst_elem
= subst_elem
->next
)
1910 if (has_subst_attribute (elem
, subst_elem
))
1912 remove_from_queue (elem
, &queue
);
1918 /* This is a subroutine of mark_operands_used_in_match_dup.
1919 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1921 mark_operands_from_match_dup (rtx pattern
)
1924 int i
, j
, len
, opno
;
1926 if (GET_CODE (pattern
) == MATCH_OPERAND
1927 || GET_CODE (pattern
) == MATCH_OPERATOR
1928 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1930 opno
= XINT (pattern
, 0);
1931 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1932 used_operands_numbers
[opno
] = 1;
1934 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1935 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1936 for (i
= 0; i
< len
; i
++)
1941 mark_operands_from_match_dup (XEXP (pattern
, i
));
1944 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1945 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1951 /* This is a subroutine of adjust_operands_numbers.
1952 It goes through all expressions in PATTERN and when MATCH_DUP is
1953 met, all MATCH_OPERANDs inside it is marked as occupied. The
1954 process of marking is done by routin mark_operands_from_match_dup. */
1956 mark_operands_used_in_match_dup (rtx pattern
)
1959 int i
, j
, len
, opno
;
1961 if (GET_CODE (pattern
) == MATCH_DUP
)
1963 opno
= XINT (pattern
, 0);
1964 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1965 mark_operands_from_match_dup (operand_data
[opno
]);
1968 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1969 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1970 for (i
= 0; i
< len
; i
++)
1975 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1978 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1979 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1985 /* This is subroutine of renumerate_operands_in_pattern.
1986 It finds first not-occupied operand-index. */
1988 find_first_unused_number_of_operand ()
1991 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1992 if (!used_operands_numbers
[i
])
1994 return MAX_OPERANDS
;
1997 /* This is subroutine of adjust_operands_numbers.
1998 It visits all expressions in PATTERN and assigns not-occupied
1999 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2002 renumerate_operands_in_pattern (rtx pattern
)
2006 int i
, j
, len
, new_opno
;
2007 code
= GET_CODE (pattern
);
2009 if (code
== MATCH_OPERAND
2010 || code
== MATCH_OPERATOR
)
2012 new_opno
= find_first_unused_number_of_operand ();
2013 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
2014 XINT (pattern
, 0) = new_opno
;
2015 used_operands_numbers
[new_opno
] = 1;
2018 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2019 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2020 for (i
= 0; i
< len
; i
++)
2025 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2028 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2029 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2035 /* If output pattern of define_subst contains MATCH_DUP, then this
2036 expression would be replaced with the pattern, matched with
2037 MATCH_OPERAND from input pattern. This pattern could contain any
2038 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2039 that a MATCH_OPERAND from output_pattern (if any) would have the
2040 same number, as MATCH_OPERAND from copied pattern. To avoid such
2041 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2042 laying in the output pattern outside of MATCH_DUPs. */
2044 adjust_operands_numbers (rtx pattern
)
2046 mark_operands_used_in_match_dup (pattern
);
2048 renumerate_operands_in_pattern (pattern
);
2053 /* Generate RTL expression
2057 generate_match_dup (int opno
)
2059 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2060 PUT_CODE (return_rtx
, MATCH_DUP
);
2061 XINT (return_rtx
, 0) = opno
;
2065 /* This routine checks all match_operands in PATTERN and if some of
2066 have the same index, it replaces all of them except the first one to
2068 Usually, match_operands with the same indexes are forbidden, but
2069 after define_subst copy an RTL-expression from original template,
2070 indexes of existed and just-copied match_operands could coincide.
2071 To fix it, we replace one of them with match_dup. */
2073 replace_duplicating_operands_in_pattern (rtx pattern
)
2076 int i
, j
, len
, opno
;
2079 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2081 opno
= XINT (pattern
, 0);
2082 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2083 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2085 match_operand_entries_in_pattern
[opno
] = pattern
;
2090 /* Compare predicates before replacing with match_dup. */
2091 if (strcmp (XSTR (pattern
, 1),
2092 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2094 error ("duplicated match_operands with different predicates were"
2098 return generate_match_dup (opno
);
2101 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2102 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2103 for (i
= 0; i
< len
; i
++)
2108 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2110 XEXP (pattern
, i
) = mdup
;
2113 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2116 replace_duplicating_operands_in_pattern (XVECEXP
2119 XVECEXP (pattern
, i
, j
) = mdup
;
2127 /* The routine modifies given input PATTERN of define_subst, replacing
2128 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2129 pattern, whose operands are stored in OPERAND_DATA array.
2130 It also duplicates constraints in operands - constraints from
2131 define_insn operands are duplicated N_SUBST_ALT times, constraints
2132 from define_subst operands are duplicated N_ALT times.
2133 After the duplication, returned output rtl-pattern contains every
2134 combination of input constraints Vs constraints from define_subst
2137 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2141 int i
, j
, len
, opno
;
2143 code
= GET_CODE (pattern
);
2148 opno
= XINT (pattern
, 0);
2150 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2152 if (operand_data
[opno
])
2154 pattern
= copy_rtx (operand_data
[opno
]);
2156 /* Duplicate constraints. */
2157 pattern
= alter_constraints (pattern
, n_subst_alt
,
2158 duplicate_alternatives
);
2166 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2167 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2168 for (i
= 0; i
< len
; i
++)
2173 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2174 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2175 n_alt
, n_subst_alt
);
2178 if (XVEC (pattern
, i
) == NULL
)
2181 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2182 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2183 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2184 n_alt
, n_subst_alt
);
2187 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
2197 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2198 patterns appropriately. */
2201 process_define_cond_exec (void)
2203 struct queue_elem
*elem
;
2205 identify_predicable_attribute ();
2209 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2210 process_one_cond_exec (elem
);
2213 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2214 DEFINE_EXPAND patterns appropriately. */
2217 process_define_subst (void)
2219 struct queue_elem
*elem
, *elem_attr
;
2221 /* Check if each define_subst has corresponding define_subst_attr. */
2222 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2224 for (elem_attr
= define_subst_attr_queue
;
2226 elem_attr
= elem_attr
->next
)
2227 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2230 error_with_line (elem
->lineno
,
2231 "%s: `define_subst' must have at least one "
2232 "corresponding `define_subst_attr'",
2233 XSTR (elem
->data
, 0));
2239 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2240 process_substs_on_one_elem (elem
, define_insn_queue
);
2241 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2243 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2245 process_substs_on_one_elem (elem
, other_queue
);
2249 /* A read_md_files callback for reading an rtx. */
2252 rtx_handle_directive (int lineno
, const char *rtx_name
)
2256 if (read_rtx (rtx_name
, &queue
))
2257 for (x
= queue
; x
; x
= XEXP (x
, 1))
2258 process_rtx (XEXP (x
, 0), lineno
);
2261 /* Comparison function for the mnemonic hash table. */
2264 htab_eq_string (const void *s1
, const void *s2
)
2266 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2269 /* Add mnemonic STR with length LEN to the mnemonic hash table
2270 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2271 and a permanent heap copy of STR is created. */
2274 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, int len
)
2278 char *str_zero
= (char*)alloca (len
+ 1);
2280 memcpy (str_zero
, str
, len
);
2281 str_zero
[len
] = '\0';
2283 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2288 /* Not found; create a permanent copy and add it to the hash table. */
2289 new_str
= XNEWVAR (char, len
+ 1);
2290 memcpy (new_str
, str_zero
, len
+ 1);
2294 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2295 table in MNEMONIC_HTAB.
2297 The mnemonics cannot be found if they are emitted using C code.
2299 If a mnemonic string contains ';' or a newline the string assumed
2300 to consist of more than a single instruction. The attribute value
2301 will then be set to the user defined default value. */
2304 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2306 const char *template_code
, *cp
;
2313 template_code
= XTMPL (insn
, 3);
2315 /* Skip patterns which use C code to emit the template. */
2316 if (template_code
[0] == '*')
2319 if (template_code
[0] == '@')
2320 cp
= &template_code
[1];
2322 cp
= &template_code
[0];
2326 const char *ep
, *sp
;
2329 while (ISSPACE (*cp
))
2332 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2337 obstack_1grow (&string_obstack
, ',');
2339 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2340 || (*cp
>= 'a' && *cp
<= 'z')))
2343 obstack_1grow (&string_obstack
, *cp
);
2350 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2352 /* Don't set a value if there are more than one
2353 instruction in the string. */
2354 obstack_next_free (&string_obstack
) =
2355 obstack_next_free (&string_obstack
) - size
;
2364 obstack_1grow (&string_obstack
, '*');
2366 add_mnemonic_string (mnemonic_htab
,
2367 obstack_next_free (&string_obstack
) - size
,
2372 /* An insn definition might emit an empty string. */
2373 if (obstack_object_size (&string_obstack
) == 0)
2376 obstack_1grow (&string_obstack
, '\0');
2378 set_attr
= rtx_alloc (SET_ATTR
);
2379 XSTR (set_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2380 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2381 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2382 XSTR (set_attr
, 0) = attr_name
;
2384 if (!XVEC (insn
, 4))
2387 vec_len
= XVECLEN (insn
, 4);
2389 new_vec
= rtvec_alloc (vec_len
+ 1);
2390 for (i
= 0; i
< vec_len
; i
++)
2391 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2392 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2393 XVEC (insn
, 4) = new_vec
;
2396 /* This function is called for the elements in the mnemonic hashtable
2397 and generates a comma separated list of the mnemonics. */
2400 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
2402 obstack_grow (&string_obstack
, (char*)*slot
, strlen ((char*)*slot
));
2403 obstack_1grow (&string_obstack
, ',');
2407 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2408 insn definition in case the back end requests it by defining the
2409 mnemonic attribute. The values for the attribute will be extracted
2410 from the output patterns of the insn definitions as far as
2414 gen_mnemonic_attr (void)
2416 struct queue_elem
*elem
;
2417 rtx mnemonic_attr
= NULL
;
2418 htab_t mnemonic_htab
;
2419 const char *str
, *p
;
2425 /* Look for the DEFINE_ATTR for `mnemonic'. */
2426 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2427 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2428 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2430 mnemonic_attr
= elem
->data
;
2434 /* A (define_attr "mnemonic" "...") indicates that the back-end
2435 wants a mnemonic attribute to be generated. */
2439 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2440 htab_eq_string
, 0, xcalloc
, free
);
2442 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2444 rtx insn
= elem
->data
;
2447 /* Check if the insn definition already has
2448 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2450 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2452 rtx set_attr
= XVECEXP (insn
, 4, i
);
2454 switch (GET_CODE (set_attr
))
2457 case SET_ATTR_ALTERNATIVE
:
2458 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2462 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2463 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2464 MNEMONIC_ATTR_NAME
) == 0)
2473 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2476 /* Add the user defined values to the hash table. */
2477 str
= XSTR (mnemonic_attr
, 1);
2478 while ((p
= scan_comma_elt (&str
)) != NULL
)
2479 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2481 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2483 /* Replace the last ',' with the zero end character. */
2484 *((char *)obstack_next_free (&string_obstack
) - 1) = '\0';
2485 XSTR (mnemonic_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2488 /* Check if there are DEFINE_ATTRs with the same name. */
2490 check_define_attr_duplicates ()
2492 struct queue_elem
*elem
;
2497 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2499 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2501 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2503 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2508 error_with_line (elem
->lineno
, "redefinition of attribute '%s'",
2510 htab_delete (attr_htab
);
2517 htab_delete (attr_htab
);
2520 /* The entry point for initializing the reader. */
2523 init_rtx_reader_args_cb (int argc
, char **argv
,
2524 bool (*parse_opt
) (const char *))
2526 /* Prepare to read input. */
2527 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
2528 init_predicate_table ();
2529 obstack_init (rtl_obstack
);
2531 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2534 read_md_files (argc
, argv
, parse_opt
, rtx_handle_directive
);
2536 if (define_attr_queue
!= NULL
)
2537 check_define_attr_duplicates ();
2539 /* Process define_cond_exec patterns. */
2540 if (define_cond_exec_queue
!= NULL
)
2541 process_define_cond_exec ();
2543 /* Process define_subst patterns. */
2544 if (define_subst_queue
!= NULL
)
2545 process_define_subst ();
2547 if (define_attr_queue
!= NULL
)
2548 gen_mnemonic_attr ();
2553 /* Programs that don't have their own options can use this entry point
2556 init_rtx_reader_args (int argc
, char **argv
)
2558 return init_rtx_reader_args_cb (argc
, argv
, 0);
2561 /* The entry point for reading a single rtx from an md file. Return
2562 the rtx, or NULL if the md file has been fully processed.
2563 Return the line where the rtx was found in LINENO.
2564 Return the number of code generating rtx'en read since the start
2565 of the md file in SEQNR. */
2568 read_md_rtx (int *lineno
, int *seqnr
)
2570 struct queue_elem
**queue
, *elem
;
2575 /* Read all patterns from a given queue before moving on to the next. */
2576 if (define_attr_queue
!= NULL
)
2577 queue
= &define_attr_queue
;
2578 else if (define_pred_queue
!= NULL
)
2579 queue
= &define_pred_queue
;
2580 else if (define_insn_queue
!= NULL
)
2581 queue
= &define_insn_queue
;
2582 else if (other_queue
!= NULL
)
2583 queue
= &other_queue
;
2588 *queue
= elem
->next
;
2590 read_md_filename
= elem
->filename
;
2591 *lineno
= elem
->lineno
;
2592 *seqnr
= sequence_num
;
2596 /* Discard insn patterns which we know can never match (because
2597 their C test is provably always false). If insn_elision is
2598 false, our caller needs to see all the patterns. Note that the
2599 elided patterns are never counted by the sequence numbering; it
2600 is the caller's responsibility, when insn_elision is false, not
2601 to use elided pattern numbers for anything. */
2602 switch (GET_CODE (desc
))
2607 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
2609 else if (insn_elision
)
2612 /* *seqnr is used here so the name table will match caller's
2613 idea of insn numbering, whether or not elision is active. */
2614 record_insn_name (*seqnr
, XSTR (desc
, 0));
2618 case DEFINE_PEEPHOLE
:
2619 case DEFINE_PEEPHOLE2
:
2620 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
2622 else if (insn_elision
)
2633 /* Helper functions for insn elision. */
2635 /* Compute a hash function of a c_test structure, which is keyed
2636 by its ->expr field. */
2638 hash_c_test (const void *x
)
2640 const struct c_test
*a
= (const struct c_test
*) x
;
2641 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2649 while ((c
= *s
++) != '\0')
2651 hash
+= c
+ (c
<< 17);
2656 hash
+= len
+ (len
<< 17);
2662 /* Compare two c_test expression structures. */
2664 cmp_c_test (const void *x
, const void *y
)
2666 const struct c_test
*a
= (const struct c_test
*) x
;
2667 const struct c_test
*b
= (const struct c_test
*) y
;
2669 return !strcmp (a
->expr
, b
->expr
);
2672 /* Given a string representing a C test expression, look it up in the
2673 condition_table and report whether or not its value is known
2674 at compile time. Returns a tristate: 1 for known true, 0 for
2675 known false, -1 for unknown. */
2677 maybe_eval_c_test (const char *expr
)
2679 const struct c_test
*test
;
2680 struct c_test dummy
;
2686 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2692 /* Record the C test expression EXPR in the condition_table, with
2693 value VAL. Duplicates clobber previous entries. */
2696 add_c_test (const char *expr
, int value
)
2698 struct c_test
*test
;
2703 test
= XNEW (struct c_test
);
2705 test
->value
= value
;
2707 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2710 /* For every C test, call CALLBACK with two arguments: a pointer to
2711 the condition structure and INFO. Stops when CALLBACK returns zero. */
2713 traverse_c_tests (htab_trav callback
, void *info
)
2715 if (condition_table
)
2716 htab_traverse (condition_table
, callback
, info
);
2719 /* Helper functions for define_predicate and define_special_predicate
2720 processing. Shared between genrecog.c and genpreds.c. */
2722 static htab_t predicate_table
;
2723 struct pred_data
*first_predicate
;
2724 static struct pred_data
**last_predicate
= &first_predicate
;
2727 hash_struct_pred_data (const void *ptr
)
2729 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2733 eq_struct_pred_data (const void *a
, const void *b
)
2735 return !strcmp (((const struct pred_data
*)a
)->name
,
2736 ((const struct pred_data
*)b
)->name
);
2740 lookup_predicate (const char *name
)
2742 struct pred_data key
;
2744 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2747 /* Record that predicate PRED can accept CODE. */
2750 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2752 if (!pred
->codes
[code
])
2755 pred
->codes
[code
] = true;
2757 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2758 pred
->allows_non_const
= true;
2765 && code
!= STRICT_LOW_PART
2767 pred
->allows_non_lvalue
= true;
2769 if (pred
->num_codes
== 1)
2770 pred
->singleton
= code
;
2771 else if (pred
->num_codes
== 2)
2772 pred
->singleton
= UNKNOWN
;
2777 add_predicate (struct pred_data
*pred
)
2779 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2782 error ("duplicate predicate definition for '%s'", pred
->name
);
2786 *last_predicate
= pred
;
2787 last_predicate
= &pred
->next
;
2790 /* This array gives the initial content of the predicate table. It
2791 has entries for all predicates defined in recog.c. */
2793 struct std_pred_table
2797 bool allows_const_p
;
2798 RTX_CODE codes
[NUM_RTX_CODE
];
2801 static const struct std_pred_table std_preds
[] = {
2802 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2803 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
}},
2804 {"register_operand", false, false, {SUBREG
, REG
}},
2805 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2806 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2807 {"immediate_operand", false, true, {UNKNOWN
}},
2808 {"const_int_operand", false, false, {CONST_INT
}},
2809 #if TARGET_SUPPORTS_WIDE_INT
2810 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2811 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2813 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2815 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2816 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2817 {"push_operand", false, false, {MEM
}},
2818 {"pop_operand", false, false, {MEM
}},
2819 {"memory_operand", false, false, {SUBREG
, MEM
}},
2820 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2821 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2823 LEU
, LTU
, GEU
, GTU
}},
2824 {"comparison_operator", false, false, {EQ
, NE
,
2831 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2833 /* Initialize the table of predicate definitions, starting with
2834 the information we have on generic predicates. */
2837 init_predicate_table (void)
2840 struct pred_data
*pred
;
2842 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2843 eq_struct_pred_data
, 0,
2846 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2848 pred
= XCNEW (struct pred_data
);
2849 pred
->name
= std_preds
[i
].name
;
2850 pred
->special
= std_preds
[i
].special
;
2852 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2853 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2855 if (std_preds
[i
].allows_const_p
)
2856 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2857 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2858 add_predicate_code (pred
, (enum rtx_code
) j
);
2860 add_predicate (pred
);
2864 /* These functions allow linkage with print-rtl.c. Also, some generators
2865 like to annotate their output with insn names. */
2867 /* Holds an array of names indexed by insn_code_number. */
2868 static char **insn_name_ptr
= 0;
2869 static int insn_name_ptr_size
= 0;
2872 get_insn_name (int code
)
2874 if (code
< insn_name_ptr_size
)
2875 return insn_name_ptr
[code
];
2881 record_insn_name (int code
, const char *name
)
2883 static const char *last_real_name
= "insn";
2884 static int last_real_code
= 0;
2887 if (insn_name_ptr_size
<= code
)
2890 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2891 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2892 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2893 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2894 insn_name_ptr_size
= new_size
;
2897 if (!name
|| name
[0] == '\0')
2899 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2900 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2904 last_real_name
= new_name
= xstrdup (name
);
2905 last_real_code
= code
;
2908 insn_name_ptr
[code
] = new_name
;
2911 /* Make STATS describe the operands that appear in rtx X. */
2914 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2924 code
= GET_CODE (x
);
2928 case MATCH_OPERATOR
:
2929 case MATCH_PARALLEL
:
2930 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
2937 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
2941 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
2948 fmt
= GET_RTX_FORMAT (code
);
2949 len
= GET_RTX_LENGTH (code
);
2950 for (i
= 0; i
< len
; i
++)
2952 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
2953 get_pattern_stats_1 (stats
, XEXP (x
, i
));
2954 else if (fmt
[i
] == 'E')
2957 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2958 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
2963 /* Make STATS describe the operands that appear in instruction pattern
2967 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
2971 stats
->max_opno
= -1;
2972 stats
->max_dup_opno
= -1;
2973 stats
->max_scratch_opno
= -1;
2974 stats
->num_dups
= 0;
2976 len
= GET_NUM_ELEM (pattern
);
2977 for (i
= 0; i
< len
; i
++)
2978 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
2980 stats
->num_generator_args
= stats
->max_opno
+ 1;
2981 stats
->num_insn_operands
= MAX (stats
->max_opno
,
2982 stats
->max_scratch_opno
) + 1;
2983 stats
->num_operand_vars
= MAX (stats
->max_opno
,
2984 MAX (stats
->max_dup_opno
,
2985 stats
->max_scratch_opno
)) + 1;