1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "gensupport.h"
31 #define MAX_OPERANDS 40
33 static rtx operand_data
[MAX_OPERANDS
];
34 static rtx match_operand_entries_in_pattern
[MAX_OPERANDS
];
35 static char used_operands_numbers
[MAX_OPERANDS
];
38 /* In case some macros used by files we include need it, define this here. */
43 static struct obstack obstack
;
44 struct obstack
*rtl_obstack
= &obstack
;
46 /* Counter for named patterns and INSN_CODEs. */
47 static int insn_sequence_num
;
49 /* Counter for define_splits. */
50 static int split_sequence_num
;
52 /* Counter for define_peephole2s. */
53 static int peephole2_sequence_num
;
55 static int predicable_default
;
56 static const char *predicable_true
;
57 static const char *predicable_false
;
59 static const char *subst_true
= "yes";
60 static const char *subst_false
= "no";
62 static htab_t condition_table
;
64 /* We initially queue all patterns, process the define_insn,
65 define_cond_exec and define_subst patterns, then return
66 them one at a time. */
72 struct queue_elem
*next
;
73 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
74 points to the generated DEFINE_SPLIT. */
75 struct queue_elem
*split
;
78 #define MNEMONIC_ATTR_NAME "mnemonic"
79 #define MNEMONIC_HTAB_SIZE 1024
81 static struct queue_elem
*define_attr_queue
;
82 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
83 static struct queue_elem
*define_pred_queue
;
84 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
85 static struct queue_elem
*define_insn_queue
;
86 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
87 static struct queue_elem
*define_cond_exec_queue
;
88 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
89 static struct queue_elem
*define_subst_queue
;
90 static struct queue_elem
**define_subst_tail
= &define_subst_queue
;
91 static struct queue_elem
*other_queue
;
92 static struct queue_elem
**other_tail
= &other_queue
;
93 static struct queue_elem
*define_subst_attr_queue
;
94 static struct queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
96 /* Mapping from DEFINE_* rtxes to their location in the source file. */
97 static hash_map
<rtx
, file_location
> *rtx_locs
;
99 static void remove_constraints (rtx
);
101 static int is_predicable (struct queue_elem
*);
102 static void identify_predicable_attribute (void);
103 static int n_alternatives (const char *);
104 static void collect_insn_data (rtx
, 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 const char * alter_output_for_subst_insn (rtx
, int);
118 static void alter_attrs_for_subst_insn (struct queue_elem
*, int);
119 static void process_substs_on_one_elem (struct queue_elem
*,
120 struct queue_elem
*);
121 static rtx
subst_dup (rtx
, int, int);
122 static void process_define_subst (void);
124 static const char * duplicate_alternatives (const char *, int);
125 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
127 typedef const char * (*constraints_handler_t
) (const char *, int);
128 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
129 static rtx
adjust_operands_numbers (rtx
);
130 static rtx
replace_duplicating_operands_in_pattern (rtx
);
132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
133 the gensupport programs. */
136 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
139 rtx rt
= rtx_alloc (CONST_INT
);
145 /* Return the rtx pattern specified by the list of rtxes in a
146 define_insn or define_split. */
149 add_implicit_parallel (rtvec vec
)
151 if (GET_NUM_ELEM (vec
) == 1)
152 return RTVEC_ELT (vec
, 0);
155 rtx pattern
= rtx_alloc (PARALLEL
);
156 XVEC (pattern
, 0) = vec
;
161 /* Predicate handling.
163 We construct from the machine description a table mapping each
164 predicate to a list of the rtl codes it can possibly match. The
165 function 'maybe_both_true' uses it to deduce that there are no
166 expressions that can be matches by certain pairs of tree nodes.
167 Also, if a predicate can match only one code, we can hardwire that
168 code into the node testing the predicate.
170 Some predicates are flagged as special. validate_pattern will not
171 warn about modeless match_operand expressions if they have a
172 special predicate. Predicates that allow only constants are also
173 treated as special, for this purpose.
175 validate_pattern will warn about predicates that allow non-lvalues
176 when they appear in destination operands.
178 Calculating the set of rtx codes that can possibly be accepted by a
179 predicate expression EXP requires a three-state logic: any given
180 subexpression may definitively accept a code C (Y), definitively
181 reject a code C (N), or may have an indeterminate effect (I). N
182 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
193 We represent Y with 1, N with 0, I with 2. If any code is left in
194 an I state by the complete expression, we must assume that that
195 code can be accepted. */
201 #define TRISTATE_AND(a,b) \
202 ((a) == I ? ((b) == N ? N : I) : \
203 (b) == I ? ((a) == N ? N : I) : \
206 #define TRISTATE_OR(a,b) \
207 ((a) == I ? ((b) == Y ? Y : I) : \
208 (b) == I ? ((a) == Y ? Y : I) : \
211 #define TRISTATE_NOT(a) \
212 ((a) == I ? I : !(a))
214 /* 0 means no warning about that code yet, 1 means warned. */
215 static char did_you_mean_codes
[NUM_RTX_CODE
];
217 /* Recursively calculate the set of rtx codes accepted by the
218 predicate expression EXP, writing the result to CODES. LOC is
219 the .md file location of the directive containing EXP. */
222 compute_test_codes (rtx exp
, file_location loc
, char *codes
)
224 char op0_codes
[NUM_RTX_CODE
];
225 char op1_codes
[NUM_RTX_CODE
];
226 char op2_codes
[NUM_RTX_CODE
];
229 switch (GET_CODE (exp
))
232 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
233 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
234 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
235 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
239 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
240 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
241 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
242 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
245 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
246 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
247 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
251 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
252 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
253 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
254 compute_test_codes (XEXP (exp
, 2), loc
, op2_codes
);
255 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
256 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
257 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
262 /* MATCH_CODE allows a specified list of codes. However, if it
263 does not apply to the top level of the expression, it does not
264 constrain the set of codes for the top level. */
265 if (XSTR (exp
, 1)[0] != '\0')
267 memset (codes
, Y
, NUM_RTX_CODE
);
271 memset (codes
, N
, NUM_RTX_CODE
);
273 const char *next_code
= XSTR (exp
, 0);
276 if (*next_code
== '\0')
278 error_at (loc
, "empty match_code expression");
282 while ((code
= scan_comma_elt (&next_code
)) != 0)
284 size_t n
= next_code
- code
;
287 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
288 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
289 && GET_RTX_NAME (i
)[n
] == '\0')
297 error_at (loc
, "match_code \"%.*s\" matches nothing",
299 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
300 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
301 && GET_RTX_NAME (i
)[n
] == '\0'
302 && !did_you_mean_codes
[i
])
304 did_you_mean_codes
[i
] = 1;
305 message_at (loc
, "(did you mean \"%s\"?)",
314 /* MATCH_OPERAND disallows the set of codes that the named predicate
315 disallows, and is indeterminate for the codes that it does allow. */
317 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
320 error_at (loc
, "reference to unknown predicate '%s'",
324 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
325 codes
[i
] = p
->codes
[i
] ? I
: N
;
331 /* (match_test WHATEVER) is completely indeterminate. */
332 memset (codes
, I
, NUM_RTX_CODE
);
336 error_at (loc
, "'%s' cannot be used in predicates or constraints",
337 GET_RTX_NAME (GET_CODE (exp
)));
338 memset (codes
, I
, NUM_RTX_CODE
);
347 /* Return true if NAME is a valid predicate name. */
350 valid_predicate_name_p (const char *name
)
354 if (!ISALPHA (name
[0]) && name
[0] != '_')
356 for (p
= name
+ 1; *p
; p
++)
357 if (!ISALNUM (*p
) && *p
!= '_')
362 /* Process define_predicate directive DESC, which appears at location LOC.
363 Compute the set of codes that can be matched, and record this as a known
367 process_define_predicate (rtx desc
, file_location loc
)
369 struct pred_data
*pred
;
370 char codes
[NUM_RTX_CODE
];
373 if (!valid_predicate_name_p (XSTR (desc
, 0)))
375 error_at (loc
, "%s: predicate name must be a valid C function name",
380 pred
= XCNEW (struct pred_data
);
381 pred
->name
= XSTR (desc
, 0);
382 pred
->exp
= XEXP (desc
, 1);
383 pred
->c_block
= XSTR (desc
, 2);
384 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
385 pred
->special
= true;
387 compute_test_codes (XEXP (desc
, 1), loc
, codes
);
389 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
391 add_predicate_code (pred
, (enum rtx_code
) i
);
393 add_predicate (pred
);
399 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
402 static struct queue_elem
*
403 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
406 struct queue_elem
*e
= XNEW (struct queue_elem
);
412 *list_tail
= &e
->next
;
416 /* Remove element ELEM from QUEUE. */
418 remove_from_queue (struct queue_elem
*elem
, struct queue_elem
**queue
)
420 struct queue_elem
*prev
, *e
;
422 for (e
= *queue
; e
; e
= e
->next
)
432 prev
->next
= elem
->next
;
437 /* Build a define_attr for an binary attribute with name NAME and
438 possible values "yes" and "no", and queue it. */
440 add_define_attr (const char *name
)
442 struct queue_elem
*e
= XNEW (struct queue_elem
);
443 rtx t1
= rtx_alloc (DEFINE_ATTR
);
445 XSTR (t1
, 1) = "no,yes";
446 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
447 XSTR (XEXP (t1
, 2), 0) = "yes";
449 e
->loc
= file_location ("built-in", -1, -1);
450 e
->next
= define_attr_queue
;
451 define_attr_queue
= e
;
455 /* Recursively remove constraints from an rtx. */
458 remove_constraints (rtx part
)
461 const char *format_ptr
;
466 if (GET_CODE (part
) == MATCH_OPERAND
)
468 else if (GET_CODE (part
) == MATCH_SCRATCH
)
471 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
473 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
474 switch (*format_ptr
++)
478 remove_constraints (XEXP (part
, i
));
481 if (XVEC (part
, i
) != NULL
)
482 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
483 remove_constraints (XVECEXP (part
, i
, j
));
488 /* Process a top level rtx in some way, queuing as appropriate. */
491 process_rtx (rtx desc
, file_location loc
)
493 switch (GET_CODE (desc
))
496 queue_pattern (desc
, &define_insn_tail
, loc
);
499 case DEFINE_COND_EXEC
:
500 queue_pattern (desc
, &define_cond_exec_tail
, loc
);
504 queue_pattern (desc
, &define_subst_tail
, loc
);
507 case DEFINE_SUBST_ATTR
:
508 queue_pattern (desc
, &define_subst_attr_tail
, loc
);
512 case DEFINE_ENUM_ATTR
:
513 queue_pattern (desc
, &define_attr_tail
, loc
);
516 case DEFINE_PREDICATE
:
517 case DEFINE_SPECIAL_PREDICATE
:
518 process_define_predicate (desc
, loc
);
521 case DEFINE_CONSTRAINT
:
522 case DEFINE_REGISTER_CONSTRAINT
:
523 case DEFINE_MEMORY_CONSTRAINT
:
524 case DEFINE_SPECIAL_MEMORY_CONSTRAINT
:
525 case DEFINE_ADDRESS_CONSTRAINT
:
526 queue_pattern (desc
, &define_pred_tail
, loc
);
529 case DEFINE_INSN_AND_SPLIT
:
531 const char *split_cond
;
535 struct queue_elem
*insn_elem
;
536 struct queue_elem
*split_elem
;
538 /* Create a split with values from the insn_and_split. */
539 split
= rtx_alloc (DEFINE_SPLIT
);
541 i
= XVECLEN (desc
, 1);
542 XVEC (split
, 0) = rtvec_alloc (i
);
545 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
546 remove_constraints (XVECEXP (split
, 0, i
));
549 /* If the split condition starts with "&&", append it to the
550 insn condition to create the new split condition. */
551 split_cond
= XSTR (desc
, 4);
552 if (split_cond
[0] == '&' && split_cond
[1] == '&')
554 rtx_reader_ptr
->copy_md_ptr_loc (split_cond
+ 2, split_cond
);
555 split_cond
= rtx_reader_ptr
->join_c_conditions (XSTR (desc
, 2),
558 XSTR (split
, 1) = split_cond
;
559 XVEC (split
, 2) = XVEC (desc
, 5);
560 XSTR (split
, 3) = XSTR (desc
, 6);
562 /* Fix up the DEFINE_INSN. */
563 attr
= XVEC (desc
, 7);
564 PUT_CODE (desc
, DEFINE_INSN
);
565 XVEC (desc
, 4) = attr
;
568 insn_elem
= queue_pattern (desc
, &define_insn_tail
, loc
);
569 split_elem
= queue_pattern (split
, &other_tail
, loc
);
570 insn_elem
->split
= split_elem
;
575 queue_pattern (desc
, &other_tail
, loc
);
580 /* Return true if attribute PREDICABLE is true for ELEM, which holds
584 is_predicable (struct queue_elem
*elem
)
586 rtvec vec
= XVEC (elem
->data
, 4);
591 return predicable_default
;
593 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
595 rtx sub
= RTVEC_ELT (vec
, i
);
596 switch (GET_CODE (sub
))
599 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
601 value
= XSTR (sub
, 1);
606 case SET_ATTR_ALTERNATIVE
:
607 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
609 error_at (elem
->loc
, "multiple alternatives for `predicable'");
615 if (GET_CODE (SET_DEST (sub
)) != ATTR
616 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
619 if (GET_CODE (sub
) == CONST_STRING
)
621 value
= XSTR (sub
, 0);
625 /* ??? It would be possible to handle this if we really tried.
626 It's not easy though, and I'm not going to bother until it
627 really proves necessary. */
628 error_at (elem
->loc
, "non-constant value for `predicable'");
636 return predicable_default
;
639 /* Find out which value we're looking at. Multiple alternatives means at
640 least one is predicable. */
641 if (strchr (value
, ',') != NULL
)
643 if (strcmp (value
, predicable_true
) == 0)
645 if (strcmp (value
, predicable_false
) == 0)
648 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute", value
);
652 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
654 change_subst_attribute (struct queue_elem
*elem
,
655 struct queue_elem
*subst_elem
,
656 const char *new_value
)
658 rtvec attrs_vec
= XVEC (elem
->data
, 4);
659 const char *subst_name
= XSTR (subst_elem
->data
, 0);
665 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
667 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
668 if (GET_CODE (cur_attr
) != SET_ATTR
)
670 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
672 XSTR (cur_attr
, 1) = new_value
;
678 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
679 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
680 DEFINE_SUBST isn't applied to patterns without such attribute. In other
681 words, we suppose the default value of the attribute to be 'no' since it is
682 always generated automaticaly in read-rtl.c. */
684 has_subst_attribute (struct queue_elem
*elem
, struct queue_elem
*subst_elem
)
686 rtvec attrs_vec
= XVEC (elem
->data
, 4);
687 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
693 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
695 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
696 switch (GET_CODE (cur_attr
))
699 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
701 value
= XSTR (cur_attr
, 1);
707 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
708 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
710 cur_attr
= SET_SRC (cur_attr
);
711 if (GET_CODE (cur_attr
) == CONST_STRING
)
713 value
= XSTR (cur_attr
, 0);
717 /* Only (set_attr "subst" "yes/no") and
718 (set (attr "subst" (const_string "yes/no")))
719 are currently allowed. */
720 error_at (elem
->loc
, "unsupported value for `%s'", subst_name
);
723 case SET_ATTR_ALTERNATIVE
:
725 "%s: `set_attr_alternative' is unsupported by "
726 "`define_subst'", XSTR (elem
->data
, 0));
738 if (strcmp (value
, subst_true
) == 0)
740 if (strcmp (value
, subst_false
) == 0)
743 error_at (elem
->loc
, "unknown value `%s' for `%s' attribute",
748 /* Compare RTL-template of original define_insn X to input RTL-template of
749 define_subst PT. Return 1 if the templates match, 0 otherwise.
750 During the comparison, the routine also fills global_array OPERAND_DATA. */
752 subst_pattern_match (rtx x
, rtx pt
, file_location loc
)
754 RTX_CODE code
, code_pt
;
756 const char *fmt
, *pred_name
;
759 code_pt
= GET_CODE (pt
);
761 if (code_pt
== MATCH_OPERAND
)
763 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
764 always accept them. */
765 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
766 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
767 return false; /* Modes don't match. */
769 if (code
== MATCH_OPERAND
)
771 pred_name
= XSTR (pt
, 1);
772 if (pred_name
[0] != 0)
774 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
775 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
776 return false; /* Predicates don't match. */
780 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
781 operand_data
[XINT (pt
, 0)] = x
;
785 if (code_pt
== MATCH_OPERATOR
)
787 int x_vecexp_pos
= -1;
790 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
793 /* In case X is also match_operator, compare predicates. */
794 if (code
== MATCH_OPERATOR
)
796 pred_name
= XSTR (pt
, 1);
797 if (pred_name
[0] != 0)
799 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
800 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
806 MATCH_OPERATOR in input template could match in original template
807 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
808 In the first case operands are at (XVECEXP (x, 2, j)), in the second
809 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
810 X_VECEXP_POS variable shows, where to look for these operands. */
812 || code
== UNSPEC_VOLATILE
)
814 else if (code
== MATCH_OPERATOR
)
819 /* MATCH_OPERATOR or UNSPEC case. */
820 if (x_vecexp_pos
>= 0)
822 /* Compare operands number in X and PT. */
823 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
825 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
826 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
827 XVECEXP (pt
, 2, j
), loc
))
831 /* Ordinary operator. */
834 /* Compare operands number in X and PT.
835 We count operands differently for X and PT since we compare
836 an operator (with operands directly in RTX) and MATCH_OPERATOR
837 (that has a vector with operands). */
838 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
840 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
841 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), loc
))
845 /* Store the operand to OPERAND_DATA array. */
846 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
847 operand_data
[XINT (pt
, 0)] = x
;
851 if (code_pt
== MATCH_PAR_DUP
852 || code_pt
== MATCH_DUP
853 || code_pt
== MATCH_OP_DUP
854 || code_pt
== MATCH_SCRATCH
855 || code_pt
== MATCH_PARALLEL
)
857 /* Currently interface for these constructions isn't defined -
858 probably they aren't needed in input template of define_subst at all.
859 So, for now their usage in define_subst is forbidden. */
860 error_at (loc
, "%s cannot be used in define_subst",
861 GET_RTX_NAME (code_pt
));
864 gcc_assert (code
!= MATCH_PAR_DUP
865 && code_pt
!= MATCH_DUP
866 && code_pt
!= MATCH_OP_DUP
867 && code_pt
!= MATCH_SCRATCH
868 && code_pt
!= MATCH_PARALLEL
869 && code_pt
!= MATCH_OPERAND
870 && code_pt
!= MATCH_OPERATOR
);
871 /* If PT is none of the handled above, then we match only expressions with
872 the same code in X. */
876 fmt
= GET_RTX_FORMAT (code_pt
);
877 len
= GET_RTX_LENGTH (code_pt
);
879 for (i
= 0; i
< len
; i
++)
886 case 'i': case 'r': case 'w': case 's':
890 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), loc
))
895 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
897 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
898 if (!subst_pattern_match (XVECEXP (x
, i
, j
),
899 XVECEXP (pt
, i
, j
), loc
))
911 /* Examine the attribute "predicable"; discover its boolean values
915 identify_predicable_attribute (void)
917 struct queue_elem
*elem
;
918 char *p_true
, *p_false
;
921 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
922 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
923 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
926 error_at (define_cond_exec_queue
->loc
,
927 "attribute `predicable' not defined");
931 value
= XSTR (elem
->data
, 1);
932 p_false
= xstrdup (value
);
933 p_true
= strchr (p_false
, ',');
934 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
936 error_at (elem
->loc
, "attribute `predicable' is not a boolean");
942 predicable_true
= p_true
;
943 predicable_false
= p_false
;
945 switch (GET_CODE (XEXP (elem
->data
, 2)))
948 value
= XSTR (XEXP (elem
->data
, 2), 0);
952 error_at (elem
->loc
, "attribute `predicable' cannot be const");
958 "attribute `predicable' must have a constant default");
963 if (strcmp (value
, p_true
) == 0)
964 predicable_default
= 1;
965 else if (strcmp (value
, p_false
) == 0)
966 predicable_default
= 0;
969 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute",
975 /* Return the number of alternatives in constraint S. */
978 n_alternatives (const char *s
)
989 /* The routine scans rtl PATTERN, find match_operand in it and counts
990 number of alternatives. If PATTERN contains several match_operands
991 with different number of alternatives, error is emitted, and the
992 routine returns 0. If all match_operands in PATTERN have the same
993 number of alternatives, it's stored in N_ALT, and the routine returns 1.
994 LOC is the location of PATTERN, for error reporting. */
996 get_alternatives_number (rtx pattern
, int *n_alt
, file_location loc
)
1005 code
= GET_CODE (pattern
);
1009 i
= n_alternatives (XSTR (pattern
, 2));
1010 /* n_alternatives returns 1 if constraint string is empty -
1011 here we fix it up. */
1012 if (!*(XSTR (pattern
, 2)))
1017 else if (i
&& i
!= *n_alt
)
1019 error_at (loc
, "wrong number of alternatives in operand %d",
1028 fmt
= GET_RTX_FORMAT (code
);
1029 len
= GET_RTX_LENGTH (code
);
1030 for (i
= 0; i
< len
; i
++)
1035 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, loc
))
1040 if (XVEC (pattern
, i
) == NULL
)
1045 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1046 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
), n_alt
, loc
))
1050 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1060 /* Determine how many alternatives there are in INSN, and how many
1064 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1070 code
= GET_CODE (pattern
);
1075 i
= n_alternatives (XSTR (pattern
, code
== MATCH_SCRATCH
? 1 : 2));
1076 *palt
= (i
> *palt
? i
: *palt
);
1079 case MATCH_OPERATOR
:
1080 case MATCH_PARALLEL
:
1081 i
= XINT (pattern
, 0);
1090 fmt
= GET_RTX_FORMAT (code
);
1091 len
= GET_RTX_LENGTH (code
);
1092 for (i
= 0; i
< len
; i
++)
1097 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1101 if (XVEC (pattern
, i
) == NULL
)
1105 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1106 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1109 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1119 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
,
1126 code
= GET_CODE (pattern
);
1131 const char *c
= XSTR (pattern
, 2);
1133 if (n_alternatives (c
) != 1)
1135 error_at (loc
, "too many alternatives for operand %d",
1140 /* Replicate C as needed to fill out ALT alternatives. */
1141 if (c
&& *c
&& alt
> 1)
1143 size_t c_len
= strlen (c
);
1144 size_t len
= alt
* (c_len
+ 1);
1145 char *new_c
= XNEWVEC (char, len
);
1147 memcpy (new_c
, c
, c_len
);
1148 for (i
= 1; i
< alt
; ++i
)
1150 new_c
[i
* (c_len
+ 1) - 1] = ',';
1151 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1153 new_c
[len
- 1] = '\0';
1154 XSTR (pattern
, 2) = new_c
;
1159 case MATCH_OPERATOR
:
1161 case MATCH_PARALLEL
:
1162 XINT (pattern
, 0) += max_op
;
1169 fmt
= GET_RTX_FORMAT (code
);
1170 len
= GET_RTX_LENGTH (code
);
1171 for (i
= 0; i
< len
; i
++)
1178 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
, max_op
, loc
);
1184 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1186 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1193 case 'i': case 'r': case 'w': case '0': case 's':
1204 /* Duplicate constraints in PATTERN. If pattern is from original
1205 rtl-template, we need to duplicate each alternative - for that we
1206 need to use duplicate_each_alternative () as a functor ALTER.
1207 If pattern is from output-pattern of define_subst, we need to
1208 duplicate constraints in another way - with duplicate_alternatives ().
1209 N_DUP is multiplication factor. */
1211 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1217 code
= GET_CODE (pattern
);
1221 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1228 fmt
= GET_RTX_FORMAT (code
);
1229 len
= GET_RTX_LENGTH (code
);
1230 for (i
= 0; i
< len
; i
++)
1237 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1243 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1245 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1251 case 'i': case 'r': case 'w': case '0': case 's':
1263 alter_test_for_insn (struct queue_elem
*ce_elem
,
1264 struct queue_elem
*insn_elem
)
1266 return rtx_reader_ptr
->join_c_conditions (XSTR (ce_elem
->data
, 1),
1267 XSTR (insn_elem
->data
, 2));
1270 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1271 to take "ce_enabled" into account. Return the new expression. */
1273 modify_attr_enabled_ce (rtx val
)
1277 eq_attr
= rtx_alloc (EQ_ATTR
);
1278 ite
= rtx_alloc (IF_THEN_ELSE
);
1279 str
= rtx_alloc (CONST_STRING
);
1281 XSTR (eq_attr
, 0) = "ce_enabled";
1282 XSTR (eq_attr
, 1) = "yes";
1283 XSTR (str
, 0) = "no";
1284 XEXP (ite
, 0) = eq_attr
;
1285 XEXP (ite
, 1) = val
;
1286 XEXP (ite
, 2) = str
;
1291 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1292 from a define_insn pattern. We must modify the "predicable" attribute
1293 to be named "ce_enabled", and also change any "enabled" attribute that's
1294 present so that it takes ce_enabled into account.
1295 We rely on the fact that INSN was created with copy_rtx, and modify data
1299 alter_attrs_for_insn (rtx insn
)
1301 static bool global_changes_made
= false;
1302 rtvec vec
= XVEC (insn
, 4);
1306 int predicable_idx
= -1;
1307 int enabled_idx
= -1;
1313 num_elem
= GET_NUM_ELEM (vec
);
1314 for (i
= num_elem
- 1; i
>= 0; --i
)
1316 rtx sub
= RTVEC_ELT (vec
, i
);
1317 switch (GET_CODE (sub
))
1320 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1323 XSTR (sub
, 0) = "ce_enabled";
1325 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1328 XSTR (sub
, 0) = "nonce_enabled";
1332 case SET_ATTR_ALTERNATIVE
:
1333 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1334 /* We already give an error elsewhere. */
1336 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1339 XSTR (sub
, 0) = "nonce_enabled";
1344 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1346 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1348 sub
= SET_SRC (sub
);
1349 if (GET_CODE (sub
) == CONST_STRING
)
1352 XSTR (sub
, 0) = "ce_enabled";
1355 /* We already give an error elsewhere. */
1359 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1362 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1370 if (predicable_idx
== -1)
1373 if (!global_changes_made
)
1375 struct queue_elem
*elem
;
1377 global_changes_made
= true;
1378 add_define_attr ("ce_enabled");
1379 add_define_attr ("nonce_enabled");
1381 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1382 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1384 XEXP (elem
->data
, 2)
1385 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1388 if (enabled_idx
== -1)
1391 new_vec
= rtvec_alloc (num_elem
+ 1);
1392 for (i
= 0; i
< num_elem
; i
++)
1393 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1394 val
= rtx_alloc (IF_THEN_ELSE
);
1395 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1396 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1397 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1398 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1399 XSTR (XEXP (val
, 0), 1) = "yes";
1400 XSTR (XEXP (val
, 1), 0) = "yes";
1401 XSTR (XEXP (val
, 2), 0) = "no";
1402 set
= rtx_alloc (SET
);
1403 SET_DEST (set
) = rtx_alloc (ATTR
);
1404 XSTR (SET_DEST (set
), 0) = "enabled";
1405 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1406 RTVEC_ELT (new_vec
, i
) = set
;
1407 XVEC (insn
, 4) = new_vec
;
1410 /* As number of constraints is changed after define_subst, we need to
1411 process attributes as well - we need to duplicate them the same way
1412 that we duplicated constraints in original pattern
1413 ELEM is a queue element, containing our rtl-template,
1414 N_DUP - multiplication factor. */
1416 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1418 rtvec vec
= XVEC (elem
->data
, 4);
1422 if (n_dup
< 2 || ! vec
)
1425 num_elem
= GET_NUM_ELEM (vec
);
1426 for (i
= num_elem
- 1; i
>= 0; --i
)
1428 rtx sub
= RTVEC_ELT (vec
, i
);
1429 switch (GET_CODE (sub
))
1432 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1433 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1436 case SET_ATTR_ALTERNATIVE
:
1438 error_at (elem
->loc
,
1439 "%s: `define_subst' does not support attributes "
1440 "assigned by `set' and `set_attr_alternative'",
1441 XSTR (elem
->data
, 0));
1450 /* Adjust all of the operand numbers in SRC to match the shift they'll
1451 get from an operand displacement of DISP. Return a pointer after the
1455 shift_output_template (char *dest
, const char *src
, int disp
)
1464 if (ISDIGIT ((unsigned char) c
))
1466 else if (ISALPHA (c
))
1479 alter_output_for_insn (struct queue_elem
*ce_elem
,
1480 struct queue_elem
*insn_elem
,
1481 int alt
, int max_op
)
1483 const char *ce_out
, *insn_out
;
1485 size_t len
, ce_len
, insn_len
;
1487 /* ??? Could coordinate with genoutput to not duplicate code here. */
1489 ce_out
= XSTR (ce_elem
->data
, 2);
1490 insn_out
= XTMPL (insn_elem
->data
, 3);
1491 if (!ce_out
|| *ce_out
== '\0')
1494 ce_len
= strlen (ce_out
);
1495 insn_len
= strlen (insn_out
);
1497 if (*insn_out
== '*')
1498 /* You must take care of the predicate yourself. */
1501 if (*insn_out
== '@')
1503 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1504 p
= result
= XNEWVEC (char, len
);
1510 while (ISSPACE ((unsigned char) *insn_out
));
1512 if (*insn_out
!= '#')
1514 p
= shift_output_template (p
, ce_out
, max_op
);
1520 while (*insn_out
&& *insn_out
!= '\n');
1527 len
= ce_len
+ 1 + insn_len
+ 1;
1528 result
= XNEWVEC (char, len
);
1530 p
= shift_output_template (result
, ce_out
, max_op
);
1532 memcpy (p
, insn_out
, insn_len
+ 1);
1538 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1539 string, duplicated N_DUP times. */
1542 duplicate_alternatives (const char * str
, int n_dup
)
1544 int i
, len
, new_len
;
1551 while (ISSPACE (*str
))
1559 new_len
= (len
+ 1) * n_dup
;
1561 sp
= result
= XNEWVEC (char, new_len
);
1563 /* Global modifier characters mustn't be duplicated: skip if found. */
1564 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1570 /* Copy original constraints N_DUP times. */
1571 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1573 memcpy (sp
, cp
, len
);
1574 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1580 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1581 each alternative from the original string is duplicated N_DUP times. */
1583 duplicate_each_alternative (const char * str
, int n_dup
)
1585 int i
, len
, new_len
;
1586 char *result
, *sp
, *ep
, *cp
;
1591 while (ISSPACE (*str
))
1599 new_len
= (strlen (cp
) + 1) * n_dup
;
1601 sp
= result
= XNEWVEC (char, new_len
);
1603 /* Global modifier characters mustn't be duplicated: skip if found. */
1604 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1609 if ((ep
= strchr (cp
, ',')) != NULL
)
1613 /* Copy a constraint N_DUP times. */
1614 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1616 memcpy (sp
, cp
, len
);
1617 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1627 /* Alter the output of INSN whose pattern was modified by
1628 DEFINE_SUBST. We must replicate output strings according
1629 to the new number of alternatives ALT in substituted pattern.
1630 If ALT equals 1, output has one alternative or defined by C
1631 code, then output is returned without any changes. */
1634 alter_output_for_subst_insn (rtx insn
, int alt
)
1636 const char *insn_out
, *old_out
;
1638 size_t old_len
, new_len
;
1641 insn_out
= XTMPL (insn
, 3);
1643 if (alt
< 2 || *insn_out
!= '@')
1646 old_out
= insn_out
+ 1;
1647 while (ISSPACE (*old_out
))
1649 old_len
= strlen (old_out
);
1651 new_len
= alt
* (old_len
+ 1) + 1;
1653 new_out
= XNEWVEC (char, new_len
);
1656 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= old_len
+ 1)
1658 memcpy (cp
, old_out
, old_len
);
1659 cp
[old_len
] = (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_at (ce_elem
->loc
, "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 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
1706 XVEC (insn
, 1) = rtvec_alloc (1);
1707 XVECEXP (insn
, 1, 0) = pattern
;
1709 if (XVEC (ce_elem
->data
, 3) != NULL
)
1711 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1712 + XVECLEN (ce_elem
->data
, 3));
1715 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1716 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1718 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1719 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1721 XVEC (insn
, 4) = attributes
;
1724 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1725 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1726 alternatives
, max_operand
);
1727 alter_attrs_for_insn (insn
);
1729 /* Put the new pattern on the `other' list so that it
1730 (a) is not reprocessed by other define_cond_exec patterns
1731 (b) appears after all normal define_insn patterns.
1733 ??? B is debatable. If one has normal insns that match
1734 cond_exec patterns, they will be preferred over these
1735 generated patterns. Whether this matters in practice, or if
1736 it's a good thing, or whether we should thread these new
1737 patterns into the define_insn chain just after their generator
1738 is something we'll have to experiment with. */
1740 queue_pattern (insn
, &other_tail
, insn_elem
->loc
);
1742 if (!insn_elem
->split
)
1745 /* If the original insn came from a define_insn_and_split,
1746 generate a new split to handle the predicated insn. */
1747 split
= copy_rtx (insn_elem
->split
->data
);
1748 /* Predicate the pattern matched by the split. */
1749 pattern
= rtx_alloc (COND_EXEC
);
1750 XEXP (pattern
, 0) = pred
;
1751 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
1752 XVEC (split
, 0) = rtvec_alloc (1);
1753 XVECEXP (split
, 0, 0) = pattern
;
1755 /* Predicate all of the insns generated by the split. */
1756 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1758 pattern
= rtx_alloc (COND_EXEC
);
1759 XEXP (pattern
, 0) = pred
;
1760 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1761 XVECEXP (split
, 2, i
) = pattern
;
1763 /* Add the new split to the queue. */
1764 queue_pattern (split
, &other_tail
, insn_elem
->split
->loc
);
1768 /* Try to apply define_substs to the given ELEM.
1769 Only define_substs, specified via attributes would be applied.
1770 If attribute, requiring define_subst, is set, but no define_subst
1771 was applied, ELEM would be deleted. */
1774 process_substs_on_one_elem (struct queue_elem
*elem
,
1775 struct queue_elem
*queue
)
1777 struct queue_elem
*subst_elem
;
1778 int i
, j
, patterns_match
;
1780 for (subst_elem
= define_subst_queue
;
1781 subst_elem
; subst_elem
= subst_elem
->next
)
1783 int alternatives
, alternatives_subst
;
1785 rtvec subst_pattern_vec
;
1787 if (!has_subst_attribute (elem
, subst_elem
))
1790 /* Compare original rtl-pattern from define_insn with input
1791 pattern from define_subst.
1792 Also, check if numbers of alternatives are the same in all
1794 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1798 alternatives_subst
= -1;
1799 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1801 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1802 XVECEXP (subst_elem
->data
, 1, j
),
1809 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1810 &alternatives
, subst_elem
->loc
))
1817 /* Check if numbers of alternatives are the same in all
1818 match_operands in output template of define_subst. */
1819 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1821 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1822 &alternatives_subst
,
1830 if (!patterns_match
)
1833 /* Clear array in which we save occupied indexes of operands. */
1834 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1836 /* Create a pattern, based on the output one from define_subst. */
1837 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1838 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1840 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1842 /* Duplicate constraints in substitute-pattern. */
1843 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1844 duplicate_each_alternative
);
1846 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1848 /* Substitute match_dup and match_op_dup in the new pattern and
1849 duplicate constraints. */
1850 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1851 alternatives_subst
);
1853 replace_duplicating_operands_in_pattern (subst_pattern
);
1855 /* We don't need any constraints in DEFINE_EXPAND. */
1856 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1857 remove_constraints (subst_pattern
);
1859 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1861 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1863 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1864 match_operand_entries_in_pattern
[i
] = NULL
;
1866 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1868 XTMPL (elem
->data
, 3) =
1869 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1870 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1873 /* Recalculate condition, joining conditions from original and
1874 DEFINE_SUBST input patterns. */
1875 XSTR (elem
->data
, 2)
1876 = rtx_reader_ptr
->join_c_conditions (XSTR (subst_elem
->data
, 2),
1877 XSTR (elem
->data
, 2));
1878 /* Mark that subst was applied by changing attribute from "yes"
1880 change_subst_attribute (elem
, subst_elem
, subst_false
);
1883 /* If ELEM contains a subst attribute with value "yes", then we
1884 expected that a subst would be applied, but it wasn't - so,
1885 we need to remove that elementto avoid duplicating. */
1886 for (subst_elem
= define_subst_queue
;
1887 subst_elem
; subst_elem
= subst_elem
->next
)
1889 if (has_subst_attribute (elem
, subst_elem
))
1891 remove_from_queue (elem
, &queue
);
1897 /* This is a subroutine of mark_operands_used_in_match_dup.
1898 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1900 mark_operands_from_match_dup (rtx pattern
)
1903 int i
, j
, len
, opno
;
1905 if (GET_CODE (pattern
) == MATCH_OPERAND
1906 || GET_CODE (pattern
) == MATCH_OPERATOR
1907 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1909 opno
= XINT (pattern
, 0);
1910 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1911 used_operands_numbers
[opno
] = 1;
1913 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1914 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1915 for (i
= 0; i
< len
; i
++)
1920 mark_operands_from_match_dup (XEXP (pattern
, i
));
1923 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1924 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1930 /* This is a subroutine of adjust_operands_numbers.
1931 It goes through all expressions in PATTERN and when MATCH_DUP is
1932 met, all MATCH_OPERANDs inside it is marked as occupied. The
1933 process of marking is done by routin mark_operands_from_match_dup. */
1935 mark_operands_used_in_match_dup (rtx pattern
)
1938 int i
, j
, len
, opno
;
1940 if (GET_CODE (pattern
) == MATCH_DUP
)
1942 opno
= XINT (pattern
, 0);
1943 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1944 mark_operands_from_match_dup (operand_data
[opno
]);
1947 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1948 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1949 for (i
= 0; i
< len
; i
++)
1954 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1957 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1958 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1964 /* This is subroutine of renumerate_operands_in_pattern.
1965 It finds first not-occupied operand-index. */
1967 find_first_unused_number_of_operand ()
1970 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1971 if (!used_operands_numbers
[i
])
1973 return MAX_OPERANDS
;
1976 /* This is subroutine of adjust_operands_numbers.
1977 It visits all expressions in PATTERN and assigns not-occupied
1978 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1981 renumerate_operands_in_pattern (rtx pattern
)
1985 int i
, j
, len
, new_opno
;
1986 code
= GET_CODE (pattern
);
1988 if (code
== MATCH_OPERAND
1989 || code
== MATCH_OPERATOR
)
1991 new_opno
= find_first_unused_number_of_operand ();
1992 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
1993 XINT (pattern
, 0) = new_opno
;
1994 used_operands_numbers
[new_opno
] = 1;
1997 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1998 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1999 for (i
= 0; i
< len
; i
++)
2004 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2007 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2008 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2014 /* If output pattern of define_subst contains MATCH_DUP, then this
2015 expression would be replaced with the pattern, matched with
2016 MATCH_OPERAND from input pattern. This pattern could contain any
2017 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2018 that a MATCH_OPERAND from output_pattern (if any) would have the
2019 same number, as MATCH_OPERAND from copied pattern. To avoid such
2020 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2021 laying in the output pattern outside of MATCH_DUPs. */
2023 adjust_operands_numbers (rtx pattern
)
2025 mark_operands_used_in_match_dup (pattern
);
2027 renumerate_operands_in_pattern (pattern
);
2032 /* Generate RTL expression
2036 generate_match_dup (int opno
)
2038 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2039 PUT_CODE (return_rtx
, MATCH_DUP
);
2040 XINT (return_rtx
, 0) = opno
;
2044 /* This routine checks all match_operands in PATTERN and if some of
2045 have the same index, it replaces all of them except the first one to
2047 Usually, match_operands with the same indexes are forbidden, but
2048 after define_subst copy an RTL-expression from original template,
2049 indexes of existed and just-copied match_operands could coincide.
2050 To fix it, we replace one of them with match_dup. */
2052 replace_duplicating_operands_in_pattern (rtx pattern
)
2055 int i
, j
, len
, opno
;
2058 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2060 opno
= XINT (pattern
, 0);
2061 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2062 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2064 match_operand_entries_in_pattern
[opno
] = pattern
;
2069 /* Compare predicates before replacing with match_dup. */
2070 if (strcmp (XSTR (pattern
, 1),
2071 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2073 error ("duplicated match_operands with different predicates were"
2077 return generate_match_dup (opno
);
2080 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2081 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2082 for (i
= 0; i
< len
; i
++)
2087 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2089 XEXP (pattern
, i
) = mdup
;
2092 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2095 replace_duplicating_operands_in_pattern (XVECEXP
2098 XVECEXP (pattern
, i
, j
) = mdup
;
2106 /* The routine modifies given input PATTERN of define_subst, replacing
2107 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2108 pattern, whose operands are stored in OPERAND_DATA array.
2109 It also duplicates constraints in operands - constraints from
2110 define_insn operands are duplicated N_SUBST_ALT times, constraints
2111 from define_subst operands are duplicated N_ALT times.
2112 After the duplication, returned output rtl-pattern contains every
2113 combination of input constraints Vs constraints from define_subst
2116 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2120 int i
, j
, len
, opno
;
2122 code
= GET_CODE (pattern
);
2127 opno
= XINT (pattern
, 0);
2129 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2131 if (operand_data
[opno
])
2133 pattern
= copy_rtx (operand_data
[opno
]);
2135 /* Duplicate constraints. */
2136 pattern
= alter_constraints (pattern
, n_subst_alt
,
2137 duplicate_alternatives
);
2145 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2146 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2147 for (i
= 0; i
< len
; i
++)
2152 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2153 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2154 n_alt
, n_subst_alt
);
2157 if (XVEC (pattern
, i
) == NULL
)
2161 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2162 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2163 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2164 n_alt
, n_subst_alt
);
2167 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2177 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2178 patterns appropriately. */
2181 process_define_cond_exec (void)
2183 struct queue_elem
*elem
;
2185 identify_predicable_attribute ();
2189 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2190 process_one_cond_exec (elem
);
2193 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2194 DEFINE_EXPAND patterns appropriately. */
2197 process_define_subst (void)
2199 struct queue_elem
*elem
, *elem_attr
;
2201 /* Check if each define_subst has corresponding define_subst_attr. */
2202 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2204 for (elem_attr
= define_subst_attr_queue
;
2206 elem_attr
= elem_attr
->next
)
2207 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2210 error_at (elem
->loc
,
2211 "%s: `define_subst' must have at least one "
2212 "corresponding `define_subst_attr'",
2213 XSTR (elem
->data
, 0));
2220 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2221 process_substs_on_one_elem (elem
, define_insn_queue
);
2222 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2224 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2226 process_substs_on_one_elem (elem
, other_queue
);
2230 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2231 the top-level elements. */
2233 class gen_reader
: public rtx_reader
2236 gen_reader () : rtx_reader (false) {}
2237 void handle_unknown_directive (file_location
, const char *);
2241 gen_reader::handle_unknown_directive (file_location loc
, const char *rtx_name
)
2243 auto_vec
<rtx
, 32> subrtxs
;
2244 if (!read_rtx (rtx_name
, &subrtxs
))
2249 FOR_EACH_VEC_ELT (subrtxs
, i
, x
)
2250 process_rtx (x
, loc
);
2253 /* Comparison function for the mnemonic hash table. */
2256 htab_eq_string (const void *s1
, const void *s2
)
2258 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2261 /* Add mnemonic STR with length LEN to the mnemonic hash table
2262 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2263 and a permanent heap copy of STR is created. */
2266 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, size_t len
)
2270 char *str_zero
= (char*)alloca (len
+ 1);
2272 memcpy (str_zero
, str
, len
);
2273 str_zero
[len
] = '\0';
2275 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2280 /* Not found; create a permanent copy and add it to the hash table. */
2281 new_str
= XNEWVAR (char, len
+ 1);
2282 memcpy (new_str
, str_zero
, len
+ 1);
2286 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2287 table in MNEMONIC_HTAB.
2289 The mnemonics cannot be found if they are emitted using C code.
2291 If a mnemonic string contains ';' or a newline the string assumed
2292 to consist of more than a single instruction. The attribute value
2293 will then be set to the user defined default value. */
2296 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2298 const char *template_code
, *cp
;
2304 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2306 template_code
= XTMPL (insn
, 3);
2308 /* Skip patterns which use C code to emit the template. */
2309 if (template_code
[0] == '*')
2312 if (template_code
[0] == '@')
2313 cp
= &template_code
[1];
2315 cp
= &template_code
[0];
2319 const char *ep
, *sp
;
2322 while (ISSPACE (*cp
))
2325 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2330 obstack_1grow (string_obstack
, ',');
2332 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2333 || (*cp
>= 'a' && *cp
<= 'z')))
2336 obstack_1grow (string_obstack
, *cp
);
2343 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2345 /* Don't set a value if there are more than one
2346 instruction in the string. */
2347 obstack_blank_fast (string_obstack
, -size
);
2356 obstack_1grow (string_obstack
, '*');
2358 add_mnemonic_string (mnemonic_htab
,
2359 (char *) obstack_next_free (string_obstack
) - size
,
2364 /* An insn definition might emit an empty string. */
2365 if (obstack_object_size (string_obstack
) == 0)
2368 obstack_1grow (string_obstack
, '\0');
2370 set_attr
= rtx_alloc (SET_ATTR
);
2371 XSTR (set_attr
, 1) = XOBFINISH (string_obstack
, char *);
2372 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2373 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2374 XSTR (set_attr
, 0) = attr_name
;
2376 if (!XVEC (insn
, 4))
2379 vec_len
= XVECLEN (insn
, 4);
2381 new_vec
= rtvec_alloc (vec_len
+ 1);
2382 for (i
= 0; i
< vec_len
; i
++)
2383 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2384 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2385 XVEC (insn
, 4) = new_vec
;
2388 /* This function is called for the elements in the mnemonic hashtable
2389 and generates a comma separated list of the mnemonics. */
2392 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
2394 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2396 obstack_grow (string_obstack
, (char*) *slot
, strlen ((char*) *slot
));
2397 obstack_1grow (string_obstack
, ',');
2401 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2402 insn definition in case the back end requests it by defining the
2403 mnemonic attribute. The values for the attribute will be extracted
2404 from the output patterns of the insn definitions as far as
2408 gen_mnemonic_attr (void)
2410 struct queue_elem
*elem
;
2411 rtx mnemonic_attr
= NULL
;
2412 htab_t mnemonic_htab
;
2413 const char *str
, *p
;
2415 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2420 /* Look for the DEFINE_ATTR for `mnemonic'. */
2421 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2422 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2423 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2425 mnemonic_attr
= elem
->data
;
2429 /* A (define_attr "mnemonic" "...") indicates that the back-end
2430 wants a mnemonic attribute to be generated. */
2434 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2435 htab_eq_string
, 0, xcalloc
, free
);
2437 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2439 rtx insn
= elem
->data
;
2442 /* Check if the insn definition already has
2443 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2445 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2447 rtx set_attr
= XVECEXP (insn
, 4, i
);
2449 switch (GET_CODE (set_attr
))
2452 case SET_ATTR_ALTERNATIVE
:
2453 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2457 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2458 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2459 MNEMONIC_ATTR_NAME
) == 0)
2468 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2471 /* Add the user defined values to the hash table. */
2472 str
= XSTR (mnemonic_attr
, 1);
2473 while ((p
= scan_comma_elt (&str
)) != NULL
)
2474 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2476 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2478 /* Replace the last ',' with the zero end character. */
2479 *((char *) obstack_next_free (string_obstack
) - 1) = '\0';
2480 XSTR (mnemonic_attr
, 1) = XOBFINISH (string_obstack
, char *);
2483 /* Check if there are DEFINE_ATTRs with the same name. */
2485 check_define_attr_duplicates ()
2487 struct queue_elem
*elem
;
2492 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2494 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2496 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2498 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2503 error_at (elem
->loc
, "redefinition of attribute '%s'", attr_name
);
2504 htab_delete (attr_htab
);
2511 htab_delete (attr_htab
);
2514 /* The entry point for initializing the reader. */
2517 init_rtx_reader_args_cb (int argc
, const char **argv
,
2518 bool (*parse_opt
) (const char *))
2520 /* Prepare to read input. */
2521 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
2522 init_predicate_table ();
2523 obstack_init (rtl_obstack
);
2525 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2526 insn_sequence_num
= 1;
2528 /* These sequences are not used as indices, so can start at 1 also. */
2529 split_sequence_num
= 1;
2530 peephole2_sequence_num
= 1;
2532 gen_reader
*reader
= new gen_reader ();
2533 reader
->read_md_files (argc
, argv
, parse_opt
);
2535 if (define_attr_queue
!= NULL
)
2536 check_define_attr_duplicates ();
2538 /* Process define_cond_exec patterns. */
2539 if (define_cond_exec_queue
!= NULL
)
2540 process_define_cond_exec ();
2542 /* Process define_subst patterns. */
2543 if (define_subst_queue
!= NULL
)
2544 process_define_subst ();
2546 if (define_attr_queue
!= NULL
)
2547 gen_mnemonic_attr ();
2558 /* Programs that don't have their own options can use this entry point
2561 init_rtx_reader_args (int argc
, const char **argv
)
2563 return init_rtx_reader_args_cb (argc
, argv
, 0);
2566 /* Try to read a single rtx from the file. Return true on success,
2567 describing it in *INFO. */
2570 read_md_rtx (md_rtx_info
*info
)
2572 int truth
, *counter
;
2575 /* Discard insn patterns which we know can never match (because
2576 their C test is provably always false). If insn_elision is
2577 false, our caller needs to see all the patterns. Note that the
2578 elided patterns are never counted by the sequence numbering; it
2579 is the caller's responsibility, when insn_elision is false, not
2580 to use elided pattern numbers for anything. */
2583 struct queue_elem
**queue
, *elem
;
2585 /* Read all patterns from a given queue before moving on to the next. */
2586 if (define_attr_queue
!= NULL
)
2587 queue
= &define_attr_queue
;
2588 else if (define_pred_queue
!= NULL
)
2589 queue
= &define_pred_queue
;
2590 else if (define_insn_queue
!= NULL
)
2591 queue
= &define_insn_queue
;
2592 else if (other_queue
!= NULL
)
2593 queue
= &other_queue
;
2598 *queue
= elem
->next
;
2601 info
->loc
= elem
->loc
;
2604 truth
= maybe_eval_c_test (get_c_test (def
));
2606 while (truth
== 0 && insn_elision
);
2608 /* Perform code-specific processing and pick the appropriate sequence
2610 switch (GET_CODE (def
))
2614 /* insn_sequence_num is used here so the name table will match caller's
2615 idea of insn numbering, whether or not elision is active. */
2616 record_insn_name (insn_sequence_num
, XSTR (def
, 0));
2619 case DEFINE_PEEPHOLE
:
2620 counter
= &insn_sequence_num
;
2624 counter
= &split_sequence_num
;
2627 case DEFINE_PEEPHOLE2
:
2628 counter
= &peephole2_sequence_num
;
2638 info
->index
= *counter
;
2646 rtx_locs
= new hash_map
<rtx
, file_location
>;
2647 rtx_locs
->put (info
->def
, info
->loc
);
2652 /* Return the file location of DEFINE_* rtx X, which was previously
2653 returned by read_md_rtx. */
2655 get_file_location (rtx x
)
2657 gcc_assert (rtx_locs
);
2658 file_location
*entry
= rtx_locs
->get (x
);
2663 /* Return the number of possible INSN_CODEs. Only meaningful once the
2664 whole file has been processed. */
2666 get_num_insn_codes ()
2668 return insn_sequence_num
;
2671 /* Return the C test that says whether definition rtx DEF can be used,
2672 or "" if it can be used unconditionally. */
2677 switch (GET_CODE (x
))
2685 case DEFINE_PEEPHOLE
:
2686 case DEFINE_PEEPHOLE2
:
2694 /* Helper functions for insn elision. */
2696 /* Compute a hash function of a c_test structure, which is keyed
2697 by its ->expr field. */
2699 hash_c_test (const void *x
)
2701 const struct c_test
*a
= (const struct c_test
*) x
;
2702 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2710 while ((c
= *s
++) != '\0')
2712 hash
+= c
+ (c
<< 17);
2717 hash
+= len
+ (len
<< 17);
2723 /* Compare two c_test expression structures. */
2725 cmp_c_test (const void *x
, const void *y
)
2727 const struct c_test
*a
= (const struct c_test
*) x
;
2728 const struct c_test
*b
= (const struct c_test
*) y
;
2730 return !strcmp (a
->expr
, b
->expr
);
2733 /* Given a string representing a C test expression, look it up in the
2734 condition_table and report whether or not its value is known
2735 at compile time. Returns a tristate: 1 for known true, 0 for
2736 known false, -1 for unknown. */
2738 maybe_eval_c_test (const char *expr
)
2740 const struct c_test
*test
;
2741 struct c_test dummy
;
2747 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2753 /* Record the C test expression EXPR in the condition_table, with
2754 value VAL. Duplicates clobber previous entries. */
2757 add_c_test (const char *expr
, int value
)
2759 struct c_test
*test
;
2764 test
= XNEW (struct c_test
);
2766 test
->value
= value
;
2768 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2771 /* For every C test, call CALLBACK with two arguments: a pointer to
2772 the condition structure and INFO. Stops when CALLBACK returns zero. */
2774 traverse_c_tests (htab_trav callback
, void *info
)
2776 if (condition_table
)
2777 htab_traverse (condition_table
, callback
, info
);
2780 /* Helper functions for define_predicate and define_special_predicate
2781 processing. Shared between genrecog.c and genpreds.c. */
2783 static htab_t predicate_table
;
2784 struct pred_data
*first_predicate
;
2785 static struct pred_data
**last_predicate
= &first_predicate
;
2788 hash_struct_pred_data (const void *ptr
)
2790 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2794 eq_struct_pred_data (const void *a
, const void *b
)
2796 return !strcmp (((const struct pred_data
*)a
)->name
,
2797 ((const struct pred_data
*)b
)->name
);
2801 lookup_predicate (const char *name
)
2803 struct pred_data key
;
2805 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2808 /* Record that predicate PRED can accept CODE. */
2811 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2813 if (!pred
->codes
[code
])
2816 pred
->codes
[code
] = true;
2818 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2819 pred
->allows_non_const
= true;
2826 && code
!= STRICT_LOW_PART
2828 pred
->allows_non_lvalue
= true;
2830 if (pred
->num_codes
== 1)
2831 pred
->singleton
= code
;
2832 else if (pred
->num_codes
== 2)
2833 pred
->singleton
= UNKNOWN
;
2838 add_predicate (struct pred_data
*pred
)
2840 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2843 error ("duplicate predicate definition for '%s'", pred
->name
);
2847 *last_predicate
= pred
;
2848 last_predicate
= &pred
->next
;
2851 /* This array gives the initial content of the predicate table. It
2852 has entries for all predicates defined in recog.c. */
2854 struct std_pred_table
2858 bool allows_const_p
;
2859 RTX_CODE codes
[NUM_RTX_CODE
];
2862 static const struct std_pred_table std_preds
[] = {
2863 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2864 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
2865 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2866 {"register_operand", false, false, {SUBREG
, REG
}},
2867 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2868 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2869 {"immediate_operand", false, true, {UNKNOWN
}},
2870 {"const_int_operand", false, false, {CONST_INT
}},
2871 #if TARGET_SUPPORTS_WIDE_INT
2872 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2873 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2875 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2877 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2878 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2879 {"push_operand", false, false, {MEM
}},
2880 {"pop_operand", false, false, {MEM
}},
2881 {"memory_operand", false, false, {SUBREG
, MEM
}},
2882 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2883 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2885 LEU
, LTU
, GEU
, GTU
}},
2886 {"comparison_operator", false, false, {EQ
, NE
,
2893 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2895 /* Initialize the table of predicate definitions, starting with
2896 the information we have on generic predicates. */
2899 init_predicate_table (void)
2902 struct pred_data
*pred
;
2904 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2905 eq_struct_pred_data
, 0,
2908 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2910 pred
= XCNEW (struct pred_data
);
2911 pred
->name
= std_preds
[i
].name
;
2912 pred
->special
= std_preds
[i
].special
;
2914 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2915 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2917 if (std_preds
[i
].allows_const_p
)
2918 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2919 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2920 add_predicate_code (pred
, (enum rtx_code
) j
);
2922 add_predicate (pred
);
2926 /* These functions allow linkage with print-rtl.c. Also, some generators
2927 like to annotate their output with insn names. */
2929 /* Holds an array of names indexed by insn_code_number. */
2930 static char **insn_name_ptr
= 0;
2931 static int insn_name_ptr_size
= 0;
2934 get_insn_name (int code
)
2936 if (code
< insn_name_ptr_size
)
2937 return insn_name_ptr
[code
];
2943 record_insn_name (int code
, const char *name
)
2945 static const char *last_real_name
= "insn";
2946 static int last_real_code
= 0;
2949 if (insn_name_ptr_size
<= code
)
2952 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2953 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2954 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2955 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2956 insn_name_ptr_size
= new_size
;
2959 if (!name
|| name
[0] == '\0')
2961 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2962 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2966 last_real_name
= new_name
= xstrdup (name
);
2967 last_real_code
= code
;
2970 insn_name_ptr
[code
] = new_name
;
2973 /* Make STATS describe the operands that appear in rtx X. */
2976 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2986 code
= GET_CODE (x
);
2990 case MATCH_OPERATOR
:
2991 case MATCH_PARALLEL
:
2992 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
2999 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
3003 if (stats
->min_scratch_opno
== -1)
3004 stats
->min_scratch_opno
= XINT (x
, 0);
3006 stats
->min_scratch_opno
= MIN (stats
->min_scratch_opno
, XINT (x
, 0));
3007 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
3014 fmt
= GET_RTX_FORMAT (code
);
3015 len
= GET_RTX_LENGTH (code
);
3016 for (i
= 0; i
< len
; i
++)
3018 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
3019 get_pattern_stats_1 (stats
, XEXP (x
, i
));
3020 else if (fmt
[i
] == 'E')
3023 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3024 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
3029 /* Make STATS describe the operands that appear in instruction pattern
3033 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
3037 stats
->max_opno
= -1;
3038 stats
->max_dup_opno
= -1;
3039 stats
->min_scratch_opno
= -1;
3040 stats
->max_scratch_opno
= -1;
3041 stats
->num_dups
= 0;
3043 len
= GET_NUM_ELEM (pattern
);
3044 for (i
= 0; i
< len
; i
++)
3045 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
3047 stats
->num_generator_args
= stats
->max_opno
+ 1;
3048 stats
->num_insn_operands
= MAX (stats
->max_opno
,
3049 stats
->max_scratch_opno
) + 1;
3050 stats
->num_operand_vars
= MAX (stats
->max_opno
,
3051 MAX (stats
->max_dup_opno
,
3052 stats
->max_scratch_opno
)) + 1;
3055 /* Return the emit_* function that should be used for pattern X, or NULL
3056 if we can't pick a particular type at compile time and should instead
3057 fall back to "emit". */
3060 get_emit_function (rtx x
)
3062 switch (classify_insn (x
))
3068 return "emit_call_insn";
3071 return "emit_jump_insn";
3081 /* Return true if we must emit a barrier after pattern X. */
3084 needs_barrier_p (rtx x
)
3086 return (GET_CODE (x
) == SET
3087 && GET_CODE (SET_DEST (x
)) == PC
3088 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);
3093 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3094 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3095 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3096 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3097 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3098 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3099 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3100 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3101 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3102 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3103 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3105 /* An array of all optabs. Note that the same optab can appear more
3106 than once, with a different pattern. */
3107 optab_def optabs
[] = {
3108 { "unknown_optab", NULL
, NS
, ZS
, NS
, unknown_optab
, UNKNOWN
, UNKNOWN
, 0 },
3109 #include "optabs.def"
3112 /* The number of entries in optabs[]. */
3113 unsigned int num_optabs
= ARRAY_SIZE (optabs
);
3127 /* Return true if instruction NAME matches pattern PAT, storing information
3128 about the match in P if so. */
3131 match_pattern (optab_pattern
*p
, const char *name
, const char *pat
)
3133 bool force_float
= false;
3134 bool force_int
= false;
3135 bool force_partial_int
= false;
3136 bool force_fixed
= false;
3144 if (*pat
!= *name
++)
3156 force_partial_int
= 1;
3170 /* This loop will stop at the first prefix match, so
3171 look through the modes in reverse order, in case
3172 there are extra CC modes and CC is a prefix of the
3173 CC modes (as it should be). */
3174 for (i
= (MAX_MACHINE_MODE
) - 1; i
>= 0; i
--)
3177 for (p
= GET_MODE_NAME (i
), q
= name
; *p
; p
++, q
++)
3178 if (TOLOWER (*p
) != *q
)
3181 && (! force_int
|| mode_class
[i
] == MODE_INT
3182 || mode_class
[i
] == MODE_VECTOR_INT
)
3183 && (! force_partial_int
3184 || mode_class
[i
] == MODE_INT
3185 || mode_class
[i
] == MODE_PARTIAL_INT
3186 || mode_class
[i
] == MODE_VECTOR_INT
)
3188 || mode_class
[i
] == MODE_FLOAT
3189 || mode_class
[i
] == MODE_DECIMAL_FLOAT
3190 || mode_class
[i
] == MODE_COMPLEX_FLOAT
3191 || mode_class
[i
] == MODE_VECTOR_FLOAT
)
3193 || mode_class
[i
] == MODE_FRACT
3194 || mode_class
[i
] == MODE_UFRACT
3195 || mode_class
[i
] == MODE_ACCUM
3196 || mode_class
[i
] == MODE_UACCUM
3197 || mode_class
[i
] == MODE_VECTOR_FRACT
3198 || mode_class
[i
] == MODE_VECTOR_UFRACT
3199 || mode_class
[i
] == MODE_VECTOR_ACCUM
3200 || mode_class
[i
] == MODE_VECTOR_UACCUM
))
3206 name
+= strlen (GET_MODE_NAME (i
));
3213 force_partial_int
= false;
3214 force_float
= false;
3215 force_fixed
= false;
3225 /* Return true if NAME is the name of an optab, describing it in P if so. */
3228 find_optab (optab_pattern
*p
, const char *name
)
3230 if (*name
== 0 || *name
== '*')
3233 /* See if NAME matches one of the patterns we have for the optabs
3235 for (unsigned int pindex
= 0; pindex
< ARRAY_SIZE (optabs
); pindex
++)
3238 if (match_pattern (p
, name
, optabs
[pindex
].pattern
))
3241 p
->op
= optabs
[pindex
].op
;
3242 p
->sort_num
= (p
->op
<< 16) | (p
->m2
<< 8) | p
->m1
;