1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2018 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 automatically 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 'r': case 'p': case 'i': 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 'r': case 'p': case 'i': case 'w':
1051 case '0': case 's': case 'S': case 'T':
1061 /* Determine how many alternatives there are in INSN, and how many
1065 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1071 code
= GET_CODE (pattern
);
1076 i
= n_alternatives (XSTR (pattern
, code
== MATCH_SCRATCH
? 1 : 2));
1077 *palt
= (i
> *palt
? i
: *palt
);
1080 case MATCH_OPERATOR
:
1081 case MATCH_PARALLEL
:
1082 i
= XINT (pattern
, 0);
1091 fmt
= GET_RTX_FORMAT (code
);
1092 len
= GET_RTX_LENGTH (code
);
1093 for (i
= 0; i
< len
; i
++)
1098 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1102 if (XVEC (pattern
, i
) == NULL
)
1106 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1107 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1110 case 'r': case 'p': case 'i': case 'w':
1111 case '0': case 's': case 'S': case 'T':
1121 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
,
1128 code
= GET_CODE (pattern
);
1133 const char *c
= XSTR (pattern
, 2);
1135 if (n_alternatives (c
) != 1)
1137 error_at (loc
, "too many alternatives for operand %d",
1142 /* Replicate C as needed to fill out ALT alternatives. */
1143 if (c
&& *c
&& alt
> 1)
1145 size_t c_len
= strlen (c
);
1146 size_t len
= alt
* (c_len
+ 1);
1147 char *new_c
= XNEWVEC (char, len
);
1149 memcpy (new_c
, c
, c_len
);
1150 for (i
= 1; i
< alt
; ++i
)
1152 new_c
[i
* (c_len
+ 1) - 1] = ',';
1153 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1155 new_c
[len
- 1] = '\0';
1156 XSTR (pattern
, 2) = new_c
;
1161 case MATCH_OPERATOR
:
1163 case MATCH_PARALLEL
:
1164 XINT (pattern
, 0) += max_op
;
1171 fmt
= GET_RTX_FORMAT (code
);
1172 len
= GET_RTX_LENGTH (code
);
1173 for (i
= 0; i
< len
; i
++)
1180 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
, max_op
, loc
);
1186 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1188 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1195 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1206 /* Duplicate constraints in PATTERN. If pattern is from original
1207 rtl-template, we need to duplicate each alternative - for that we
1208 need to use duplicate_each_alternative () as a functor ALTER.
1209 If pattern is from output-pattern of define_subst, we need to
1210 duplicate constraints in another way - with duplicate_alternatives ().
1211 N_DUP is multiplication factor. */
1213 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1219 code
= GET_CODE (pattern
);
1223 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1230 fmt
= GET_RTX_FORMAT (code
);
1231 len
= GET_RTX_LENGTH (code
);
1232 for (i
= 0; i
< len
; i
++)
1239 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1245 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1247 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1253 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1265 alter_test_for_insn (struct queue_elem
*ce_elem
,
1266 struct queue_elem
*insn_elem
)
1268 return rtx_reader_ptr
->join_c_conditions (XSTR (ce_elem
->data
, 1),
1269 XSTR (insn_elem
->data
, 2));
1272 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1273 to take "ce_enabled" into account. Return the new expression. */
1275 modify_attr_enabled_ce (rtx val
)
1279 eq_attr
= rtx_alloc (EQ_ATTR
);
1280 ite
= rtx_alloc (IF_THEN_ELSE
);
1281 str
= rtx_alloc (CONST_STRING
);
1283 XSTR (eq_attr
, 0) = "ce_enabled";
1284 XSTR (eq_attr
, 1) = "yes";
1285 XSTR (str
, 0) = "no";
1286 XEXP (ite
, 0) = eq_attr
;
1287 XEXP (ite
, 1) = val
;
1288 XEXP (ite
, 2) = str
;
1293 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1294 from a define_insn pattern. We must modify the "predicable" attribute
1295 to be named "ce_enabled", and also change any "enabled" attribute that's
1296 present so that it takes ce_enabled into account.
1297 We rely on the fact that INSN was created with copy_rtx, and modify data
1301 alter_attrs_for_insn (rtx insn
)
1303 static bool global_changes_made
= false;
1304 rtvec vec
= XVEC (insn
, 4);
1308 int predicable_idx
= -1;
1309 int enabled_idx
= -1;
1315 num_elem
= GET_NUM_ELEM (vec
);
1316 for (i
= num_elem
- 1; i
>= 0; --i
)
1318 rtx sub
= RTVEC_ELT (vec
, i
);
1319 switch (GET_CODE (sub
))
1322 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1325 XSTR (sub
, 0) = "ce_enabled";
1327 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1330 XSTR (sub
, 0) = "nonce_enabled";
1334 case SET_ATTR_ALTERNATIVE
:
1335 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1336 /* We already give an error elsewhere. */
1338 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1341 XSTR (sub
, 0) = "nonce_enabled";
1346 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1348 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1350 sub
= SET_SRC (sub
);
1351 if (GET_CODE (sub
) == CONST_STRING
)
1354 XSTR (sub
, 0) = "ce_enabled";
1357 /* We already give an error elsewhere. */
1361 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1364 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1372 if (predicable_idx
== -1)
1375 if (!global_changes_made
)
1377 struct queue_elem
*elem
;
1379 global_changes_made
= true;
1380 add_define_attr ("ce_enabled");
1381 add_define_attr ("nonce_enabled");
1383 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1384 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1386 XEXP (elem
->data
, 2)
1387 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1390 if (enabled_idx
== -1)
1393 new_vec
= rtvec_alloc (num_elem
+ 1);
1394 for (i
= 0; i
< num_elem
; i
++)
1395 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1396 val
= rtx_alloc (IF_THEN_ELSE
);
1397 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1398 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1399 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1400 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1401 XSTR (XEXP (val
, 0), 1) = "yes";
1402 XSTR (XEXP (val
, 1), 0) = "yes";
1403 XSTR (XEXP (val
, 2), 0) = "no";
1404 set
= rtx_alloc (SET
);
1405 SET_DEST (set
) = rtx_alloc (ATTR
);
1406 XSTR (SET_DEST (set
), 0) = "enabled";
1407 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1408 RTVEC_ELT (new_vec
, i
) = set
;
1409 XVEC (insn
, 4) = new_vec
;
1412 /* As number of constraints is changed after define_subst, we need to
1413 process attributes as well - we need to duplicate them the same way
1414 that we duplicated constraints in original pattern
1415 ELEM is a queue element, containing our rtl-template,
1416 N_DUP - multiplication factor. */
1418 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1420 rtvec vec
= XVEC (elem
->data
, 4);
1424 if (n_dup
< 2 || ! vec
)
1427 num_elem
= GET_NUM_ELEM (vec
);
1428 for (i
= num_elem
- 1; i
>= 0; --i
)
1430 rtx sub
= RTVEC_ELT (vec
, i
);
1431 switch (GET_CODE (sub
))
1434 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1435 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1438 case SET_ATTR_ALTERNATIVE
:
1440 error_at (elem
->loc
,
1441 "%s: `define_subst' does not support attributes "
1442 "assigned by `set' and `set_attr_alternative'",
1443 XSTR (elem
->data
, 0));
1452 /* Adjust all of the operand numbers in SRC to match the shift they'll
1453 get from an operand displacement of DISP. Return a pointer after the
1457 shift_output_template (char *dest
, const char *src
, int disp
)
1466 if (ISDIGIT ((unsigned char) c
))
1468 else if (ISALPHA (c
))
1481 alter_output_for_insn (struct queue_elem
*ce_elem
,
1482 struct queue_elem
*insn_elem
,
1483 int alt
, int max_op
)
1485 const char *ce_out
, *insn_out
;
1487 size_t len
, ce_len
, insn_len
;
1489 /* ??? Could coordinate with genoutput to not duplicate code here. */
1491 ce_out
= XSTR (ce_elem
->data
, 2);
1492 insn_out
= XTMPL (insn_elem
->data
, 3);
1493 if (!ce_out
|| *ce_out
== '\0')
1496 ce_len
= strlen (ce_out
);
1497 insn_len
= strlen (insn_out
);
1499 if (*insn_out
== '*')
1500 /* You must take care of the predicate yourself. */
1503 if (*insn_out
== '@')
1505 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1506 p
= result
= XNEWVEC (char, len
);
1512 while (ISSPACE ((unsigned char) *insn_out
));
1514 if (*insn_out
!= '#')
1516 p
= shift_output_template (p
, ce_out
, max_op
);
1522 while (*insn_out
&& *insn_out
!= '\n');
1529 len
= ce_len
+ 1 + insn_len
+ 1;
1530 result
= XNEWVEC (char, len
);
1532 p
= shift_output_template (result
, ce_out
, max_op
);
1534 memcpy (p
, insn_out
, insn_len
+ 1);
1540 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1541 string, duplicated N_DUP times. */
1544 duplicate_alternatives (const char * str
, int n_dup
)
1546 int i
, len
, new_len
;
1553 while (ISSPACE (*str
))
1561 new_len
= (len
+ 1) * n_dup
;
1563 sp
= result
= XNEWVEC (char, new_len
);
1565 /* Global modifier characters mustn't be duplicated: skip if found. */
1566 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1572 /* Copy original constraints N_DUP times. */
1573 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1575 memcpy (sp
, cp
, len
);
1576 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1582 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1583 each alternative from the original string is duplicated N_DUP times. */
1585 duplicate_each_alternative (const char * str
, int n_dup
)
1587 int i
, len
, new_len
;
1588 char *result
, *sp
, *ep
, *cp
;
1593 while (ISSPACE (*str
))
1601 new_len
= (strlen (cp
) + 1) * n_dup
;
1603 sp
= result
= XNEWVEC (char, new_len
);
1605 /* Global modifier characters mustn't be duplicated: skip if found. */
1606 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1611 if ((ep
= strchr (cp
, ',')) != NULL
)
1615 /* Copy a constraint N_DUP times. */
1616 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1618 memcpy (sp
, cp
, len
);
1619 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1629 /* Alter the output of INSN whose pattern was modified by
1630 DEFINE_SUBST. We must replicate output strings according
1631 to the new number of alternatives ALT in substituted pattern.
1632 If ALT equals 1, output has one alternative or defined by C
1633 code, then output is returned without any changes. */
1636 alter_output_for_subst_insn (rtx insn
, int alt
)
1638 const char *insn_out
, *old_out
;
1640 size_t old_len
, new_len
;
1643 insn_out
= XTMPL (insn
, 3);
1645 if (alt
< 2 || *insn_out
!= '@')
1648 old_out
= insn_out
+ 1;
1649 while (ISSPACE (*old_out
))
1651 old_len
= strlen (old_out
);
1653 new_len
= alt
* (old_len
+ 1) + 1;
1655 new_out
= XNEWVEC (char, new_len
);
1658 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= old_len
+ 1)
1660 memcpy (cp
, old_out
, old_len
);
1661 cp
[old_len
] = (j
== alt
- 1) ? '\0' : '\n';
1667 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1670 process_one_cond_exec (struct queue_elem
*ce_elem
)
1672 struct queue_elem
*insn_elem
;
1673 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1675 int alternatives
, max_operand
;
1676 rtx pred
, insn
, pattern
, split
;
1680 if (! is_predicable (insn_elem
))
1685 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1688 if (XVECLEN (ce_elem
->data
, 0) != 1)
1690 error_at (ce_elem
->loc
, "too many patterns in predicate");
1694 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1695 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1700 /* Construct a new pattern for the new insn. */
1701 insn
= copy_rtx (insn_elem
->data
);
1702 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1703 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1704 XSTR (insn
, 0) = new_name
;
1705 pattern
= rtx_alloc (COND_EXEC
);
1706 XEXP (pattern
, 0) = pred
;
1707 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
1708 XVEC (insn
, 1) = rtvec_alloc (1);
1709 XVECEXP (insn
, 1, 0) = pattern
;
1711 if (XVEC (ce_elem
->data
, 3) != NULL
)
1713 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1714 + XVECLEN (ce_elem
->data
, 3));
1717 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1718 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1720 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1721 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1723 XVEC (insn
, 4) = attributes
;
1726 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1727 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1728 alternatives
, max_operand
);
1729 alter_attrs_for_insn (insn
);
1731 /* Put the new pattern on the `other' list so that it
1732 (a) is not reprocessed by other define_cond_exec patterns
1733 (b) appears after all normal define_insn patterns.
1735 ??? B is debatable. If one has normal insns that match
1736 cond_exec patterns, they will be preferred over these
1737 generated patterns. Whether this matters in practice, or if
1738 it's a good thing, or whether we should thread these new
1739 patterns into the define_insn chain just after their generator
1740 is something we'll have to experiment with. */
1742 queue_pattern (insn
, &other_tail
, insn_elem
->loc
);
1744 if (!insn_elem
->split
)
1747 /* If the original insn came from a define_insn_and_split,
1748 generate a new split to handle the predicated insn. */
1749 split
= copy_rtx (insn_elem
->split
->data
);
1750 /* Predicate the pattern matched by the split. */
1751 pattern
= rtx_alloc (COND_EXEC
);
1752 XEXP (pattern
, 0) = pred
;
1753 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
1754 XVEC (split
, 0) = rtvec_alloc (1);
1755 XVECEXP (split
, 0, 0) = pattern
;
1757 /* Predicate all of the insns generated by the split. */
1758 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1760 pattern
= rtx_alloc (COND_EXEC
);
1761 XEXP (pattern
, 0) = pred
;
1762 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1763 XVECEXP (split
, 2, i
) = pattern
;
1765 /* Add the new split to the queue. */
1766 queue_pattern (split
, &other_tail
, insn_elem
->split
->loc
);
1770 /* Try to apply define_substs to the given ELEM.
1771 Only define_substs, specified via attributes would be applied.
1772 If attribute, requiring define_subst, is set, but no define_subst
1773 was applied, ELEM would be deleted. */
1776 process_substs_on_one_elem (struct queue_elem
*elem
,
1777 struct queue_elem
*queue
)
1779 struct queue_elem
*subst_elem
;
1780 int i
, j
, patterns_match
;
1782 for (subst_elem
= define_subst_queue
;
1783 subst_elem
; subst_elem
= subst_elem
->next
)
1785 int alternatives
, alternatives_subst
;
1787 rtvec subst_pattern_vec
;
1789 if (!has_subst_attribute (elem
, subst_elem
))
1792 /* Compare original rtl-pattern from define_insn with input
1793 pattern from define_subst.
1794 Also, check if numbers of alternatives are the same in all
1796 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1800 alternatives_subst
= -1;
1801 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1803 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1804 XVECEXP (subst_elem
->data
, 1, j
),
1811 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1812 &alternatives
, subst_elem
->loc
))
1819 /* Check if numbers of alternatives are the same in all
1820 match_operands in output template of define_subst. */
1821 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1823 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1824 &alternatives_subst
,
1832 if (!patterns_match
)
1835 /* Clear array in which we save occupied indexes of operands. */
1836 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1838 /* Create a pattern, based on the output one from define_subst. */
1839 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1840 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1842 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1844 /* Duplicate constraints in substitute-pattern. */
1845 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1846 duplicate_each_alternative
);
1848 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1850 /* Substitute match_dup and match_op_dup in the new pattern and
1851 duplicate constraints. */
1852 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1853 alternatives_subst
);
1855 replace_duplicating_operands_in_pattern (subst_pattern
);
1857 /* We don't need any constraints in DEFINE_EXPAND. */
1858 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1859 remove_constraints (subst_pattern
);
1861 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1863 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1865 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1866 match_operand_entries_in_pattern
[i
] = NULL
;
1868 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1870 XTMPL (elem
->data
, 3) =
1871 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1872 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1875 /* Recalculate condition, joining conditions from original and
1876 DEFINE_SUBST input patterns. */
1877 XSTR (elem
->data
, 2)
1878 = rtx_reader_ptr
->join_c_conditions (XSTR (subst_elem
->data
, 2),
1879 XSTR (elem
->data
, 2));
1880 /* Mark that subst was applied by changing attribute from "yes"
1882 change_subst_attribute (elem
, subst_elem
, subst_false
);
1885 /* If ELEM contains a subst attribute with value "yes", then we
1886 expected that a subst would be applied, but it wasn't - so,
1887 we need to remove that elementto avoid duplicating. */
1888 for (subst_elem
= define_subst_queue
;
1889 subst_elem
; subst_elem
= subst_elem
->next
)
1891 if (has_subst_attribute (elem
, subst_elem
))
1893 remove_from_queue (elem
, &queue
);
1899 /* This is a subroutine of mark_operands_used_in_match_dup.
1900 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1902 mark_operands_from_match_dup (rtx pattern
)
1905 int i
, j
, len
, opno
;
1907 if (GET_CODE (pattern
) == MATCH_OPERAND
1908 || GET_CODE (pattern
) == MATCH_OPERATOR
1909 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1911 opno
= XINT (pattern
, 0);
1912 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1913 used_operands_numbers
[opno
] = 1;
1915 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1916 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1917 for (i
= 0; i
< len
; i
++)
1922 mark_operands_from_match_dup (XEXP (pattern
, i
));
1925 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1926 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1932 /* This is a subroutine of adjust_operands_numbers.
1933 It goes through all expressions in PATTERN and when MATCH_DUP is
1934 met, all MATCH_OPERANDs inside it is marked as occupied. The
1935 process of marking is done by routin mark_operands_from_match_dup. */
1937 mark_operands_used_in_match_dup (rtx pattern
)
1940 int i
, j
, len
, opno
;
1942 if (GET_CODE (pattern
) == MATCH_DUP
)
1944 opno
= XINT (pattern
, 0);
1945 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1946 mark_operands_from_match_dup (operand_data
[opno
]);
1949 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1950 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1951 for (i
= 0; i
< len
; i
++)
1956 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1959 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1960 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1966 /* This is subroutine of renumerate_operands_in_pattern.
1967 It finds first not-occupied operand-index. */
1969 find_first_unused_number_of_operand ()
1972 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1973 if (!used_operands_numbers
[i
])
1975 return MAX_OPERANDS
;
1978 /* This is subroutine of adjust_operands_numbers.
1979 It visits all expressions in PATTERN and assigns not-occupied
1980 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1983 renumerate_operands_in_pattern (rtx pattern
)
1987 int i
, j
, len
, new_opno
;
1988 code
= GET_CODE (pattern
);
1990 if (code
== MATCH_OPERAND
1991 || code
== MATCH_OPERATOR
)
1993 new_opno
= find_first_unused_number_of_operand ();
1994 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
1995 XINT (pattern
, 0) = new_opno
;
1996 used_operands_numbers
[new_opno
] = 1;
1999 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2000 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2001 for (i
= 0; i
< len
; i
++)
2006 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2009 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2010 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2016 /* If output pattern of define_subst contains MATCH_DUP, then this
2017 expression would be replaced with the pattern, matched with
2018 MATCH_OPERAND from input pattern. This pattern could contain any
2019 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2020 that a MATCH_OPERAND from output_pattern (if any) would have the
2021 same number, as MATCH_OPERAND from copied pattern. To avoid such
2022 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2023 laying in the output pattern outside of MATCH_DUPs. */
2025 adjust_operands_numbers (rtx pattern
)
2027 mark_operands_used_in_match_dup (pattern
);
2029 renumerate_operands_in_pattern (pattern
);
2034 /* Generate RTL expression
2038 generate_match_dup (int opno
)
2040 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2041 PUT_CODE (return_rtx
, MATCH_DUP
);
2042 XINT (return_rtx
, 0) = opno
;
2046 /* This routine checks all match_operands in PATTERN and if some of
2047 have the same index, it replaces all of them except the first one to
2049 Usually, match_operands with the same indexes are forbidden, but
2050 after define_subst copy an RTL-expression from original template,
2051 indexes of existed and just-copied match_operands could coincide.
2052 To fix it, we replace one of them with match_dup. */
2054 replace_duplicating_operands_in_pattern (rtx pattern
)
2057 int i
, j
, len
, opno
;
2060 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2062 opno
= XINT (pattern
, 0);
2063 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2064 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2066 match_operand_entries_in_pattern
[opno
] = pattern
;
2071 /* Compare predicates before replacing with match_dup. */
2072 if (strcmp (XSTR (pattern
, 1),
2073 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2075 error ("duplicated match_operands with different predicates were"
2079 return generate_match_dup (opno
);
2082 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2083 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2084 for (i
= 0; i
< len
; i
++)
2089 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2091 XEXP (pattern
, i
) = mdup
;
2094 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2097 replace_duplicating_operands_in_pattern (XVECEXP
2100 XVECEXP (pattern
, i
, j
) = mdup
;
2108 /* The routine modifies given input PATTERN of define_subst, replacing
2109 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2110 pattern, whose operands are stored in OPERAND_DATA array.
2111 It also duplicates constraints in operands - constraints from
2112 define_insn operands are duplicated N_SUBST_ALT times, constraints
2113 from define_subst operands are duplicated N_ALT times.
2114 After the duplication, returned output rtl-pattern contains every
2115 combination of input constraints Vs constraints from define_subst
2118 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2122 int i
, j
, len
, opno
;
2124 code
= GET_CODE (pattern
);
2129 opno
= XINT (pattern
, 0);
2131 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2133 if (operand_data
[opno
])
2135 pattern
= copy_rtx (operand_data
[opno
]);
2137 /* Duplicate constraints. */
2138 pattern
= alter_constraints (pattern
, n_subst_alt
,
2139 duplicate_alternatives
);
2147 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2148 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2149 for (i
= 0; i
< len
; i
++)
2154 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2155 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2156 n_alt
, n_subst_alt
);
2159 if (XVEC (pattern
, i
) == NULL
)
2163 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2164 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2165 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2166 n_alt
, n_subst_alt
);
2169 case 'r': case 'p': case 'i': case 'w':
2170 case '0': case 's': case 'S': case 'T':
2180 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2181 patterns appropriately. */
2184 process_define_cond_exec (void)
2186 struct queue_elem
*elem
;
2188 identify_predicable_attribute ();
2192 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2193 process_one_cond_exec (elem
);
2196 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2197 DEFINE_EXPAND patterns appropriately. */
2200 process_define_subst (void)
2202 struct queue_elem
*elem
, *elem_attr
;
2204 /* Check if each define_subst has corresponding define_subst_attr. */
2205 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2207 for (elem_attr
= define_subst_attr_queue
;
2209 elem_attr
= elem_attr
->next
)
2210 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2213 error_at (elem
->loc
,
2214 "%s: `define_subst' must have at least one "
2215 "corresponding `define_subst_attr'",
2216 XSTR (elem
->data
, 0));
2223 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2224 process_substs_on_one_elem (elem
, define_insn_queue
);
2225 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2227 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2229 process_substs_on_one_elem (elem
, other_queue
);
2233 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2234 the top-level elements. */
2236 class gen_reader
: public rtx_reader
2239 gen_reader () : rtx_reader (false) {}
2240 void handle_unknown_directive (file_location
, const char *);
2244 gen_reader::handle_unknown_directive (file_location loc
, const char *rtx_name
)
2246 auto_vec
<rtx
, 32> subrtxs
;
2247 if (!read_rtx (rtx_name
, &subrtxs
))
2252 FOR_EACH_VEC_ELT (subrtxs
, i
, x
)
2253 process_rtx (x
, loc
);
2256 /* Comparison function for the mnemonic hash table. */
2259 htab_eq_string (const void *s1
, const void *s2
)
2261 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2264 /* Add mnemonic STR with length LEN to the mnemonic hash table
2265 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2266 and a permanent heap copy of STR is created. */
2269 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, size_t len
)
2273 char *str_zero
= (char*)alloca (len
+ 1);
2275 memcpy (str_zero
, str
, len
);
2276 str_zero
[len
] = '\0';
2278 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2283 /* Not found; create a permanent copy and add it to the hash table. */
2284 new_str
= XNEWVAR (char, len
+ 1);
2285 memcpy (new_str
, str_zero
, len
+ 1);
2289 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2290 table in MNEMONIC_HTAB.
2292 The mnemonics cannot be found if they are emitted using C code.
2294 If a mnemonic string contains ';' or a newline the string assumed
2295 to consist of more than a single instruction. The attribute value
2296 will then be set to the user defined default value. */
2299 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2301 const char *template_code
, *cp
;
2307 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2309 template_code
= XTMPL (insn
, 3);
2311 /* Skip patterns which use C code to emit the template. */
2312 if (template_code
[0] == '*')
2315 if (template_code
[0] == '@')
2316 cp
= &template_code
[1];
2318 cp
= &template_code
[0];
2322 const char *ep
, *sp
;
2325 while (ISSPACE (*cp
))
2328 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2333 obstack_1grow (string_obstack
, ',');
2335 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2336 || (*cp
>= 'a' && *cp
<= 'z')))
2339 obstack_1grow (string_obstack
, *cp
);
2346 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2348 /* Don't set a value if there are more than one
2349 instruction in the string. */
2350 obstack_blank_fast (string_obstack
, -size
);
2359 obstack_1grow (string_obstack
, '*');
2361 add_mnemonic_string (mnemonic_htab
,
2362 (char *) obstack_next_free (string_obstack
) - size
,
2367 /* An insn definition might emit an empty string. */
2368 if (obstack_object_size (string_obstack
) == 0)
2371 obstack_1grow (string_obstack
, '\0');
2373 set_attr
= rtx_alloc (SET_ATTR
);
2374 XSTR (set_attr
, 1) = XOBFINISH (string_obstack
, char *);
2375 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2376 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2377 XSTR (set_attr
, 0) = attr_name
;
2379 if (!XVEC (insn
, 4))
2382 vec_len
= XVECLEN (insn
, 4);
2384 new_vec
= rtvec_alloc (vec_len
+ 1);
2385 for (i
= 0; i
< vec_len
; i
++)
2386 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2387 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2388 XVEC (insn
, 4) = new_vec
;
2391 /* This function is called for the elements in the mnemonic hashtable
2392 and generates a comma separated list of the mnemonics. */
2395 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
2397 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2399 obstack_grow (string_obstack
, (char*) *slot
, strlen ((char*) *slot
));
2400 obstack_1grow (string_obstack
, ',');
2404 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2405 insn definition in case the back end requests it by defining the
2406 mnemonic attribute. The values for the attribute will be extracted
2407 from the output patterns of the insn definitions as far as
2411 gen_mnemonic_attr (void)
2413 struct queue_elem
*elem
;
2414 rtx mnemonic_attr
= NULL
;
2415 htab_t mnemonic_htab
;
2416 const char *str
, *p
;
2418 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2423 /* Look for the DEFINE_ATTR for `mnemonic'. */
2424 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2425 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2426 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2428 mnemonic_attr
= elem
->data
;
2432 /* A (define_attr "mnemonic" "...") indicates that the back-end
2433 wants a mnemonic attribute to be generated. */
2437 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2438 htab_eq_string
, 0, xcalloc
, free
);
2440 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2442 rtx insn
= elem
->data
;
2445 /* Check if the insn definition already has
2446 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2448 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2450 rtx set_attr
= XVECEXP (insn
, 4, i
);
2452 switch (GET_CODE (set_attr
))
2455 case SET_ATTR_ALTERNATIVE
:
2456 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2460 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2461 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2462 MNEMONIC_ATTR_NAME
) == 0)
2471 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2474 /* Add the user defined values to the hash table. */
2475 str
= XSTR (mnemonic_attr
, 1);
2476 while ((p
= scan_comma_elt (&str
)) != NULL
)
2477 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2479 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2481 /* Replace the last ',' with the zero end character. */
2482 *((char *) obstack_next_free (string_obstack
) - 1) = '\0';
2483 XSTR (mnemonic_attr
, 1) = XOBFINISH (string_obstack
, char *);
2486 /* Check if there are DEFINE_ATTRs with the same name. */
2488 check_define_attr_duplicates ()
2490 struct queue_elem
*elem
;
2495 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2497 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2499 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2501 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2506 error_at (elem
->loc
, "redefinition of attribute '%s'", attr_name
);
2507 htab_delete (attr_htab
);
2514 htab_delete (attr_htab
);
2517 /* The entry point for initializing the reader. */
2520 init_rtx_reader_args_cb (int argc
, const char **argv
,
2521 bool (*parse_opt
) (const char *))
2523 /* Prepare to read input. */
2524 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
2525 init_predicate_table ();
2526 obstack_init (rtl_obstack
);
2528 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2529 insn_sequence_num
= 1;
2531 /* These sequences are not used as indices, so can start at 1 also. */
2532 split_sequence_num
= 1;
2533 peephole2_sequence_num
= 1;
2535 gen_reader
*reader
= new gen_reader ();
2536 reader
->read_md_files (argc
, argv
, parse_opt
);
2538 if (define_attr_queue
!= NULL
)
2539 check_define_attr_duplicates ();
2541 /* Process define_cond_exec patterns. */
2542 if (define_cond_exec_queue
!= NULL
)
2543 process_define_cond_exec ();
2545 /* Process define_subst patterns. */
2546 if (define_subst_queue
!= NULL
)
2547 process_define_subst ();
2549 if (define_attr_queue
!= NULL
)
2550 gen_mnemonic_attr ();
2561 /* Programs that don't have their own options can use this entry point
2564 init_rtx_reader_args (int argc
, const char **argv
)
2566 return init_rtx_reader_args_cb (argc
, argv
, 0);
2569 /* Try to read a single rtx from the file. Return true on success,
2570 describing it in *INFO. */
2573 read_md_rtx (md_rtx_info
*info
)
2575 int truth
, *counter
;
2578 /* Discard insn patterns which we know can never match (because
2579 their C test is provably always false). If insn_elision is
2580 false, our caller needs to see all the patterns. Note that the
2581 elided patterns are never counted by the sequence numbering; it
2582 is the caller's responsibility, when insn_elision is false, not
2583 to use elided pattern numbers for anything. */
2586 struct queue_elem
**queue
, *elem
;
2588 /* Read all patterns from a given queue before moving on to the next. */
2589 if (define_attr_queue
!= NULL
)
2590 queue
= &define_attr_queue
;
2591 else if (define_pred_queue
!= NULL
)
2592 queue
= &define_pred_queue
;
2593 else if (define_insn_queue
!= NULL
)
2594 queue
= &define_insn_queue
;
2595 else if (other_queue
!= NULL
)
2596 queue
= &other_queue
;
2601 *queue
= elem
->next
;
2604 info
->loc
= elem
->loc
;
2607 truth
= maybe_eval_c_test (get_c_test (def
));
2609 while (truth
== 0 && insn_elision
);
2611 /* Perform code-specific processing and pick the appropriate sequence
2613 switch (GET_CODE (def
))
2617 /* insn_sequence_num is used here so the name table will match caller's
2618 idea of insn numbering, whether or not elision is active. */
2619 record_insn_name (insn_sequence_num
, XSTR (def
, 0));
2622 case DEFINE_PEEPHOLE
:
2623 counter
= &insn_sequence_num
;
2627 counter
= &split_sequence_num
;
2630 case DEFINE_PEEPHOLE2
:
2631 counter
= &peephole2_sequence_num
;
2641 info
->index
= *counter
;
2649 rtx_locs
= new hash_map
<rtx
, file_location
>;
2650 rtx_locs
->put (info
->def
, info
->loc
);
2655 /* Return the file location of DEFINE_* rtx X, which was previously
2656 returned by read_md_rtx. */
2658 get_file_location (rtx x
)
2660 gcc_assert (rtx_locs
);
2661 file_location
*entry
= rtx_locs
->get (x
);
2666 /* Return the number of possible INSN_CODEs. Only meaningful once the
2667 whole file has been processed. */
2669 get_num_insn_codes ()
2671 return insn_sequence_num
;
2674 /* Return the C test that says whether definition rtx DEF can be used,
2675 or "" if it can be used unconditionally. */
2680 switch (GET_CODE (x
))
2688 case DEFINE_PEEPHOLE
:
2689 case DEFINE_PEEPHOLE2
:
2697 /* Helper functions for insn elision. */
2699 /* Compute a hash function of a c_test structure, which is keyed
2700 by its ->expr field. */
2702 hash_c_test (const void *x
)
2704 const struct c_test
*a
= (const struct c_test
*) x
;
2705 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2713 while ((c
= *s
++) != '\0')
2715 hash
+= c
+ (c
<< 17);
2720 hash
+= len
+ (len
<< 17);
2726 /* Compare two c_test expression structures. */
2728 cmp_c_test (const void *x
, const void *y
)
2730 const struct c_test
*a
= (const struct c_test
*) x
;
2731 const struct c_test
*b
= (const struct c_test
*) y
;
2733 return !strcmp (a
->expr
, b
->expr
);
2736 /* Given a string representing a C test expression, look it up in the
2737 condition_table and report whether or not its value is known
2738 at compile time. Returns a tristate: 1 for known true, 0 for
2739 known false, -1 for unknown. */
2741 maybe_eval_c_test (const char *expr
)
2743 const struct c_test
*test
;
2744 struct c_test dummy
;
2750 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2756 /* Record the C test expression EXPR in the condition_table, with
2757 value VAL. Duplicates clobber previous entries. */
2760 add_c_test (const char *expr
, int value
)
2762 struct c_test
*test
;
2767 test
= XNEW (struct c_test
);
2769 test
->value
= value
;
2771 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2774 /* For every C test, call CALLBACK with two arguments: a pointer to
2775 the condition structure and INFO. Stops when CALLBACK returns zero. */
2777 traverse_c_tests (htab_trav callback
, void *info
)
2779 if (condition_table
)
2780 htab_traverse (condition_table
, callback
, info
);
2783 /* Helper functions for define_predicate and define_special_predicate
2784 processing. Shared between genrecog.c and genpreds.c. */
2786 static htab_t predicate_table
;
2787 struct pred_data
*first_predicate
;
2788 static struct pred_data
**last_predicate
= &first_predicate
;
2791 hash_struct_pred_data (const void *ptr
)
2793 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2797 eq_struct_pred_data (const void *a
, const void *b
)
2799 return !strcmp (((const struct pred_data
*)a
)->name
,
2800 ((const struct pred_data
*)b
)->name
);
2804 lookup_predicate (const char *name
)
2806 struct pred_data key
;
2808 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2811 /* Record that predicate PRED can accept CODE. */
2814 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2816 if (!pred
->codes
[code
])
2819 pred
->codes
[code
] = true;
2821 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2822 pred
->allows_non_const
= true;
2829 && code
!= STRICT_LOW_PART
2830 && code
!= ZERO_EXTRACT
2832 pred
->allows_non_lvalue
= true;
2834 if (pred
->num_codes
== 1)
2835 pred
->singleton
= code
;
2836 else if (pred
->num_codes
== 2)
2837 pred
->singleton
= UNKNOWN
;
2842 add_predicate (struct pred_data
*pred
)
2844 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2847 error ("duplicate predicate definition for '%s'", pred
->name
);
2851 *last_predicate
= pred
;
2852 last_predicate
= &pred
->next
;
2855 /* This array gives the initial content of the predicate table. It
2856 has entries for all predicates defined in recog.c. */
2858 struct std_pred_table
2862 bool allows_const_p
;
2863 RTX_CODE codes
[NUM_RTX_CODE
];
2866 static const struct std_pred_table std_preds
[] = {
2867 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2868 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
2869 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2870 {"register_operand", false, false, {SUBREG
, REG
}},
2871 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2872 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2873 {"immediate_operand", false, true, {UNKNOWN
}},
2874 {"const_int_operand", false, false, {CONST_INT
}},
2875 #if TARGET_SUPPORTS_WIDE_INT
2876 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2877 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2879 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2881 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2882 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2883 {"push_operand", false, false, {MEM
}},
2884 {"pop_operand", false, false, {MEM
}},
2885 {"memory_operand", false, false, {SUBREG
, MEM
}},
2886 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2887 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2889 LEU
, LTU
, GEU
, GTU
}},
2890 {"comparison_operator", false, false, {EQ
, NE
,
2897 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2899 /* Initialize the table of predicate definitions, starting with
2900 the information we have on generic predicates. */
2903 init_predicate_table (void)
2906 struct pred_data
*pred
;
2908 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2909 eq_struct_pred_data
, 0,
2912 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2914 pred
= XCNEW (struct pred_data
);
2915 pred
->name
= std_preds
[i
].name
;
2916 pred
->special
= std_preds
[i
].special
;
2918 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2919 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2921 if (std_preds
[i
].allows_const_p
)
2922 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2923 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2924 add_predicate_code (pred
, (enum rtx_code
) j
);
2926 add_predicate (pred
);
2930 /* These functions allow linkage with print-rtl.c. Also, some generators
2931 like to annotate their output with insn names. */
2933 /* Holds an array of names indexed by insn_code_number. */
2934 static char **insn_name_ptr
= 0;
2935 static int insn_name_ptr_size
= 0;
2938 get_insn_name (int code
)
2940 if (code
< insn_name_ptr_size
)
2941 return insn_name_ptr
[code
];
2947 record_insn_name (int code
, const char *name
)
2949 static const char *last_real_name
= "insn";
2950 static int last_real_code
= 0;
2953 if (insn_name_ptr_size
<= code
)
2956 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2957 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2958 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2959 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2960 insn_name_ptr_size
= new_size
;
2963 if (!name
|| name
[0] == '\0')
2965 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2966 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2970 last_real_name
= new_name
= xstrdup (name
);
2971 last_real_code
= code
;
2974 insn_name_ptr
[code
] = new_name
;
2977 /* Make STATS describe the operands that appear in rtx X. */
2980 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2990 code
= GET_CODE (x
);
2994 case MATCH_OPERATOR
:
2995 case MATCH_PARALLEL
:
2996 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
3003 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
3007 if (stats
->min_scratch_opno
== -1)
3008 stats
->min_scratch_opno
= XINT (x
, 0);
3010 stats
->min_scratch_opno
= MIN (stats
->min_scratch_opno
, XINT (x
, 0));
3011 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
3018 fmt
= GET_RTX_FORMAT (code
);
3019 len
= GET_RTX_LENGTH (code
);
3020 for (i
= 0; i
< len
; i
++)
3022 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
3023 get_pattern_stats_1 (stats
, XEXP (x
, i
));
3024 else if (fmt
[i
] == 'E')
3027 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3028 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
3033 /* Make STATS describe the operands that appear in instruction pattern
3037 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
3041 stats
->max_opno
= -1;
3042 stats
->max_dup_opno
= -1;
3043 stats
->min_scratch_opno
= -1;
3044 stats
->max_scratch_opno
= -1;
3045 stats
->num_dups
= 0;
3047 len
= GET_NUM_ELEM (pattern
);
3048 for (i
= 0; i
< len
; i
++)
3049 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
3051 stats
->num_generator_args
= stats
->max_opno
+ 1;
3052 stats
->num_insn_operands
= MAX (stats
->max_opno
,
3053 stats
->max_scratch_opno
) + 1;
3054 stats
->num_operand_vars
= MAX (stats
->max_opno
,
3055 MAX (stats
->max_dup_opno
,
3056 stats
->max_scratch_opno
)) + 1;
3059 /* Return the emit_* function that should be used for pattern X, or NULL
3060 if we can't pick a particular type at compile time and should instead
3061 fall back to "emit". */
3064 get_emit_function (rtx x
)
3066 switch (classify_insn (x
))
3072 return "emit_call_insn";
3075 return "emit_jump_insn";
3085 /* Return true if we must emit a barrier after pattern X. */
3088 needs_barrier_p (rtx x
)
3090 return (GET_CODE (x
) == SET
3091 && GET_CODE (SET_DEST (x
)) == PC
3092 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);
3097 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3098 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3099 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3100 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3101 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3102 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3103 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3104 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3105 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3106 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3107 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3109 /* An array of all optabs. Note that the same optab can appear more
3110 than once, with a different pattern. */
3111 optab_def optabs
[] = {
3112 { "unknown_optab", NULL
, NS
, ZS
, NS
, unknown_optab
, UNKNOWN
, UNKNOWN
, 0 },
3113 #include "optabs.def"
3116 /* The number of entries in optabs[]. */
3117 unsigned int num_optabs
= ARRAY_SIZE (optabs
);
3131 /* Return true if instruction NAME matches pattern PAT, storing information
3132 about the match in P if so. */
3135 match_pattern (optab_pattern
*p
, const char *name
, const char *pat
)
3137 bool force_float
= false;
3138 bool force_int
= false;
3139 bool force_partial_int
= false;
3140 bool force_fixed
= false;
3148 if (*pat
!= *name
++)
3160 force_partial_int
= 1;
3174 /* This loop will stop at the first prefix match, so
3175 look through the modes in reverse order, in case
3176 there are extra CC modes and CC is a prefix of the
3177 CC modes (as it should be). */
3178 for (i
= (MAX_MACHINE_MODE
) - 1; i
>= 0; i
--)
3181 for (p
= GET_MODE_NAME (i
), q
= name
; *p
; p
++, q
++)
3182 if (TOLOWER (*p
) != *q
)
3185 && (! force_int
|| mode_class
[i
] == MODE_INT
3186 || mode_class
[i
] == MODE_VECTOR_INT
)
3187 && (! force_partial_int
3188 || mode_class
[i
] == MODE_INT
3189 || mode_class
[i
] == MODE_PARTIAL_INT
3190 || mode_class
[i
] == MODE_VECTOR_INT
)
3192 || mode_class
[i
] == MODE_FLOAT
3193 || mode_class
[i
] == MODE_DECIMAL_FLOAT
3194 || mode_class
[i
] == MODE_COMPLEX_FLOAT
3195 || mode_class
[i
] == MODE_VECTOR_FLOAT
)
3197 || mode_class
[i
] == MODE_FRACT
3198 || mode_class
[i
] == MODE_UFRACT
3199 || mode_class
[i
] == MODE_ACCUM
3200 || mode_class
[i
] == MODE_UACCUM
3201 || mode_class
[i
] == MODE_VECTOR_FRACT
3202 || mode_class
[i
] == MODE_VECTOR_UFRACT
3203 || mode_class
[i
] == MODE_VECTOR_ACCUM
3204 || mode_class
[i
] == MODE_VECTOR_UACCUM
))
3210 name
+= strlen (GET_MODE_NAME (i
));
3217 force_partial_int
= false;
3218 force_float
= false;
3219 force_fixed
= false;
3229 /* Return true if NAME is the name of an optab, describing it in P if so. */
3232 find_optab (optab_pattern
*p
, const char *name
)
3234 if (*name
== 0 || *name
== '*')
3237 /* See if NAME matches one of the patterns we have for the optabs
3239 for (unsigned int pindex
= 0; pindex
< ARRAY_SIZE (optabs
); pindex
++)
3242 if (match_pattern (p
, name
, optabs
[pindex
].pattern
))
3245 p
->op
= optabs
[pindex
].op
;
3246 p
->sort_num
= (p
->op
<< 16) | (p
->m2
<< 8) | p
->m1
;