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"
30 #define MAX_OPERANDS 40
32 static rtx operand_data
[MAX_OPERANDS
];
33 static rtx match_operand_entries_in_pattern
[MAX_OPERANDS
];
34 static char used_operands_numbers
[MAX_OPERANDS
];
37 /* In case some macros used by files we include need it, define this here. */
42 static struct obstack obstack
;
43 struct obstack
*rtl_obstack
= &obstack
;
45 /* Counter for patterns that generate code: define_insn, define_expand,
46 define_split, define_peephole, and define_peephole2. See read_md_rtx().
47 Any define_insn_and_splits are already in separate queues so that the
48 insn and the splitter get a unique number also. */
49 static int sequence_num
;
51 static int predicable_default
;
52 static const char *predicable_true
;
53 static const char *predicable_false
;
55 static const char *subst_true
= "yes";
56 static const char *subst_false
= "no";
58 static htab_t condition_table
;
60 /* We initially queue all patterns, process the define_insn,
61 define_cond_exec and define_subst patterns, then return
62 them one at a time. */
69 struct queue_elem
*next
;
70 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
71 points to the generated DEFINE_SPLIT. */
72 struct queue_elem
*split
;
75 #define MNEMONIC_ATTR_NAME "mnemonic"
76 #define MNEMONIC_HTAB_SIZE 1024
78 static struct queue_elem
*define_attr_queue
;
79 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
80 static struct queue_elem
*define_pred_queue
;
81 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
82 static struct queue_elem
*define_insn_queue
;
83 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
84 static struct queue_elem
*define_cond_exec_queue
;
85 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
86 static struct queue_elem
*define_subst_queue
;
87 static struct queue_elem
**define_subst_tail
= &define_subst_queue
;
88 static struct queue_elem
*other_queue
;
89 static struct queue_elem
**other_tail
= &other_queue
;
90 static struct queue_elem
*define_subst_attr_queue
;
91 static struct queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
93 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
96 static void remove_constraints (rtx
);
97 static void process_rtx (rtx
, int);
99 static int is_predicable (struct queue_elem
*);
100 static void identify_predicable_attribute (void);
101 static int n_alternatives (const char *);
102 static void collect_insn_data (rtx
, int *, int *);
103 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
104 static const char *alter_test_for_insn (struct queue_elem
*,
105 struct queue_elem
*);
106 static char *shift_output_template (char *, const char *, int);
107 static const char *alter_output_for_insn (struct queue_elem
*,
110 static void process_one_cond_exec (struct queue_elem
*);
111 static void process_define_cond_exec (void);
112 static void init_predicate_table (void);
113 static void record_insn_name (int, const char *);
115 static bool has_subst_attribute (struct queue_elem
*, struct queue_elem
*);
116 static bool subst_pattern_match (rtx
, rtx
, int);
117 static int get_alternatives_number (rtx
, int *, int);
118 static const char * alter_output_for_subst_insn (rtx
, int);
119 static void alter_attrs_for_subst_insn (struct queue_elem
*, int);
120 static void process_substs_on_one_elem (struct queue_elem
*,
121 struct queue_elem
*);
122 static rtx
subst_dup (rtx
, int, int);
123 static void process_define_subst (void);
125 static const char * duplicate_alternatives (const char *, int);
126 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
128 typedef const char * (*constraints_handler_t
) (const char *, int);
129 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
130 static rtx
adjust_operands_numbers (rtx
);
131 static rtx
replace_duplicating_operands_in_pattern (rtx
);
133 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
134 the gensupport programs. */
137 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
140 rtx rt
= rtx_alloc (CONST_INT
);
146 /* Predicate handling.
148 We construct from the machine description a table mapping each
149 predicate to a list of the rtl codes it can possibly match. The
150 function 'maybe_both_true' uses it to deduce that there are no
151 expressions that can be matches by certain pairs of tree nodes.
152 Also, if a predicate can match only one code, we can hardwire that
153 code into the node testing the predicate.
155 Some predicates are flagged as special. validate_pattern will not
156 warn about modeless match_operand expressions if they have a
157 special predicate. Predicates that allow only constants are also
158 treated as special, for this purpose.
160 validate_pattern will warn about predicates that allow non-lvalues
161 when they appear in destination operands.
163 Calculating the set of rtx codes that can possibly be accepted by a
164 predicate expression EXP requires a three-state logic: any given
165 subexpression may definitively accept a code C (Y), definitively
166 reject a code C (N), or may have an indeterminate effect (I). N
167 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
178 We represent Y with 1, N with 0, I with 2. If any code is left in
179 an I state by the complete expression, we must assume that that
180 code can be accepted. */
186 #define TRISTATE_AND(a,b) \
187 ((a) == I ? ((b) == N ? N : I) : \
188 (b) == I ? ((a) == N ? N : I) : \
191 #define TRISTATE_OR(a,b) \
192 ((a) == I ? ((b) == Y ? Y : I) : \
193 (b) == I ? ((a) == Y ? Y : I) : \
196 #define TRISTATE_NOT(a) \
197 ((a) == I ? I : !(a))
199 /* 0 means no warning about that code yet, 1 means warned. */
200 static char did_you_mean_codes
[NUM_RTX_CODE
];
202 /* Recursively calculate the set of rtx codes accepted by the
203 predicate expression EXP, writing the result to CODES. LINENO is
204 the line number on which the directive containing EXP appeared. */
207 compute_test_codes (rtx exp
, int lineno
, char *codes
)
209 char op0_codes
[NUM_RTX_CODE
];
210 char op1_codes
[NUM_RTX_CODE
];
211 char op2_codes
[NUM_RTX_CODE
];
214 switch (GET_CODE (exp
))
217 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
218 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
219 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
220 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
224 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
225 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
226 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
227 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
230 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
231 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
232 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
236 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
237 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
238 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
239 compute_test_codes (XEXP (exp
, 2), lineno
, op2_codes
);
240 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
241 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
242 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
247 /* MATCH_CODE allows a specified list of codes. However, if it
248 does not apply to the top level of the expression, it does not
249 constrain the set of codes for the top level. */
250 if (XSTR (exp
, 1)[0] != '\0')
252 memset (codes
, Y
, NUM_RTX_CODE
);
256 memset (codes
, N
, NUM_RTX_CODE
);
258 const char *next_code
= XSTR (exp
, 0);
261 if (*next_code
== '\0')
263 error_with_line (lineno
, "empty match_code expression");
267 while ((code
= scan_comma_elt (&next_code
)) != 0)
269 size_t n
= next_code
- code
;
272 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
273 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
274 && GET_RTX_NAME (i
)[n
] == '\0')
282 error_with_line (lineno
,
283 "match_code \"%.*s\" matches nothing",
285 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
286 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
287 && GET_RTX_NAME (i
)[n
] == '\0'
288 && !did_you_mean_codes
[i
])
290 did_you_mean_codes
[i
] = 1;
291 message_with_line (lineno
, "(did you mean \"%s\"?)",
300 /* MATCH_OPERAND disallows the set of codes that the named predicate
301 disallows, and is indeterminate for the codes that it does allow. */
303 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
306 error_with_line (lineno
, "reference to unknown predicate '%s'",
310 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
311 codes
[i
] = p
->codes
[i
] ? I
: N
;
317 /* (match_test WHATEVER) is completely indeterminate. */
318 memset (codes
, I
, NUM_RTX_CODE
);
322 error_with_line (lineno
,
323 "'%s' cannot be used in predicates or constraints",
324 GET_RTX_NAME (GET_CODE (exp
)));
325 memset (codes
, I
, NUM_RTX_CODE
);
334 /* Return true if NAME is a valid predicate name. */
337 valid_predicate_name_p (const char *name
)
341 if (!ISALPHA (name
[0]) && name
[0] != '_')
343 for (p
= name
+ 1; *p
; p
++)
344 if (!ISALNUM (*p
) && *p
!= '_')
349 /* Process define_predicate directive DESC, which appears on line number
350 LINENO. Compute the set of codes that can be matched, and record this
351 as a known predicate. */
354 process_define_predicate (rtx desc
, int lineno
)
356 struct pred_data
*pred
;
357 char codes
[NUM_RTX_CODE
];
360 if (!valid_predicate_name_p (XSTR (desc
, 0)))
362 error_with_line (lineno
,
363 "%s: predicate name must be a valid C function name",
368 pred
= XCNEW (struct pred_data
);
369 pred
->name
= XSTR (desc
, 0);
370 pred
->exp
= XEXP (desc
, 1);
371 pred
->c_block
= XSTR (desc
, 2);
372 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
373 pred
->special
= true;
375 compute_test_codes (XEXP (desc
, 1), lineno
, codes
);
377 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
379 add_predicate_code (pred
, (enum rtx_code
) i
);
381 add_predicate (pred
);
387 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
390 static struct queue_elem
*
391 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
392 const char *filename
, int lineno
)
394 struct queue_elem
*e
= XNEW (struct queue_elem
);
396 e
->filename
= filename
;
401 *list_tail
= &e
->next
;
405 /* Remove element ELEM from QUEUE. */
407 remove_from_queue (struct queue_elem
*elem
, struct queue_elem
**queue
)
409 struct queue_elem
*prev
, *e
;
411 for (e
= *queue
; e
; e
= e
->next
)
421 prev
->next
= elem
->next
;
426 /* Build a define_attr for an binary attribute with name NAME and
427 possible values "yes" and "no", and queue it. */
429 add_define_attr (const char *name
)
431 struct queue_elem
*e
= XNEW (struct queue_elem
);
432 rtx t1
= rtx_alloc (DEFINE_ATTR
);
434 XSTR (t1
, 1) = "no,yes";
435 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
436 XSTR (XEXP (t1
, 2), 0) = "yes";
438 e
->filename
= "built-in";
440 e
->next
= define_attr_queue
;
441 define_attr_queue
= e
;
445 /* Recursively remove constraints from an rtx. */
448 remove_constraints (rtx part
)
451 const char *format_ptr
;
456 if (GET_CODE (part
) == MATCH_OPERAND
)
458 else if (GET_CODE (part
) == MATCH_SCRATCH
)
461 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
463 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
464 switch (*format_ptr
++)
468 remove_constraints (XEXP (part
, i
));
471 if (XVEC (part
, i
) != NULL
)
472 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
473 remove_constraints (XVECEXP (part
, i
, j
));
478 /* Process a top level rtx in some way, queuing as appropriate. */
481 process_rtx (rtx desc
, int lineno
)
483 switch (GET_CODE (desc
))
486 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
489 case DEFINE_COND_EXEC
:
490 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
494 queue_pattern (desc
, &define_subst_tail
, read_md_filename
, lineno
);
497 case DEFINE_SUBST_ATTR
:
498 queue_pattern (desc
, &define_subst_attr_tail
, read_md_filename
, lineno
);
502 case DEFINE_ENUM_ATTR
:
503 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
506 case DEFINE_PREDICATE
:
507 case DEFINE_SPECIAL_PREDICATE
:
508 process_define_predicate (desc
, lineno
);
511 case DEFINE_CONSTRAINT
:
512 case DEFINE_REGISTER_CONSTRAINT
:
513 case DEFINE_MEMORY_CONSTRAINT
:
514 case DEFINE_ADDRESS_CONSTRAINT
:
515 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
518 case DEFINE_INSN_AND_SPLIT
:
520 const char *split_cond
;
524 struct queue_elem
*insn_elem
;
525 struct queue_elem
*split_elem
;
527 /* Create a split with values from the insn_and_split. */
528 split
= rtx_alloc (DEFINE_SPLIT
);
530 i
= XVECLEN (desc
, 1);
531 XVEC (split
, 0) = rtvec_alloc (i
);
534 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
535 remove_constraints (XVECEXP (split
, 0, i
));
538 /* If the split condition starts with "&&", append it to the
539 insn condition to create the new split condition. */
540 split_cond
= XSTR (desc
, 4);
541 if (split_cond
[0] == '&' && split_cond
[1] == '&')
543 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
544 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
546 XSTR (split
, 1) = split_cond
;
547 XVEC (split
, 2) = XVEC (desc
, 5);
548 XSTR (split
, 3) = XSTR (desc
, 6);
550 /* Fix up the DEFINE_INSN. */
551 attr
= XVEC (desc
, 7);
552 PUT_CODE (desc
, DEFINE_INSN
);
553 XVEC (desc
, 4) = attr
;
557 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
560 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
561 insn_elem
->split
= split_elem
;
566 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
571 /* Return true if attribute PREDICABLE is true for ELEM, which holds
575 is_predicable (struct queue_elem
*elem
)
577 rtvec vec
= XVEC (elem
->data
, 4);
582 return predicable_default
;
584 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
586 rtx sub
= RTVEC_ELT (vec
, i
);
587 switch (GET_CODE (sub
))
590 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
592 value
= XSTR (sub
, 1);
597 case SET_ATTR_ALTERNATIVE
:
598 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
600 error_with_line (elem
->lineno
,
601 "multiple alternatives for `predicable'");
607 if (GET_CODE (SET_DEST (sub
)) != ATTR
608 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
611 if (GET_CODE (sub
) == CONST_STRING
)
613 value
= XSTR (sub
, 0);
617 /* ??? It would be possible to handle this if we really tried.
618 It's not easy though, and I'm not going to bother until it
619 really proves necessary. */
620 error_with_line (elem
->lineno
,
621 "non-constant value for `predicable'");
629 return predicable_default
;
632 /* Find out which value we're looking at. Multiple alternatives means at
633 least one is predicable. */
634 if (strchr (value
, ',') != NULL
)
636 if (strcmp (value
, predicable_true
) == 0)
638 if (strcmp (value
, predicable_false
) == 0)
641 error_with_line (elem
->lineno
,
642 "unknown value `%s' for `predicable' attribute", value
);
646 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
648 change_subst_attribute (struct queue_elem
*elem
,
649 struct queue_elem
*subst_elem
,
650 const char *new_value
)
652 rtvec attrs_vec
= XVEC (elem
->data
, 4);
653 const char *subst_name
= XSTR (subst_elem
->data
, 0);
659 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
661 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
662 if (GET_CODE (cur_attr
) != SET_ATTR
)
664 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
666 XSTR (cur_attr
, 1) = new_value
;
672 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
673 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
674 DEFINE_SUBST isn't applied to patterns without such attribute. In other
675 words, we suppose the default value of the attribute to be 'no' since it is
676 always generated automaticaly in read-rtl.c. */
678 has_subst_attribute (struct queue_elem
*elem
, struct queue_elem
*subst_elem
)
680 rtvec attrs_vec
= XVEC (elem
->data
, 4);
681 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
687 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
689 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
690 switch (GET_CODE (cur_attr
))
693 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
695 value
= XSTR (cur_attr
, 1);
701 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
702 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
704 cur_attr
= SET_SRC (cur_attr
);
705 if (GET_CODE (cur_attr
) == CONST_STRING
)
707 value
= XSTR (cur_attr
, 0);
711 /* Only (set_attr "subst" "yes/no") and
712 (set (attr "subst" (const_string "yes/no")))
713 are currently allowed. */
714 error_with_line (elem
->lineno
,
715 "unsupported value for `%s'", subst_name
);
718 case SET_ATTR_ALTERNATIVE
:
719 error_with_line (elem
->lineno
,
720 "%s: `set_attr_alternative' is unsupported by "
722 XSTR (elem
->data
, 0));
734 if (strcmp (value
, subst_true
) == 0)
736 if (strcmp (value
, subst_false
) == 0)
739 error_with_line (elem
->lineno
,
740 "unknown value `%s' for `%s' attribute", value
, subst_name
);
744 /* Compare RTL-template of original define_insn X to input RTL-template of
745 define_subst PT. Return 1 if the templates match, 0 otherwise.
746 During the comparison, the routine also fills global_array OPERAND_DATA. */
748 subst_pattern_match (rtx x
, rtx pt
, int lineno
)
750 RTX_CODE code
, code_pt
;
752 const char *fmt
, *pred_name
;
755 code_pt
= GET_CODE (pt
);
757 if (code_pt
== MATCH_OPERAND
)
759 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
760 always accept them. */
761 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
762 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
763 return false; /* Modes don't match. */
765 if (code
== MATCH_OPERAND
)
767 pred_name
= XSTR (pt
, 1);
768 if (pred_name
[0] != 0)
770 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
771 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
772 return false; /* Predicates don't match. */
776 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
777 operand_data
[XINT (pt
, 0)] = x
;
781 if (code_pt
== MATCH_OPERATOR
)
783 int x_vecexp_pos
= -1;
786 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
789 /* In case X is also match_operator, compare predicates. */
790 if (code
== MATCH_OPERATOR
)
792 pred_name
= XSTR (pt
, 1);
793 if (pred_name
[0] != 0)
795 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
796 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
802 MATCH_OPERATOR in input template could match in original template
803 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
804 In the first case operands are at (XVECEXP (x, 2, j)), in the second
805 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
806 X_VECEXP_POS variable shows, where to look for these operands. */
808 || code
== UNSPEC_VOLATILE
)
810 else if (code
== MATCH_OPERATOR
)
815 /* MATCH_OPERATOR or UNSPEC case. */
816 if (x_vecexp_pos
>= 0)
818 /* Compare operands number in X and PT. */
819 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
821 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
822 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
823 XVECEXP (pt
, 2, j
), lineno
))
827 /* Ordinary operator. */
830 /* Compare operands number in X and PT.
831 We count operands differently for X and PT since we compare
832 an operator (with operands directly in RTX) and MATCH_OPERATOR
833 (that has a vector with operands). */
834 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
836 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
837 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), lineno
))
841 /* Store the operand to OPERAND_DATA array. */
842 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
843 operand_data
[XINT (pt
, 0)] = x
;
847 if (code_pt
== MATCH_PAR_DUP
848 || code_pt
== MATCH_DUP
849 || code_pt
== MATCH_OP_DUP
850 || code_pt
== MATCH_SCRATCH
851 || code_pt
== MATCH_PARALLEL
)
853 /* Currently interface for these constructions isn't defined -
854 probably they aren't needed in input template of define_subst at all.
855 So, for now their usage in define_subst is forbidden. */
856 error_with_line (lineno
, "%s cannot be used in define_subst",
857 GET_RTX_NAME (code_pt
));
860 gcc_assert (code
!= MATCH_PAR_DUP
861 && code_pt
!= MATCH_DUP
862 && code_pt
!= MATCH_OP_DUP
863 && code_pt
!= MATCH_SCRATCH
864 && code_pt
!= MATCH_PARALLEL
865 && code_pt
!= MATCH_OPERAND
866 && code_pt
!= MATCH_OPERATOR
);
867 /* If PT is none of the handled above, then we match only expressions with
868 the same code in X. */
872 fmt
= GET_RTX_FORMAT (code_pt
);
873 len
= GET_RTX_LENGTH (code_pt
);
875 for (i
= 0; i
< len
; i
++)
882 case 'i': case 'r': case 'w': case 's':
886 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), lineno
))
891 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
893 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
894 if (!subst_pattern_match (XVECEXP (x
, i
, j
), XVECEXP (pt
, i
, j
),
907 /* Examine the attribute "predicable"; discover its boolean values
911 identify_predicable_attribute (void)
913 struct queue_elem
*elem
;
914 char *p_true
, *p_false
;
917 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
918 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
919 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
922 error_with_line (define_cond_exec_queue
->lineno
,
923 "attribute `predicable' not defined");
927 value
= XSTR (elem
->data
, 1);
928 p_false
= xstrdup (value
);
929 p_true
= strchr (p_false
, ',');
930 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
932 error_with_line (elem
->lineno
, "attribute `predicable' is not a boolean");
938 predicable_true
= p_true
;
939 predicable_false
= p_false
;
941 switch (GET_CODE (XEXP (elem
->data
, 2)))
944 value
= XSTR (XEXP (elem
->data
, 2), 0);
948 error_with_line (elem
->lineno
, "attribute `predicable' cannot be const");
953 error_with_line (elem
->lineno
,
954 "attribute `predicable' must have a constant default");
959 if (strcmp (value
, p_true
) == 0)
960 predicable_default
= 1;
961 else if (strcmp (value
, p_false
) == 0)
962 predicable_default
= 0;
965 error_with_line (elem
->lineno
,
966 "unknown value `%s' for `predicable' attribute", value
);
971 /* Return the number of alternatives in constraint S. */
974 n_alternatives (const char *s
)
985 /* The routine scans rtl PATTERN, find match_operand in it and counts
986 number of alternatives. If PATTERN contains several match_operands
987 with different number of alternatives, error is emitted, and the
988 routine returns 0. If all match_operands in PATTERN have the same
989 number of alternatives, it's stored in N_ALT, and the routine returns 1.
990 Argument LINENO is used in when the error is emitted. */
992 get_alternatives_number (rtx pattern
, int *n_alt
, int lineno
)
1001 code
= GET_CODE (pattern
);
1005 i
= n_alternatives (XSTR (pattern
, 2));
1006 /* n_alternatives returns 1 if constraint string is empty -
1007 here we fix it up. */
1008 if (!*(XSTR (pattern
, 2)))
1013 else if (i
&& i
!= *n_alt
)
1015 error_with_line (lineno
,
1016 "wrong number of alternatives in operand %d",
1025 fmt
= GET_RTX_FORMAT (code
);
1026 len
= GET_RTX_LENGTH (code
);
1027 for (i
= 0; i
< len
; i
++)
1032 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, lineno
))
1037 if (XVEC (pattern
, i
) == NULL
)
1041 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1042 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
),
1047 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1057 /* Determine how many alternatives there are in INSN, and how many
1061 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1067 code
= GET_CODE (pattern
);
1071 i
= n_alternatives (XSTR (pattern
, 2));
1072 *palt
= (i
> *palt
? i
: *palt
);
1075 case MATCH_OPERATOR
:
1077 case MATCH_PARALLEL
:
1078 i
= XINT (pattern
, 0);
1087 fmt
= GET_RTX_FORMAT (code
);
1088 len
= GET_RTX_LENGTH (code
);
1089 for (i
= 0; i
< len
; i
++)
1094 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1098 if (XVEC (pattern
, i
) == NULL
)
1102 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1103 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1106 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1116 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
1122 code
= GET_CODE (pattern
);
1127 const char *c
= XSTR (pattern
, 2);
1129 if (n_alternatives (c
) != 1)
1131 error_with_line (lineno
, "too many alternatives for operand %d",
1136 /* Replicate C as needed to fill out ALT alternatives. */
1137 if (c
&& *c
&& alt
> 1)
1139 size_t c_len
= strlen (c
);
1140 size_t len
= alt
* (c_len
+ 1);
1141 char *new_c
= XNEWVEC (char, len
);
1143 memcpy (new_c
, c
, c_len
);
1144 for (i
= 1; i
< alt
; ++i
)
1146 new_c
[i
* (c_len
+ 1) - 1] = ',';
1147 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1149 new_c
[len
- 1] = '\0';
1150 XSTR (pattern
, 2) = new_c
;
1155 case MATCH_OPERATOR
:
1157 case MATCH_PARALLEL
:
1158 XINT (pattern
, 0) += max_op
;
1165 fmt
= GET_RTX_FORMAT (code
);
1166 len
= GET_RTX_LENGTH (code
);
1167 for (i
= 0; i
< len
; i
++)
1174 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
1181 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1183 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1184 alt
, max_op
, lineno
);
1190 case 'i': case 'r': case 'w': case '0': case 's':
1201 /* Duplicate constraints in PATTERN. If pattern is from original
1202 rtl-template, we need to duplicate each alternative - for that we
1203 need to use duplicate_each_alternative () as a functor ALTER.
1204 If pattern is from output-pattern of define_subst, we need to
1205 duplicate constraints in another way - with duplicate_alternatives ().
1206 N_DUP is multiplication factor. */
1208 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1214 code
= GET_CODE (pattern
);
1218 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1225 fmt
= GET_RTX_FORMAT (code
);
1226 len
= GET_RTX_LENGTH (code
);
1227 for (i
= 0; i
< len
; i
++)
1234 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1240 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1242 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1248 case 'i': case 'r': case 'w': case '0': case 's':
1260 alter_test_for_insn (struct queue_elem
*ce_elem
,
1261 struct queue_elem
*insn_elem
)
1263 return join_c_conditions (XSTR (ce_elem
->data
, 1),
1264 XSTR (insn_elem
->data
, 2));
1267 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1268 to take "ce_enabled" into account. Return the new expression. */
1270 modify_attr_enabled_ce (rtx val
)
1274 eq_attr
= rtx_alloc (EQ_ATTR
);
1275 ite
= rtx_alloc (IF_THEN_ELSE
);
1276 str
= rtx_alloc (CONST_STRING
);
1278 XSTR (eq_attr
, 0) = "ce_enabled";
1279 XSTR (eq_attr
, 1) = "yes";
1280 XSTR (str
, 0) = "no";
1281 XEXP (ite
, 0) = eq_attr
;
1282 XEXP (ite
, 1) = val
;
1283 XEXP (ite
, 2) = str
;
1288 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1289 from a define_insn pattern. We must modify the "predicable" attribute
1290 to be named "ce_enabled", and also change any "enabled" attribute that's
1291 present so that it takes ce_enabled into account.
1292 We rely on the fact that INSN was created with copy_rtx, and modify data
1296 alter_attrs_for_insn (rtx insn
)
1298 static bool global_changes_made
= false;
1299 rtvec vec
= XVEC (insn
, 4);
1303 int predicable_idx
= -1;
1304 int enabled_idx
= -1;
1310 num_elem
= GET_NUM_ELEM (vec
);
1311 for (i
= num_elem
- 1; i
>= 0; --i
)
1313 rtx sub
= RTVEC_ELT (vec
, i
);
1314 switch (GET_CODE (sub
))
1317 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1320 XSTR (sub
, 0) = "ce_enabled";
1322 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1325 XSTR (sub
, 0) = "nonce_enabled";
1329 case SET_ATTR_ALTERNATIVE
:
1330 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1331 /* We already give an error elsewhere. */
1333 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1336 XSTR (sub
, 0) = "nonce_enabled";
1341 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1343 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1345 sub
= SET_SRC (sub
);
1346 if (GET_CODE (sub
) == CONST_STRING
)
1349 XSTR (sub
, 0) = "ce_enabled";
1352 /* We already give an error elsewhere. */
1356 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1359 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1367 if (predicable_idx
== -1)
1370 if (!global_changes_made
)
1372 struct queue_elem
*elem
;
1374 global_changes_made
= true;
1375 add_define_attr ("ce_enabled");
1376 add_define_attr ("nonce_enabled");
1378 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1379 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1381 XEXP (elem
->data
, 2)
1382 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1385 if (enabled_idx
== -1)
1388 new_vec
= rtvec_alloc (num_elem
+ 1);
1389 for (i
= 0; i
< num_elem
; i
++)
1390 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1391 val
= rtx_alloc (IF_THEN_ELSE
);
1392 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1393 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1394 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1395 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1396 XSTR (XEXP (val
, 0), 1) = "yes";
1397 XSTR (XEXP (val
, 1), 0) = "yes";
1398 XSTR (XEXP (val
, 2), 0) = "no";
1399 set
= rtx_alloc (SET
);
1400 SET_DEST (set
) = rtx_alloc (ATTR
);
1401 XSTR (SET_DEST (set
), 0) = "enabled";
1402 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1403 RTVEC_ELT (new_vec
, i
) = set
;
1404 XVEC (insn
, 4) = new_vec
;
1407 /* As number of constraints is changed after define_subst, we need to
1408 process attributes as well - we need to duplicate them the same way
1409 that we duplicated constraints in original pattern
1410 ELEM is a queue element, containing our rtl-template,
1411 N_DUP - multiplication factor. */
1413 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1415 rtvec vec
= XVEC (elem
->data
, 4);
1419 if (n_dup
< 2 || ! vec
)
1422 num_elem
= GET_NUM_ELEM (vec
);
1423 for (i
= num_elem
- 1; i
>= 0; --i
)
1425 rtx sub
= RTVEC_ELT (vec
, i
);
1426 switch (GET_CODE (sub
))
1429 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1430 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1433 case SET_ATTR_ALTERNATIVE
:
1435 error_with_line (elem
->lineno
,
1436 "%s: `define_subst' does not support attributes "
1437 "assigned by `set' and `set_attr_alternative'",
1438 XSTR (elem
->data
, 0));
1447 /* Adjust all of the operand numbers in SRC to match the shift they'll
1448 get from an operand displacement of DISP. Return a pointer after the
1452 shift_output_template (char *dest
, const char *src
, int disp
)
1461 if (ISDIGIT ((unsigned char) c
))
1463 else if (ISALPHA (c
))
1476 alter_output_for_insn (struct queue_elem
*ce_elem
,
1477 struct queue_elem
*insn_elem
,
1478 int alt
, int max_op
)
1480 const char *ce_out
, *insn_out
;
1482 size_t len
, ce_len
, insn_len
;
1484 /* ??? Could coordinate with genoutput to not duplicate code here. */
1486 ce_out
= XSTR (ce_elem
->data
, 2);
1487 insn_out
= XTMPL (insn_elem
->data
, 3);
1488 if (!ce_out
|| *ce_out
== '\0')
1491 ce_len
= strlen (ce_out
);
1492 insn_len
= strlen (insn_out
);
1494 if (*insn_out
== '*')
1495 /* You must take care of the predicate yourself. */
1498 if (*insn_out
== '@')
1500 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1501 p
= result
= XNEWVEC (char, len
);
1507 while (ISSPACE ((unsigned char) *insn_out
));
1509 if (*insn_out
!= '#')
1511 p
= shift_output_template (p
, ce_out
, max_op
);
1517 while (*insn_out
&& *insn_out
!= '\n');
1524 len
= ce_len
+ 1 + insn_len
+ 1;
1525 result
= XNEWVEC (char, len
);
1527 p
= shift_output_template (result
, ce_out
, max_op
);
1529 memcpy (p
, insn_out
, insn_len
+ 1);
1535 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1536 string, duplicated N_DUP times. */
1539 duplicate_alternatives (const char * str
, int n_dup
)
1541 int i
, len
, new_len
;
1548 while (ISSPACE (*str
))
1556 new_len
= (len
+ 1) * n_dup
;
1558 sp
= result
= XNEWVEC (char, new_len
);
1560 /* Global modifier characters mustn't be duplicated: skip if found. */
1561 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1567 /* Copy original constraints N_DUP times. */
1568 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1570 memcpy (sp
, cp
, len
);
1571 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1577 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1578 each alternative from the original string is duplicated N_DUP times. */
1580 duplicate_each_alternative (const char * str
, int n_dup
)
1582 int i
, len
, new_len
;
1583 char *result
, *sp
, *ep
, *cp
;
1588 while (ISSPACE (*str
))
1596 new_len
= (strlen (cp
) + 1) * n_dup
;
1598 sp
= result
= XNEWVEC (char, new_len
);
1600 /* Global modifier characters mustn't be duplicated: skip if found. */
1601 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1606 if ((ep
= strchr (cp
, ',')) != NULL
)
1610 /* Copy a constraint N_DUP times. */
1611 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1613 memcpy (sp
, cp
, len
);
1614 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1624 /* Alter the output of INSN whose pattern was modified by
1625 DEFINE_SUBST. We must replicate output strings according
1626 to the new number of alternatives ALT in substituted pattern.
1627 If ALT equals 1, output has one alternative or defined by C
1628 code, then output is returned without any changes. */
1631 alter_output_for_subst_insn (rtx insn
, int alt
)
1633 const char *insn_out
, *sp
;
1634 char *old_out
, *new_out
, *cp
;
1637 insn_out
= XTMPL (insn
, 3);
1639 if (alt
< 2 || *insn_out
== '*' || *insn_out
!= '@')
1642 old_out
= XNEWVEC (char, strlen (insn_out
)),
1645 while (ISSPACE (*sp
) || *sp
== '@')
1649 old_out
[i
++] = *sp
++;
1651 new_len
= alt
* (i
+ 1) + 1;
1653 new_out
= XNEWVEC (char, new_len
);
1656 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= i
+ 1)
1658 memcpy (cp
, old_out
, i
);
1659 *(cp
+i
) = (j
== alt
- 1) ? '\0' : '\n';
1665 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1668 process_one_cond_exec (struct queue_elem
*ce_elem
)
1670 struct queue_elem
*insn_elem
;
1671 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1673 int alternatives
, max_operand
;
1674 rtx pred
, insn
, pattern
, split
;
1678 if (! is_predicable (insn_elem
))
1683 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1686 if (XVECLEN (ce_elem
->data
, 0) != 1)
1688 error_with_line (ce_elem
->lineno
, "too many patterns in predicate");
1692 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1693 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1698 /* Construct a new pattern for the new insn. */
1699 insn
= copy_rtx (insn_elem
->data
);
1700 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1701 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1702 XSTR (insn
, 0) = new_name
;
1703 pattern
= rtx_alloc (COND_EXEC
);
1704 XEXP (pattern
, 0) = pred
;
1705 if (XVECLEN (insn
, 1) == 1)
1707 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
1708 XVECEXP (insn
, 1, 0) = pattern
;
1709 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
1713 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1714 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
1715 XVEC (insn
, 1) = rtvec_alloc (1);
1716 XVECEXP (insn
, 1, 0) = pattern
;
1719 if (XVEC (ce_elem
->data
, 3) != NULL
)
1721 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1722 + XVECLEN (ce_elem
->data
, 3));
1725 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1726 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1728 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1729 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1731 XVEC (insn
, 4) = attributes
;
1734 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1735 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1736 alternatives
, max_operand
);
1737 alter_attrs_for_insn (insn
);
1739 /* Put the new pattern on the `other' list so that it
1740 (a) is not reprocessed by other define_cond_exec patterns
1741 (b) appears after all normal define_insn patterns.
1743 ??? B is debatable. If one has normal insns that match
1744 cond_exec patterns, they will be preferred over these
1745 generated patterns. Whether this matters in practice, or if
1746 it's a good thing, or whether we should thread these new
1747 patterns into the define_insn chain just after their generator
1748 is something we'll have to experiment with. */
1750 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
1753 if (!insn_elem
->split
)
1756 /* If the original insn came from a define_insn_and_split,
1757 generate a new split to handle the predicated insn. */
1758 split
= copy_rtx (insn_elem
->split
->data
);
1759 /* Predicate the pattern matched by the split. */
1760 pattern
= rtx_alloc (COND_EXEC
);
1761 XEXP (pattern
, 0) = pred
;
1762 if (XVECLEN (split
, 0) == 1)
1764 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
1765 XVECEXP (split
, 0, 0) = pattern
;
1766 PUT_NUM_ELEM (XVEC (split
, 0), 1);
1770 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1771 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
1772 XVEC (split
, 0) = rtvec_alloc (1);
1773 XVECEXP (split
, 0, 0) = pattern
;
1775 /* Predicate all of the insns generated by the split. */
1776 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1778 pattern
= rtx_alloc (COND_EXEC
);
1779 XEXP (pattern
, 0) = pred
;
1780 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1781 XVECEXP (split
, 2, i
) = pattern
;
1783 /* Add the new split to the queue. */
1784 queue_pattern (split
, &other_tail
, read_md_filename
,
1785 insn_elem
->split
->lineno
);
1789 /* Try to apply define_substs to the given ELEM.
1790 Only define_substs, specified via attributes would be applied.
1791 If attribute, requiring define_subst, is set, but no define_subst
1792 was applied, ELEM would be deleted. */
1795 process_substs_on_one_elem (struct queue_elem
*elem
,
1796 struct queue_elem
*queue
)
1798 struct queue_elem
*subst_elem
;
1799 int i
, j
, patterns_match
;
1801 for (subst_elem
= define_subst_queue
;
1802 subst_elem
; subst_elem
= subst_elem
->next
)
1804 int alternatives
, alternatives_subst
;
1806 rtvec subst_pattern_vec
;
1808 if (!has_subst_attribute (elem
, subst_elem
))
1811 /* Compare original rtl-pattern from define_insn with input
1812 pattern from define_subst.
1813 Also, check if numbers of alternatives are the same in all
1815 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1819 alternatives_subst
= -1;
1820 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1822 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1823 XVECEXP (subst_elem
->data
, 1, j
),
1824 subst_elem
->lineno
))
1830 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1831 &alternatives
, subst_elem
->lineno
))
1838 /* Check if numbers of alternatives are the same in all
1839 match_operands in output template of define_subst. */
1840 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1842 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1843 &alternatives_subst
,
1844 subst_elem
->lineno
))
1851 if (!patterns_match
)
1854 /* Clear array in which we save occupied indexes of operands. */
1855 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1857 /* Create a pattern, based on the output one from define_subst. */
1858 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1859 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1861 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1863 /* Duplicate constraints in substitute-pattern. */
1864 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1865 duplicate_each_alternative
);
1867 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1869 /* Substitute match_dup and match_op_dup in the new pattern and
1870 duplicate constraints. */
1871 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1872 alternatives_subst
);
1874 replace_duplicating_operands_in_pattern (subst_pattern
);
1876 /* We don't need any constraints in DEFINE_EXPAND. */
1877 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1878 remove_constraints (subst_pattern
);
1880 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1882 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1884 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1885 match_operand_entries_in_pattern
[i
] = NULL
;
1887 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1889 XTMPL (elem
->data
, 3) =
1890 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1891 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1894 /* Recalculate condition, joining conditions from original and
1895 DEFINE_SUBST input patterns. */
1896 XSTR (elem
->data
, 2) = join_c_conditions (XSTR (subst_elem
->data
, 2),
1897 XSTR (elem
->data
, 2));
1898 /* Mark that subst was applied by changing attribute from "yes"
1900 change_subst_attribute (elem
, subst_elem
, subst_false
);
1903 /* If ELEM contains a subst attribute with value "yes", then we
1904 expected that a subst would be applied, but it wasn't - so,
1905 we need to remove that elementto avoid duplicating. */
1906 for (subst_elem
= define_subst_queue
;
1907 subst_elem
; subst_elem
= subst_elem
->next
)
1909 if (has_subst_attribute (elem
, subst_elem
))
1911 remove_from_queue (elem
, &queue
);
1917 /* This is a subroutine of mark_operands_used_in_match_dup.
1918 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1920 mark_operands_from_match_dup (rtx pattern
)
1923 int i
, j
, len
, opno
;
1925 if (GET_CODE (pattern
) == MATCH_OPERAND
1926 || GET_CODE (pattern
) == MATCH_OPERATOR
1927 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1929 opno
= XINT (pattern
, 0);
1930 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1931 used_operands_numbers
[opno
] = 1;
1933 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1934 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1935 for (i
= 0; i
< len
; i
++)
1940 mark_operands_from_match_dup (XEXP (pattern
, i
));
1943 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1944 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1950 /* This is a subroutine of adjust_operands_numbers.
1951 It goes through all expressions in PATTERN and when MATCH_DUP is
1952 met, all MATCH_OPERANDs inside it is marked as occupied. The
1953 process of marking is done by routin mark_operands_from_match_dup. */
1955 mark_operands_used_in_match_dup (rtx pattern
)
1958 int i
, j
, len
, opno
;
1960 if (GET_CODE (pattern
) == MATCH_DUP
)
1962 opno
= XINT (pattern
, 0);
1963 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1964 mark_operands_from_match_dup (operand_data
[opno
]);
1967 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1968 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1969 for (i
= 0; i
< len
; i
++)
1974 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1977 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1978 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1984 /* This is subroutine of renumerate_operands_in_pattern.
1985 It finds first not-occupied operand-index. */
1987 find_first_unused_number_of_operand ()
1990 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1991 if (!used_operands_numbers
[i
])
1993 return MAX_OPERANDS
;
1996 /* This is subroutine of adjust_operands_numbers.
1997 It visits all expressions in PATTERN and assigns not-occupied
1998 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2001 renumerate_operands_in_pattern (rtx pattern
)
2005 int i
, j
, len
, new_opno
;
2006 code
= GET_CODE (pattern
);
2008 if (code
== MATCH_OPERAND
2009 || code
== MATCH_OPERATOR
)
2011 new_opno
= find_first_unused_number_of_operand ();
2012 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
2013 XINT (pattern
, 0) = new_opno
;
2014 used_operands_numbers
[new_opno
] = 1;
2017 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2018 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2019 for (i
= 0; i
< len
; i
++)
2024 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2027 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2028 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2034 /* If output pattern of define_subst contains MATCH_DUP, then this
2035 expression would be replaced with the pattern, matched with
2036 MATCH_OPERAND from input pattern. This pattern could contain any
2037 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2038 that a MATCH_OPERAND from output_pattern (if any) would have the
2039 same number, as MATCH_OPERAND from copied pattern. To avoid such
2040 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2041 laying in the output pattern outside of MATCH_DUPs. */
2043 adjust_operands_numbers (rtx pattern
)
2045 mark_operands_used_in_match_dup (pattern
);
2047 renumerate_operands_in_pattern (pattern
);
2052 /* Generate RTL expression
2056 generate_match_dup (int opno
)
2058 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2059 PUT_CODE (return_rtx
, MATCH_DUP
);
2060 XINT (return_rtx
, 0) = opno
;
2064 /* This routine checks all match_operands in PATTERN and if some of
2065 have the same index, it replaces all of them except the first one to
2067 Usually, match_operands with the same indexes are forbidden, but
2068 after define_subst copy an RTL-expression from original template,
2069 indexes of existed and just-copied match_operands could coincide.
2070 To fix it, we replace one of them with match_dup. */
2072 replace_duplicating_operands_in_pattern (rtx pattern
)
2075 int i
, j
, len
, opno
;
2078 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2080 opno
= XINT (pattern
, 0);
2081 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2082 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2084 match_operand_entries_in_pattern
[opno
] = pattern
;
2089 /* Compare predicates before replacing with match_dup. */
2090 if (strcmp (XSTR (pattern
, 1),
2091 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2093 error ("duplicated match_operands with different predicates were"
2097 return generate_match_dup (opno
);
2100 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2101 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2102 for (i
= 0; i
< len
; i
++)
2107 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2109 XEXP (pattern
, i
) = mdup
;
2112 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2115 replace_duplicating_operands_in_pattern (XVECEXP
2118 XVECEXP (pattern
, i
, j
) = mdup
;
2126 /* The routine modifies given input PATTERN of define_subst, replacing
2127 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2128 pattern, whose operands are stored in OPERAND_DATA array.
2129 It also duplicates constraints in operands - constraints from
2130 define_insn operands are duplicated N_SUBST_ALT times, constraints
2131 from define_subst operands are duplicated N_ALT times.
2132 After the duplication, returned output rtl-pattern contains every
2133 combination of input constraints Vs constraints from define_subst
2136 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2140 int i
, j
, len
, opno
;
2142 code
= GET_CODE (pattern
);
2147 opno
= XINT (pattern
, 0);
2149 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2151 if (operand_data
[opno
])
2153 pattern
= copy_rtx (operand_data
[opno
]);
2155 /* Duplicate constraints. */
2156 pattern
= alter_constraints (pattern
, n_subst_alt
,
2157 duplicate_alternatives
);
2165 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2166 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2167 for (i
= 0; i
< len
; i
++)
2172 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2173 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2174 n_alt
, n_subst_alt
);
2177 if (XVEC (pattern
, i
) == NULL
)
2180 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2181 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2182 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2183 n_alt
, n_subst_alt
);
2186 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2196 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2197 patterns appropriately. */
2200 process_define_cond_exec (void)
2202 struct queue_elem
*elem
;
2204 identify_predicable_attribute ();
2208 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2209 process_one_cond_exec (elem
);
2212 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2213 DEFINE_EXPAND patterns appropriately. */
2216 process_define_subst (void)
2218 struct queue_elem
*elem
, *elem_attr
;
2220 /* Check if each define_subst has corresponding define_subst_attr. */
2221 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2223 for (elem_attr
= define_subst_attr_queue
;
2225 elem_attr
= elem_attr
->next
)
2226 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2229 error_with_line (elem
->lineno
,
2230 "%s: `define_subst' must have at least one "
2231 "corresponding `define_subst_attr'",
2232 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 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2805 {"register_operand", false, false, {SUBREG
, REG
}},
2806 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2807 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2808 {"immediate_operand", false, true, {UNKNOWN
}},
2809 {"const_int_operand", false, false, {CONST_INT
}},
2810 #if TARGET_SUPPORTS_WIDE_INT
2811 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2812 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2814 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2816 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2817 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2818 {"push_operand", false, false, {MEM
}},
2819 {"pop_operand", false, false, {MEM
}},
2820 {"memory_operand", false, false, {SUBREG
, MEM
}},
2821 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2822 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2824 LEU
, LTU
, GEU
, GTU
}},
2825 {"comparison_operator", false, false, {EQ
, NE
,
2832 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2834 /* Initialize the table of predicate definitions, starting with
2835 the information we have on generic predicates. */
2838 init_predicate_table (void)
2841 struct pred_data
*pred
;
2843 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2844 eq_struct_pred_data
, 0,
2847 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2849 pred
= XCNEW (struct pred_data
);
2850 pred
->name
= std_preds
[i
].name
;
2851 pred
->special
= std_preds
[i
].special
;
2853 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2854 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2856 if (std_preds
[i
].allows_const_p
)
2857 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2858 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2859 add_predicate_code (pred
, (enum rtx_code
) j
);
2861 add_predicate (pred
);
2865 /* These functions allow linkage with print-rtl.c. Also, some generators
2866 like to annotate their output with insn names. */
2868 /* Holds an array of names indexed by insn_code_number. */
2869 static char **insn_name_ptr
= 0;
2870 static int insn_name_ptr_size
= 0;
2873 get_insn_name (int code
)
2875 if (code
< insn_name_ptr_size
)
2876 return insn_name_ptr
[code
];
2882 record_insn_name (int code
, const char *name
)
2884 static const char *last_real_name
= "insn";
2885 static int last_real_code
= 0;
2888 if (insn_name_ptr_size
<= code
)
2891 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2892 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2893 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2894 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2895 insn_name_ptr_size
= new_size
;
2898 if (!name
|| name
[0] == '\0')
2900 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2901 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2905 last_real_name
= new_name
= xstrdup (name
);
2906 last_real_code
= code
;
2909 insn_name_ptr
[code
] = new_name
;
2912 /* Make STATS describe the operands that appear in rtx X. */
2915 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2925 code
= GET_CODE (x
);
2929 case MATCH_OPERATOR
:
2930 case MATCH_PARALLEL
:
2931 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
2938 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
2942 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
2949 fmt
= GET_RTX_FORMAT (code
);
2950 len
= GET_RTX_LENGTH (code
);
2951 for (i
= 0; i
< len
; i
++)
2953 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
2954 get_pattern_stats_1 (stats
, XEXP (x
, i
));
2955 else if (fmt
[i
] == 'E')
2958 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2959 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
2964 /* Make STATS describe the operands that appear in instruction pattern
2968 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
2972 stats
->max_opno
= -1;
2973 stats
->max_dup_opno
= -1;
2974 stats
->max_scratch_opno
= -1;
2975 stats
->num_dups
= 0;
2977 len
= GET_NUM_ELEM (pattern
);
2978 for (i
= 0; i
< len
; i
++)
2979 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
2981 stats
->num_generator_args
= stats
->max_opno
+ 1;
2982 stats
->num_insn_operands
= MAX (stats
->max_opno
,
2983 stats
->max_scratch_opno
) + 1;
2984 stats
->num_operand_vars
= MAX (stats
->max_opno
,
2985 MAX (stats
->max_dup_opno
,
2986 stats
->max_scratch_opno
)) + 1;