1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "gensupport.h"
30 #define MAX_OPERANDS 40
32 static rtx operand_data
[MAX_OPERANDS
];
33 static rtx match_operand_entries_in_pattern
[MAX_OPERANDS
];
34 static char used_operands_numbers
[MAX_OPERANDS
];
37 /* In case some macros used by files we include need it, define this here. */
42 static struct obstack obstack
;
43 struct obstack
*rtl_obstack
= &obstack
;
45 /* Counter for patterns that generate code: define_insn, define_expand,
46 define_split, define_peephole, and define_peephole2. See read_md_rtx().
47 Any define_insn_and_splits are already in separate queues so that the
48 insn and the splitter get a unique number also. */
49 static int sequence_num
;
51 static int predicable_default
;
52 static const char *predicable_true
;
53 static const char *predicable_false
;
55 static const char *subst_true
= "yes";
56 static const char *subst_false
= "no";
58 static htab_t condition_table
;
60 /* We initially queue all patterns, process the define_insn,
61 define_cond_exec and define_subst patterns, then return
62 them one at a time. */
69 struct queue_elem
*next
;
70 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
71 points to the generated DEFINE_SPLIT. */
72 struct queue_elem
*split
;
75 #define MNEMONIC_ATTR_NAME "mnemonic"
76 #define MNEMONIC_HTAB_SIZE 1024
78 static struct queue_elem
*define_attr_queue
;
79 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
80 static struct queue_elem
*define_pred_queue
;
81 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
82 static struct queue_elem
*define_insn_queue
;
83 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
84 static struct queue_elem
*define_cond_exec_queue
;
85 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
86 static struct queue_elem
*define_subst_queue
;
87 static struct queue_elem
**define_subst_tail
= &define_subst_queue
;
88 static struct queue_elem
*other_queue
;
89 static struct queue_elem
**other_tail
= &other_queue
;
90 static struct queue_elem
*define_subst_attr_queue
;
91 static struct queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
93 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
96 static void remove_constraints (rtx
);
97 static void process_rtx (rtx
, int);
99 static int is_predicable (struct queue_elem
*);
100 static void identify_predicable_attribute (void);
101 static int n_alternatives (const char *);
102 static void collect_insn_data (rtx
, int *, int *);
103 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
104 static const char *alter_test_for_insn (struct queue_elem
*,
105 struct queue_elem
*);
106 static char *shift_output_template (char *, const char *, int);
107 static const char *alter_output_for_insn (struct queue_elem
*,
110 static void process_one_cond_exec (struct queue_elem
*);
111 static void process_define_cond_exec (void);
112 static void init_predicate_table (void);
113 static void record_insn_name (int, const char *);
115 static bool has_subst_attribute (struct queue_elem
*, struct queue_elem
*);
116 static bool subst_pattern_match (rtx
, rtx
, int);
117 static int get_alternatives_number (rtx
, int *, int);
118 static const char * alter_output_for_subst_insn (rtx
, int);
119 static void alter_attrs_for_subst_insn (struct queue_elem
*, int);
120 static void process_substs_on_one_elem (struct queue_elem
*,
121 struct queue_elem
*);
122 static rtx
subst_dup (rtx
, int, int);
123 static void process_define_subst (void);
125 static const char * duplicate_alternatives (const char *, int);
126 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
128 typedef const char * (*constraints_handler_t
) (const char *, int);
129 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
130 static rtx
adjust_operands_numbers (rtx
);
131 static rtx
replace_duplicating_operands_in_pattern (rtx
);
133 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
134 the gensupport programs. */
137 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
140 rtx rt
= rtx_alloc (CONST_INT
);
146 /* Return the rtx pattern specified by the list of rtxes in a
147 define_insn or define_split. */
150 add_implicit_parallel (rtvec vec
)
152 if (GET_NUM_ELEM (vec
) == 1)
153 return RTVEC_ELT (vec
, 0);
156 rtx pattern
= rtx_alloc (PARALLEL
);
157 XVEC (pattern
, 0) = vec
;
162 /* Predicate handling.
164 We construct from the machine description a table mapping each
165 predicate to a list of the rtl codes it can possibly match. The
166 function 'maybe_both_true' uses it to deduce that there are no
167 expressions that can be matches by certain pairs of tree nodes.
168 Also, if a predicate can match only one code, we can hardwire that
169 code into the node testing the predicate.
171 Some predicates are flagged as special. validate_pattern will not
172 warn about modeless match_operand expressions if they have a
173 special predicate. Predicates that allow only constants are also
174 treated as special, for this purpose.
176 validate_pattern will warn about predicates that allow non-lvalues
177 when they appear in destination operands.
179 Calculating the set of rtx codes that can possibly be accepted by a
180 predicate expression EXP requires a three-state logic: any given
181 subexpression may definitively accept a code C (Y), definitively
182 reject a code C (N), or may have an indeterminate effect (I). N
183 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
194 We represent Y with 1, N with 0, I with 2. If any code is left in
195 an I state by the complete expression, we must assume that that
196 code can be accepted. */
202 #define TRISTATE_AND(a,b) \
203 ((a) == I ? ((b) == N ? N : I) : \
204 (b) == I ? ((a) == N ? N : I) : \
207 #define TRISTATE_OR(a,b) \
208 ((a) == I ? ((b) == Y ? Y : I) : \
209 (b) == I ? ((a) == Y ? Y : I) : \
212 #define TRISTATE_NOT(a) \
213 ((a) == I ? I : !(a))
215 /* 0 means no warning about that code yet, 1 means warned. */
216 static char did_you_mean_codes
[NUM_RTX_CODE
];
218 /* Recursively calculate the set of rtx codes accepted by the
219 predicate expression EXP, writing the result to CODES. LINENO is
220 the line number on which the directive containing EXP appeared. */
223 compute_test_codes (rtx exp
, int lineno
, char *codes
)
225 char op0_codes
[NUM_RTX_CODE
];
226 char op1_codes
[NUM_RTX_CODE
];
227 char op2_codes
[NUM_RTX_CODE
];
230 switch (GET_CODE (exp
))
233 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
234 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
235 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
236 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
240 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
241 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
242 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
243 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
246 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
247 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
248 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
252 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
253 compute_test_codes (XEXP (exp
, 0), lineno
, op0_codes
);
254 compute_test_codes (XEXP (exp
, 1), lineno
, op1_codes
);
255 compute_test_codes (XEXP (exp
, 2), lineno
, op2_codes
);
256 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
257 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
258 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
263 /* MATCH_CODE allows a specified list of codes. However, if it
264 does not apply to the top level of the expression, it does not
265 constrain the set of codes for the top level. */
266 if (XSTR (exp
, 1)[0] != '\0')
268 memset (codes
, Y
, NUM_RTX_CODE
);
272 memset (codes
, N
, NUM_RTX_CODE
);
274 const char *next_code
= XSTR (exp
, 0);
277 if (*next_code
== '\0')
279 error_with_line (lineno
, "empty match_code expression");
283 while ((code
= scan_comma_elt (&next_code
)) != 0)
285 size_t n
= next_code
- code
;
288 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
289 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
290 && GET_RTX_NAME (i
)[n
] == '\0')
298 error_with_line (lineno
,
299 "match_code \"%.*s\" matches nothing",
301 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
302 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
303 && GET_RTX_NAME (i
)[n
] == '\0'
304 && !did_you_mean_codes
[i
])
306 did_you_mean_codes
[i
] = 1;
307 message_with_line (lineno
, "(did you mean \"%s\"?)",
316 /* MATCH_OPERAND disallows the set of codes that the named predicate
317 disallows, and is indeterminate for the codes that it does allow. */
319 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
322 error_with_line (lineno
, "reference to unknown predicate '%s'",
326 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
327 codes
[i
] = p
->codes
[i
] ? I
: N
;
333 /* (match_test WHATEVER) is completely indeterminate. */
334 memset (codes
, I
, NUM_RTX_CODE
);
338 error_with_line (lineno
,
339 "'%s' cannot be used in predicates or constraints",
340 GET_RTX_NAME (GET_CODE (exp
)));
341 memset (codes
, I
, NUM_RTX_CODE
);
350 /* Return true if NAME is a valid predicate name. */
353 valid_predicate_name_p (const char *name
)
357 if (!ISALPHA (name
[0]) && name
[0] != '_')
359 for (p
= name
+ 1; *p
; p
++)
360 if (!ISALNUM (*p
) && *p
!= '_')
365 /* Process define_predicate directive DESC, which appears on line number
366 LINENO. Compute the set of codes that can be matched, and record this
367 as a known predicate. */
370 process_define_predicate (rtx desc
, int lineno
)
372 struct pred_data
*pred
;
373 char codes
[NUM_RTX_CODE
];
376 if (!valid_predicate_name_p (XSTR (desc
, 0)))
378 error_with_line (lineno
,
379 "%s: predicate name must be a valid C function name",
384 pred
= XCNEW (struct pred_data
);
385 pred
->name
= XSTR (desc
, 0);
386 pred
->exp
= XEXP (desc
, 1);
387 pred
->c_block
= XSTR (desc
, 2);
388 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
389 pred
->special
= true;
391 compute_test_codes (XEXP (desc
, 1), lineno
, codes
);
393 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
395 add_predicate_code (pred
, (enum rtx_code
) i
);
397 add_predicate (pred
);
403 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
406 static struct queue_elem
*
407 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
408 const char *filename
, int lineno
)
410 struct queue_elem
*e
= XNEW (struct queue_elem
);
412 e
->filename
= filename
;
417 *list_tail
= &e
->next
;
421 /* Remove element ELEM from QUEUE. */
423 remove_from_queue (struct queue_elem
*elem
, struct queue_elem
**queue
)
425 struct queue_elem
*prev
, *e
;
427 for (e
= *queue
; e
; e
= e
->next
)
437 prev
->next
= elem
->next
;
442 /* Build a define_attr for an binary attribute with name NAME and
443 possible values "yes" and "no", and queue it. */
445 add_define_attr (const char *name
)
447 struct queue_elem
*e
= XNEW (struct queue_elem
);
448 rtx t1
= rtx_alloc (DEFINE_ATTR
);
450 XSTR (t1
, 1) = "no,yes";
451 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
452 XSTR (XEXP (t1
, 2), 0) = "yes";
454 e
->filename
= "built-in";
456 e
->next
= define_attr_queue
;
457 define_attr_queue
= e
;
461 /* Recursively remove constraints from an rtx. */
464 remove_constraints (rtx part
)
467 const char *format_ptr
;
472 if (GET_CODE (part
) == MATCH_OPERAND
)
474 else if (GET_CODE (part
) == MATCH_SCRATCH
)
477 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
479 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
480 switch (*format_ptr
++)
484 remove_constraints (XEXP (part
, i
));
487 if (XVEC (part
, i
) != NULL
)
488 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
489 remove_constraints (XVECEXP (part
, i
, j
));
494 /* Process a top level rtx in some way, queuing as appropriate. */
497 process_rtx (rtx desc
, int lineno
)
499 switch (GET_CODE (desc
))
502 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
505 case DEFINE_COND_EXEC
:
506 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
510 queue_pattern (desc
, &define_subst_tail
, read_md_filename
, lineno
);
513 case DEFINE_SUBST_ATTR
:
514 queue_pattern (desc
, &define_subst_attr_tail
, read_md_filename
, lineno
);
518 case DEFINE_ENUM_ATTR
:
519 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
522 case DEFINE_PREDICATE
:
523 case DEFINE_SPECIAL_PREDICATE
:
524 process_define_predicate (desc
, lineno
);
527 case DEFINE_CONSTRAINT
:
528 case DEFINE_REGISTER_CONSTRAINT
:
529 case DEFINE_MEMORY_CONSTRAINT
:
530 case DEFINE_ADDRESS_CONSTRAINT
:
531 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
534 case DEFINE_INSN_AND_SPLIT
:
536 const char *split_cond
;
540 struct queue_elem
*insn_elem
;
541 struct queue_elem
*split_elem
;
543 /* Create a split with values from the insn_and_split. */
544 split
= rtx_alloc (DEFINE_SPLIT
);
546 i
= XVECLEN (desc
, 1);
547 XVEC (split
, 0) = rtvec_alloc (i
);
550 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
551 remove_constraints (XVECEXP (split
, 0, i
));
554 /* If the split condition starts with "&&", append it to the
555 insn condition to create the new split condition. */
556 split_cond
= XSTR (desc
, 4);
557 if (split_cond
[0] == '&' && split_cond
[1] == '&')
559 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
560 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
562 XSTR (split
, 1) = split_cond
;
563 XVEC (split
, 2) = XVEC (desc
, 5);
564 XSTR (split
, 3) = XSTR (desc
, 6);
566 /* Fix up the DEFINE_INSN. */
567 attr
= XVEC (desc
, 7);
568 PUT_CODE (desc
, DEFINE_INSN
);
569 XVEC (desc
, 4) = attr
;
573 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
576 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
577 insn_elem
->split
= split_elem
;
582 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
587 /* Return true if attribute PREDICABLE is true for ELEM, which holds
591 is_predicable (struct queue_elem
*elem
)
593 rtvec vec
= XVEC (elem
->data
, 4);
598 return predicable_default
;
600 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
602 rtx sub
= RTVEC_ELT (vec
, i
);
603 switch (GET_CODE (sub
))
606 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
608 value
= XSTR (sub
, 1);
613 case SET_ATTR_ALTERNATIVE
:
614 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
616 error_with_line (elem
->lineno
,
617 "multiple alternatives for `predicable'");
623 if (GET_CODE (SET_DEST (sub
)) != ATTR
624 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
627 if (GET_CODE (sub
) == CONST_STRING
)
629 value
= XSTR (sub
, 0);
633 /* ??? It would be possible to handle this if we really tried.
634 It's not easy though, and I'm not going to bother until it
635 really proves necessary. */
636 error_with_line (elem
->lineno
,
637 "non-constant value for `predicable'");
645 return predicable_default
;
648 /* Find out which value we're looking at. Multiple alternatives means at
649 least one is predicable. */
650 if (strchr (value
, ',') != NULL
)
652 if (strcmp (value
, predicable_true
) == 0)
654 if (strcmp (value
, predicable_false
) == 0)
657 error_with_line (elem
->lineno
,
658 "unknown value `%s' for `predicable' attribute", value
);
662 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
664 change_subst_attribute (struct queue_elem
*elem
,
665 struct queue_elem
*subst_elem
,
666 const char *new_value
)
668 rtvec attrs_vec
= XVEC (elem
->data
, 4);
669 const char *subst_name
= XSTR (subst_elem
->data
, 0);
675 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
677 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
678 if (GET_CODE (cur_attr
) != SET_ATTR
)
680 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
682 XSTR (cur_attr
, 1) = new_value
;
688 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
689 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
690 DEFINE_SUBST isn't applied to patterns without such attribute. In other
691 words, we suppose the default value of the attribute to be 'no' since it is
692 always generated automaticaly in read-rtl.c. */
694 has_subst_attribute (struct queue_elem
*elem
, struct queue_elem
*subst_elem
)
696 rtvec attrs_vec
= XVEC (elem
->data
, 4);
697 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
703 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
705 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
706 switch (GET_CODE (cur_attr
))
709 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
711 value
= XSTR (cur_attr
, 1);
717 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
718 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
720 cur_attr
= SET_SRC (cur_attr
);
721 if (GET_CODE (cur_attr
) == CONST_STRING
)
723 value
= XSTR (cur_attr
, 0);
727 /* Only (set_attr "subst" "yes/no") and
728 (set (attr "subst" (const_string "yes/no")))
729 are currently allowed. */
730 error_with_line (elem
->lineno
,
731 "unsupported value for `%s'", subst_name
);
734 case SET_ATTR_ALTERNATIVE
:
735 error_with_line (elem
->lineno
,
736 "%s: `set_attr_alternative' is unsupported by "
738 XSTR (elem
->data
, 0));
750 if (strcmp (value
, subst_true
) == 0)
752 if (strcmp (value
, subst_false
) == 0)
755 error_with_line (elem
->lineno
,
756 "unknown value `%s' for `%s' attribute", value
, subst_name
);
760 /* Compare RTL-template of original define_insn X to input RTL-template of
761 define_subst PT. Return 1 if the templates match, 0 otherwise.
762 During the comparison, the routine also fills global_array OPERAND_DATA. */
764 subst_pattern_match (rtx x
, rtx pt
, int lineno
)
766 RTX_CODE code
, code_pt
;
768 const char *fmt
, *pred_name
;
771 code_pt
= GET_CODE (pt
);
773 if (code_pt
== MATCH_OPERAND
)
775 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
776 always accept them. */
777 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
778 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
779 return false; /* Modes don't match. */
781 if (code
== MATCH_OPERAND
)
783 pred_name
= XSTR (pt
, 1);
784 if (pred_name
[0] != 0)
786 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
787 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
788 return false; /* Predicates don't match. */
792 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
793 operand_data
[XINT (pt
, 0)] = x
;
797 if (code_pt
== MATCH_OPERATOR
)
799 int x_vecexp_pos
= -1;
802 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
805 /* In case X is also match_operator, compare predicates. */
806 if (code
== MATCH_OPERATOR
)
808 pred_name
= XSTR (pt
, 1);
809 if (pred_name
[0] != 0)
811 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
812 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
818 MATCH_OPERATOR in input template could match in original template
819 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
820 In the first case operands are at (XVECEXP (x, 2, j)), in the second
821 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
822 X_VECEXP_POS variable shows, where to look for these operands. */
824 || code
== UNSPEC_VOLATILE
)
826 else if (code
== MATCH_OPERATOR
)
831 /* MATCH_OPERATOR or UNSPEC case. */
832 if (x_vecexp_pos
>= 0)
834 /* Compare operands number in X and PT. */
835 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
837 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
838 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
839 XVECEXP (pt
, 2, j
), lineno
))
843 /* Ordinary operator. */
846 /* Compare operands number in X and PT.
847 We count operands differently for X and PT since we compare
848 an operator (with operands directly in RTX) and MATCH_OPERATOR
849 (that has a vector with operands). */
850 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
852 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
853 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), lineno
))
857 /* Store the operand to OPERAND_DATA array. */
858 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
859 operand_data
[XINT (pt
, 0)] = x
;
863 if (code_pt
== MATCH_PAR_DUP
864 || code_pt
== MATCH_DUP
865 || code_pt
== MATCH_OP_DUP
866 || code_pt
== MATCH_SCRATCH
867 || code_pt
== MATCH_PARALLEL
)
869 /* Currently interface for these constructions isn't defined -
870 probably they aren't needed in input template of define_subst at all.
871 So, for now their usage in define_subst is forbidden. */
872 error_with_line (lineno
, "%s cannot be used in define_subst",
873 GET_RTX_NAME (code_pt
));
876 gcc_assert (code
!= MATCH_PAR_DUP
877 && code_pt
!= MATCH_DUP
878 && code_pt
!= MATCH_OP_DUP
879 && code_pt
!= MATCH_SCRATCH
880 && code_pt
!= MATCH_PARALLEL
881 && code_pt
!= MATCH_OPERAND
882 && code_pt
!= MATCH_OPERATOR
);
883 /* If PT is none of the handled above, then we match only expressions with
884 the same code in X. */
888 fmt
= GET_RTX_FORMAT (code_pt
);
889 len
= GET_RTX_LENGTH (code_pt
);
891 for (i
= 0; i
< len
; i
++)
898 case 'i': case 'r': case 'w': case 's':
902 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), lineno
))
907 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
909 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
910 if (!subst_pattern_match (XVECEXP (x
, i
, j
), XVECEXP (pt
, i
, j
),
923 /* Examine the attribute "predicable"; discover its boolean values
927 identify_predicable_attribute (void)
929 struct queue_elem
*elem
;
930 char *p_true
, *p_false
;
933 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
934 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
935 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
938 error_with_line (define_cond_exec_queue
->lineno
,
939 "attribute `predicable' not defined");
943 value
= XSTR (elem
->data
, 1);
944 p_false
= xstrdup (value
);
945 p_true
= strchr (p_false
, ',');
946 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
948 error_with_line (elem
->lineno
, "attribute `predicable' is not a boolean");
954 predicable_true
= p_true
;
955 predicable_false
= p_false
;
957 switch (GET_CODE (XEXP (elem
->data
, 2)))
960 value
= XSTR (XEXP (elem
->data
, 2), 0);
964 error_with_line (elem
->lineno
, "attribute `predicable' cannot be const");
969 error_with_line (elem
->lineno
,
970 "attribute `predicable' must have a constant default");
975 if (strcmp (value
, p_true
) == 0)
976 predicable_default
= 1;
977 else if (strcmp (value
, p_false
) == 0)
978 predicable_default
= 0;
981 error_with_line (elem
->lineno
,
982 "unknown value `%s' for `predicable' attribute", value
);
987 /* Return the number of alternatives in constraint S. */
990 n_alternatives (const char *s
)
1001 /* The routine scans rtl PATTERN, find match_operand in it and counts
1002 number of alternatives. If PATTERN contains several match_operands
1003 with different number of alternatives, error is emitted, and the
1004 routine returns 0. If all match_operands in PATTERN have the same
1005 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1006 Argument LINENO is used in when the error is emitted. */
1008 get_alternatives_number (rtx pattern
, int *n_alt
, int lineno
)
1017 code
= GET_CODE (pattern
);
1021 i
= n_alternatives (XSTR (pattern
, 2));
1022 /* n_alternatives returns 1 if constraint string is empty -
1023 here we fix it up. */
1024 if (!*(XSTR (pattern
, 2)))
1029 else if (i
&& i
!= *n_alt
)
1031 error_with_line (lineno
,
1032 "wrong number of alternatives in operand %d",
1041 fmt
= GET_RTX_FORMAT (code
);
1042 len
= GET_RTX_LENGTH (code
);
1043 for (i
= 0; i
< len
; i
++)
1048 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, lineno
))
1053 if (XVEC (pattern
, i
) == NULL
)
1057 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1058 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
),
1063 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1073 /* Determine how many alternatives there are in INSN, and how many
1077 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1083 code
= GET_CODE (pattern
);
1087 i
= n_alternatives (XSTR (pattern
, 2));
1088 *palt
= (i
> *palt
? i
: *palt
);
1091 case MATCH_OPERATOR
:
1093 case MATCH_PARALLEL
:
1094 i
= XINT (pattern
, 0);
1103 fmt
= GET_RTX_FORMAT (code
);
1104 len
= GET_RTX_LENGTH (code
);
1105 for (i
= 0; i
< len
; i
++)
1110 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1114 if (XVEC (pattern
, i
) == NULL
)
1118 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1119 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1122 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
1132 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
1138 code
= GET_CODE (pattern
);
1143 const char *c
= XSTR (pattern
, 2);
1145 if (n_alternatives (c
) != 1)
1147 error_with_line (lineno
, "too many alternatives for operand %d",
1152 /* Replicate C as needed to fill out ALT alternatives. */
1153 if (c
&& *c
&& alt
> 1)
1155 size_t c_len
= strlen (c
);
1156 size_t len
= alt
* (c_len
+ 1);
1157 char *new_c
= XNEWVEC (char, len
);
1159 memcpy (new_c
, c
, c_len
);
1160 for (i
= 1; i
< alt
; ++i
)
1162 new_c
[i
* (c_len
+ 1) - 1] = ',';
1163 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1165 new_c
[len
- 1] = '\0';
1166 XSTR (pattern
, 2) = new_c
;
1171 case MATCH_OPERATOR
:
1173 case MATCH_PARALLEL
:
1174 XINT (pattern
, 0) += max_op
;
1181 fmt
= GET_RTX_FORMAT (code
);
1182 len
= GET_RTX_LENGTH (code
);
1183 for (i
= 0; i
< len
; i
++)
1190 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
1197 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1199 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1200 alt
, max_op
, lineno
);
1206 case 'i': case 'r': case 'w': case '0': case 's':
1217 /* Duplicate constraints in PATTERN. If pattern is from original
1218 rtl-template, we need to duplicate each alternative - for that we
1219 need to use duplicate_each_alternative () as a functor ALTER.
1220 If pattern is from output-pattern of define_subst, we need to
1221 duplicate constraints in another way - with duplicate_alternatives ().
1222 N_DUP is multiplication factor. */
1224 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1230 code
= GET_CODE (pattern
);
1234 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1241 fmt
= GET_RTX_FORMAT (code
);
1242 len
= GET_RTX_LENGTH (code
);
1243 for (i
= 0; i
< len
; i
++)
1250 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1256 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1258 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1264 case 'i': case 'r': case 'w': case '0': case 's':
1276 alter_test_for_insn (struct queue_elem
*ce_elem
,
1277 struct queue_elem
*insn_elem
)
1279 return join_c_conditions (XSTR (ce_elem
->data
, 1),
1280 XSTR (insn_elem
->data
, 2));
1283 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1284 to take "ce_enabled" into account. Return the new expression. */
1286 modify_attr_enabled_ce (rtx val
)
1290 eq_attr
= rtx_alloc (EQ_ATTR
);
1291 ite
= rtx_alloc (IF_THEN_ELSE
);
1292 str
= rtx_alloc (CONST_STRING
);
1294 XSTR (eq_attr
, 0) = "ce_enabled";
1295 XSTR (eq_attr
, 1) = "yes";
1296 XSTR (str
, 0) = "no";
1297 XEXP (ite
, 0) = eq_attr
;
1298 XEXP (ite
, 1) = val
;
1299 XEXP (ite
, 2) = str
;
1304 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1305 from a define_insn pattern. We must modify the "predicable" attribute
1306 to be named "ce_enabled", and also change any "enabled" attribute that's
1307 present so that it takes ce_enabled into account.
1308 We rely on the fact that INSN was created with copy_rtx, and modify data
1312 alter_attrs_for_insn (rtx insn
)
1314 static bool global_changes_made
= false;
1315 rtvec vec
= XVEC (insn
, 4);
1319 int predicable_idx
= -1;
1320 int enabled_idx
= -1;
1326 num_elem
= GET_NUM_ELEM (vec
);
1327 for (i
= num_elem
- 1; i
>= 0; --i
)
1329 rtx sub
= RTVEC_ELT (vec
, i
);
1330 switch (GET_CODE (sub
))
1333 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1336 XSTR (sub
, 0) = "ce_enabled";
1338 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1341 XSTR (sub
, 0) = "nonce_enabled";
1345 case SET_ATTR_ALTERNATIVE
:
1346 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1347 /* We already give an error elsewhere. */
1349 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1352 XSTR (sub
, 0) = "nonce_enabled";
1357 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1359 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1361 sub
= SET_SRC (sub
);
1362 if (GET_CODE (sub
) == CONST_STRING
)
1365 XSTR (sub
, 0) = "ce_enabled";
1368 /* We already give an error elsewhere. */
1372 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1375 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1383 if (predicable_idx
== -1)
1386 if (!global_changes_made
)
1388 struct queue_elem
*elem
;
1390 global_changes_made
= true;
1391 add_define_attr ("ce_enabled");
1392 add_define_attr ("nonce_enabled");
1394 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1395 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1397 XEXP (elem
->data
, 2)
1398 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1401 if (enabled_idx
== -1)
1404 new_vec
= rtvec_alloc (num_elem
+ 1);
1405 for (i
= 0; i
< num_elem
; i
++)
1406 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1407 val
= rtx_alloc (IF_THEN_ELSE
);
1408 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1409 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1410 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1411 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1412 XSTR (XEXP (val
, 0), 1) = "yes";
1413 XSTR (XEXP (val
, 1), 0) = "yes";
1414 XSTR (XEXP (val
, 2), 0) = "no";
1415 set
= rtx_alloc (SET
);
1416 SET_DEST (set
) = rtx_alloc (ATTR
);
1417 XSTR (SET_DEST (set
), 0) = "enabled";
1418 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1419 RTVEC_ELT (new_vec
, i
) = set
;
1420 XVEC (insn
, 4) = new_vec
;
1423 /* As number of constraints is changed after define_subst, we need to
1424 process attributes as well - we need to duplicate them the same way
1425 that we duplicated constraints in original pattern
1426 ELEM is a queue element, containing our rtl-template,
1427 N_DUP - multiplication factor. */
1429 alter_attrs_for_subst_insn (struct queue_elem
* elem
, int n_dup
)
1431 rtvec vec
= XVEC (elem
->data
, 4);
1435 if (n_dup
< 2 || ! vec
)
1438 num_elem
= GET_NUM_ELEM (vec
);
1439 for (i
= num_elem
- 1; i
>= 0; --i
)
1441 rtx sub
= RTVEC_ELT (vec
, i
);
1442 switch (GET_CODE (sub
))
1445 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1446 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1449 case SET_ATTR_ALTERNATIVE
:
1451 error_with_line (elem
->lineno
,
1452 "%s: `define_subst' does not support attributes "
1453 "assigned by `set' and `set_attr_alternative'",
1454 XSTR (elem
->data
, 0));
1463 /* Adjust all of the operand numbers in SRC to match the shift they'll
1464 get from an operand displacement of DISP. Return a pointer after the
1468 shift_output_template (char *dest
, const char *src
, int disp
)
1477 if (ISDIGIT ((unsigned char) c
))
1479 else if (ISALPHA (c
))
1492 alter_output_for_insn (struct queue_elem
*ce_elem
,
1493 struct queue_elem
*insn_elem
,
1494 int alt
, int max_op
)
1496 const char *ce_out
, *insn_out
;
1498 size_t len
, ce_len
, insn_len
;
1500 /* ??? Could coordinate with genoutput to not duplicate code here. */
1502 ce_out
= XSTR (ce_elem
->data
, 2);
1503 insn_out
= XTMPL (insn_elem
->data
, 3);
1504 if (!ce_out
|| *ce_out
== '\0')
1507 ce_len
= strlen (ce_out
);
1508 insn_len
= strlen (insn_out
);
1510 if (*insn_out
== '*')
1511 /* You must take care of the predicate yourself. */
1514 if (*insn_out
== '@')
1516 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1517 p
= result
= XNEWVEC (char, len
);
1523 while (ISSPACE ((unsigned char) *insn_out
));
1525 if (*insn_out
!= '#')
1527 p
= shift_output_template (p
, ce_out
, max_op
);
1533 while (*insn_out
&& *insn_out
!= '\n');
1540 len
= ce_len
+ 1 + insn_len
+ 1;
1541 result
= XNEWVEC (char, len
);
1543 p
= shift_output_template (result
, ce_out
, max_op
);
1545 memcpy (p
, insn_out
, insn_len
+ 1);
1551 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1552 string, duplicated N_DUP times. */
1555 duplicate_alternatives (const char * str
, int n_dup
)
1557 int i
, len
, new_len
;
1564 while (ISSPACE (*str
))
1572 new_len
= (len
+ 1) * n_dup
;
1574 sp
= result
= XNEWVEC (char, new_len
);
1576 /* Global modifier characters mustn't be duplicated: skip if found. */
1577 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1583 /* Copy original constraints N_DUP times. */
1584 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1586 memcpy (sp
, cp
, len
);
1587 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1593 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1594 each alternative from the original string is duplicated N_DUP times. */
1596 duplicate_each_alternative (const char * str
, int n_dup
)
1598 int i
, len
, new_len
;
1599 char *result
, *sp
, *ep
, *cp
;
1604 while (ISSPACE (*str
))
1612 new_len
= (strlen (cp
) + 1) * n_dup
;
1614 sp
= result
= XNEWVEC (char, new_len
);
1616 /* Global modifier characters mustn't be duplicated: skip if found. */
1617 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1622 if ((ep
= strchr (cp
, ',')) != NULL
)
1626 /* Copy a constraint N_DUP times. */
1627 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1629 memcpy (sp
, cp
, len
);
1630 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1640 /* Alter the output of INSN whose pattern was modified by
1641 DEFINE_SUBST. We must replicate output strings according
1642 to the new number of alternatives ALT in substituted pattern.
1643 If ALT equals 1, output has one alternative or defined by C
1644 code, then output is returned without any changes. */
1647 alter_output_for_subst_insn (rtx insn
, int alt
)
1649 const char *insn_out
, *sp
;
1650 char *old_out
, *new_out
, *cp
;
1653 insn_out
= XTMPL (insn
, 3);
1655 if (alt
< 2 || *insn_out
== '*' || *insn_out
!= '@')
1658 old_out
= XNEWVEC (char, strlen (insn_out
)),
1661 while (ISSPACE (*sp
) || *sp
== '@')
1665 old_out
[i
++] = *sp
++;
1667 new_len
= alt
* (i
+ 1) + 1;
1669 new_out
= XNEWVEC (char, new_len
);
1672 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= i
+ 1)
1674 memcpy (cp
, old_out
, i
);
1675 *(cp
+i
) = (j
== alt
- 1) ? '\0' : '\n';
1681 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1684 process_one_cond_exec (struct queue_elem
*ce_elem
)
1686 struct queue_elem
*insn_elem
;
1687 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1689 int alternatives
, max_operand
;
1690 rtx pred
, insn
, pattern
, split
;
1694 if (! is_predicable (insn_elem
))
1699 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1702 if (XVECLEN (ce_elem
->data
, 0) != 1)
1704 error_with_line (ce_elem
->lineno
, "too many patterns in predicate");
1708 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1709 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1714 /* Construct a new pattern for the new insn. */
1715 insn
= copy_rtx (insn_elem
->data
);
1716 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1717 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1718 XSTR (insn
, 0) = new_name
;
1719 pattern
= rtx_alloc (COND_EXEC
);
1720 XEXP (pattern
, 0) = pred
;
1721 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
1722 XVEC (insn
, 1) = rtvec_alloc (1);
1723 XVECEXP (insn
, 1, 0) = pattern
;
1725 if (XVEC (ce_elem
->data
, 3) != NULL
)
1727 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1728 + XVECLEN (ce_elem
->data
, 3));
1731 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1732 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1734 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1735 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1737 XVEC (insn
, 4) = attributes
;
1740 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1741 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1742 alternatives
, max_operand
);
1743 alter_attrs_for_insn (insn
);
1745 /* Put the new pattern on the `other' list so that it
1746 (a) is not reprocessed by other define_cond_exec patterns
1747 (b) appears after all normal define_insn patterns.
1749 ??? B is debatable. If one has normal insns that match
1750 cond_exec patterns, they will be preferred over these
1751 generated patterns. Whether this matters in practice, or if
1752 it's a good thing, or whether we should thread these new
1753 patterns into the define_insn chain just after their generator
1754 is something we'll have to experiment with. */
1756 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
1759 if (!insn_elem
->split
)
1762 /* If the original insn came from a define_insn_and_split,
1763 generate a new split to handle the predicated insn. */
1764 split
= copy_rtx (insn_elem
->split
->data
);
1765 /* Predicate the pattern matched by the split. */
1766 pattern
= rtx_alloc (COND_EXEC
);
1767 XEXP (pattern
, 0) = pred
;
1768 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
1769 XVEC (split
, 0) = rtvec_alloc (1);
1770 XVECEXP (split
, 0, 0) = pattern
;
1772 /* Predicate all of the insns generated by the split. */
1773 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1775 pattern
= rtx_alloc (COND_EXEC
);
1776 XEXP (pattern
, 0) = pred
;
1777 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1778 XVECEXP (split
, 2, i
) = pattern
;
1780 /* Add the new split to the queue. */
1781 queue_pattern (split
, &other_tail
, read_md_filename
,
1782 insn_elem
->split
->lineno
);
1786 /* Try to apply define_substs to the given ELEM.
1787 Only define_substs, specified via attributes would be applied.
1788 If attribute, requiring define_subst, is set, but no define_subst
1789 was applied, ELEM would be deleted. */
1792 process_substs_on_one_elem (struct queue_elem
*elem
,
1793 struct queue_elem
*queue
)
1795 struct queue_elem
*subst_elem
;
1796 int i
, j
, patterns_match
;
1798 for (subst_elem
= define_subst_queue
;
1799 subst_elem
; subst_elem
= subst_elem
->next
)
1801 int alternatives
, alternatives_subst
;
1803 rtvec subst_pattern_vec
;
1805 if (!has_subst_attribute (elem
, subst_elem
))
1808 /* Compare original rtl-pattern from define_insn with input
1809 pattern from define_subst.
1810 Also, check if numbers of alternatives are the same in all
1812 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1816 alternatives_subst
= -1;
1817 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1819 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1820 XVECEXP (subst_elem
->data
, 1, j
),
1821 subst_elem
->lineno
))
1827 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1828 &alternatives
, subst_elem
->lineno
))
1835 /* Check if numbers of alternatives are the same in all
1836 match_operands in output template of define_subst. */
1837 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1839 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1840 &alternatives_subst
,
1841 subst_elem
->lineno
))
1848 if (!patterns_match
)
1851 /* Clear array in which we save occupied indexes of operands. */
1852 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1854 /* Create a pattern, based on the output one from define_subst. */
1855 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1856 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1858 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1860 /* Duplicate constraints in substitute-pattern. */
1861 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1862 duplicate_each_alternative
);
1864 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1866 /* Substitute match_dup and match_op_dup in the new pattern and
1867 duplicate constraints. */
1868 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1869 alternatives_subst
);
1871 replace_duplicating_operands_in_pattern (subst_pattern
);
1873 /* We don't need any constraints in DEFINE_EXPAND. */
1874 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1875 remove_constraints (subst_pattern
);
1877 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1879 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1881 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1882 match_operand_entries_in_pattern
[i
] = NULL
;
1884 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1886 XTMPL (elem
->data
, 3) =
1887 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1888 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1891 /* Recalculate condition, joining conditions from original and
1892 DEFINE_SUBST input patterns. */
1893 XSTR (elem
->data
, 2) = join_c_conditions (XSTR (subst_elem
->data
, 2),
1894 XSTR (elem
->data
, 2));
1895 /* Mark that subst was applied by changing attribute from "yes"
1897 change_subst_attribute (elem
, subst_elem
, subst_false
);
1900 /* If ELEM contains a subst attribute with value "yes", then we
1901 expected that a subst would be applied, but it wasn't - so,
1902 we need to remove that elementto avoid duplicating. */
1903 for (subst_elem
= define_subst_queue
;
1904 subst_elem
; subst_elem
= subst_elem
->next
)
1906 if (has_subst_attribute (elem
, subst_elem
))
1908 remove_from_queue (elem
, &queue
);
1914 /* This is a subroutine of mark_operands_used_in_match_dup.
1915 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1917 mark_operands_from_match_dup (rtx pattern
)
1920 int i
, j
, len
, opno
;
1922 if (GET_CODE (pattern
) == MATCH_OPERAND
1923 || GET_CODE (pattern
) == MATCH_OPERATOR
1924 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1926 opno
= XINT (pattern
, 0);
1927 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1928 used_operands_numbers
[opno
] = 1;
1930 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1931 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1932 for (i
= 0; i
< len
; i
++)
1937 mark_operands_from_match_dup (XEXP (pattern
, i
));
1940 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1941 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
1947 /* This is a subroutine of adjust_operands_numbers.
1948 It goes through all expressions in PATTERN and when MATCH_DUP is
1949 met, all MATCH_OPERANDs inside it is marked as occupied. The
1950 process of marking is done by routin mark_operands_from_match_dup. */
1952 mark_operands_used_in_match_dup (rtx pattern
)
1955 int i
, j
, len
, opno
;
1957 if (GET_CODE (pattern
) == MATCH_DUP
)
1959 opno
= XINT (pattern
, 0);
1960 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1961 mark_operands_from_match_dup (operand_data
[opno
]);
1964 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1965 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1966 for (i
= 0; i
< len
; i
++)
1971 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
1974 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1975 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
1981 /* This is subroutine of renumerate_operands_in_pattern.
1982 It finds first not-occupied operand-index. */
1984 find_first_unused_number_of_operand ()
1987 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1988 if (!used_operands_numbers
[i
])
1990 return MAX_OPERANDS
;
1993 /* This is subroutine of adjust_operands_numbers.
1994 It visits all expressions in PATTERN and assigns not-occupied
1995 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1998 renumerate_operands_in_pattern (rtx pattern
)
2002 int i
, j
, len
, new_opno
;
2003 code
= GET_CODE (pattern
);
2005 if (code
== MATCH_OPERAND
2006 || code
== MATCH_OPERATOR
)
2008 new_opno
= find_first_unused_number_of_operand ();
2009 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
2010 XINT (pattern
, 0) = new_opno
;
2011 used_operands_numbers
[new_opno
] = 1;
2014 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2015 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2016 for (i
= 0; i
< len
; i
++)
2021 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2024 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2025 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2031 /* If output pattern of define_subst contains MATCH_DUP, then this
2032 expression would be replaced with the pattern, matched with
2033 MATCH_OPERAND from input pattern. This pattern could contain any
2034 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2035 that a MATCH_OPERAND from output_pattern (if any) would have the
2036 same number, as MATCH_OPERAND from copied pattern. To avoid such
2037 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2038 laying in the output pattern outside of MATCH_DUPs. */
2040 adjust_operands_numbers (rtx pattern
)
2042 mark_operands_used_in_match_dup (pattern
);
2044 renumerate_operands_in_pattern (pattern
);
2049 /* Generate RTL expression
2053 generate_match_dup (int opno
)
2055 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2056 PUT_CODE (return_rtx
, MATCH_DUP
);
2057 XINT (return_rtx
, 0) = opno
;
2061 /* This routine checks all match_operands in PATTERN and if some of
2062 have the same index, it replaces all of them except the first one to
2064 Usually, match_operands with the same indexes are forbidden, but
2065 after define_subst copy an RTL-expression from original template,
2066 indexes of existed and just-copied match_operands could coincide.
2067 To fix it, we replace one of them with match_dup. */
2069 replace_duplicating_operands_in_pattern (rtx pattern
)
2072 int i
, j
, len
, opno
;
2075 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2077 opno
= XINT (pattern
, 0);
2078 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2079 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2081 match_operand_entries_in_pattern
[opno
] = pattern
;
2086 /* Compare predicates before replacing with match_dup. */
2087 if (strcmp (XSTR (pattern
, 1),
2088 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2090 error ("duplicated match_operands with different predicates were"
2094 return generate_match_dup (opno
);
2097 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2098 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2099 for (i
= 0; i
< len
; i
++)
2104 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2106 XEXP (pattern
, i
) = mdup
;
2109 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2112 replace_duplicating_operands_in_pattern (XVECEXP
2115 XVECEXP (pattern
, i
, j
) = mdup
;
2123 /* The routine modifies given input PATTERN of define_subst, replacing
2124 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2125 pattern, whose operands are stored in OPERAND_DATA array.
2126 It also duplicates constraints in operands - constraints from
2127 define_insn operands are duplicated N_SUBST_ALT times, constraints
2128 from define_subst operands are duplicated N_ALT times.
2129 After the duplication, returned output rtl-pattern contains every
2130 combination of input constraints Vs constraints from define_subst
2133 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2137 int i
, j
, len
, opno
;
2139 code
= GET_CODE (pattern
);
2144 opno
= XINT (pattern
, 0);
2146 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2148 if (operand_data
[opno
])
2150 pattern
= copy_rtx (operand_data
[opno
]);
2152 /* Duplicate constraints. */
2153 pattern
= alter_constraints (pattern
, n_subst_alt
,
2154 duplicate_alternatives
);
2162 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2163 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2164 for (i
= 0; i
< len
; i
++)
2169 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2170 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2171 n_alt
, n_subst_alt
);
2174 if (XVEC (pattern
, i
) == NULL
)
2177 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2178 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2179 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2180 n_alt
, n_subst_alt
);
2183 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
2193 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2194 patterns appropriately. */
2197 process_define_cond_exec (void)
2199 struct queue_elem
*elem
;
2201 identify_predicable_attribute ();
2205 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2206 process_one_cond_exec (elem
);
2209 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2210 DEFINE_EXPAND patterns appropriately. */
2213 process_define_subst (void)
2215 struct queue_elem
*elem
, *elem_attr
;
2217 /* Check if each define_subst has corresponding define_subst_attr. */
2218 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2220 for (elem_attr
= define_subst_attr_queue
;
2222 elem_attr
= elem_attr
->next
)
2223 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2226 error_with_line (elem
->lineno
,
2227 "%s: `define_subst' must have at least one "
2228 "corresponding `define_subst_attr'",
2229 XSTR (elem
->data
, 0));
2236 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2237 process_substs_on_one_elem (elem
, define_insn_queue
);
2238 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2240 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2242 process_substs_on_one_elem (elem
, other_queue
);
2246 /* A read_md_files callback for reading an rtx. */
2249 rtx_handle_directive (int lineno
, const char *rtx_name
)
2253 if (read_rtx (rtx_name
, &queue
))
2254 for (x
= queue
; x
; x
= XEXP (x
, 1))
2255 process_rtx (XEXP (x
, 0), lineno
);
2258 /* Comparison function for the mnemonic hash table. */
2261 htab_eq_string (const void *s1
, const void *s2
)
2263 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2266 /* Add mnemonic STR with length LEN to the mnemonic hash table
2267 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
2268 and a permanent heap copy of STR is created. */
2271 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, int len
)
2275 char *str_zero
= (char*)alloca (len
+ 1);
2277 memcpy (str_zero
, str
, len
);
2278 str_zero
[len
] = '\0';
2280 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2285 /* Not found; create a permanent copy and add it to the hash table. */
2286 new_str
= XNEWVAR (char, len
+ 1);
2287 memcpy (new_str
, str_zero
, len
+ 1);
2291 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2292 table in MNEMONIC_HTAB.
2294 The mnemonics cannot be found if they are emitted using C code.
2296 If a mnemonic string contains ';' or a newline the string assumed
2297 to consist of more than a single instruction. The attribute value
2298 will then be set to the user defined default value. */
2301 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2303 const char *template_code
, *cp
;
2310 template_code
= XTMPL (insn
, 3);
2312 /* Skip patterns which use C code to emit the template. */
2313 if (template_code
[0] == '*')
2316 if (template_code
[0] == '@')
2317 cp
= &template_code
[1];
2319 cp
= &template_code
[0];
2323 const char *ep
, *sp
;
2326 while (ISSPACE (*cp
))
2329 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2334 obstack_1grow (&string_obstack
, ',');
2336 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2337 || (*cp
>= 'a' && *cp
<= 'z')))
2340 obstack_1grow (&string_obstack
, *cp
);
2347 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2349 /* Don't set a value if there are more than one
2350 instruction in the string. */
2351 obstack_next_free (&string_obstack
) =
2352 obstack_next_free (&string_obstack
) - size
;
2361 obstack_1grow (&string_obstack
, '*');
2363 add_mnemonic_string (mnemonic_htab
,
2364 obstack_next_free (&string_obstack
) - size
,
2369 /* An insn definition might emit an empty string. */
2370 if (obstack_object_size (&string_obstack
) == 0)
2373 obstack_1grow (&string_obstack
, '\0');
2375 set_attr
= rtx_alloc (SET_ATTR
);
2376 XSTR (set_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2377 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2378 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2379 XSTR (set_attr
, 0) = attr_name
;
2381 if (!XVEC (insn
, 4))
2384 vec_len
= XVECLEN (insn
, 4);
2386 new_vec
= rtvec_alloc (vec_len
+ 1);
2387 for (i
= 0; i
< vec_len
; i
++)
2388 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2389 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2390 XVEC (insn
, 4) = new_vec
;
2393 /* This function is called for the elements in the mnemonic hashtable
2394 and generates a comma separated list of the mnemonics. */
2397 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
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
;
2422 /* Look for the DEFINE_ATTR for `mnemonic'. */
2423 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2424 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2425 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2427 mnemonic_attr
= elem
->data
;
2431 /* A (define_attr "mnemonic" "...") indicates that the back-end
2432 wants a mnemonic attribute to be generated. */
2436 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2437 htab_eq_string
, 0, xcalloc
, free
);
2439 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2441 rtx insn
= elem
->data
;
2444 /* Check if the insn definition already has
2445 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2447 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2449 rtx set_attr
= XVECEXP (insn
, 4, i
);
2451 switch (GET_CODE (set_attr
))
2454 case SET_ATTR_ALTERNATIVE
:
2455 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2459 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2460 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2461 MNEMONIC_ATTR_NAME
) == 0)
2470 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2473 /* Add the user defined values to the hash table. */
2474 str
= XSTR (mnemonic_attr
, 1);
2475 while ((p
= scan_comma_elt (&str
)) != NULL
)
2476 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2478 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2480 /* Replace the last ',' with the zero end character. */
2481 *((char *)obstack_next_free (&string_obstack
) - 1) = '\0';
2482 XSTR (mnemonic_attr
, 1) = XOBFINISH (&string_obstack
, char *);
2485 /* Check if there are DEFINE_ATTRs with the same name. */
2487 check_define_attr_duplicates ()
2489 struct queue_elem
*elem
;
2494 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2496 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2498 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2500 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2505 error_with_line (elem
->lineno
, "redefinition of attribute '%s'",
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
, 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. */
2531 read_md_files (argc
, argv
, parse_opt
, rtx_handle_directive
);
2533 if (define_attr_queue
!= NULL
)
2534 check_define_attr_duplicates ();
2536 /* Process define_cond_exec patterns. */
2537 if (define_cond_exec_queue
!= NULL
)
2538 process_define_cond_exec ();
2540 /* Process define_subst patterns. */
2541 if (define_subst_queue
!= NULL
)
2542 process_define_subst ();
2544 if (define_attr_queue
!= NULL
)
2545 gen_mnemonic_attr ();
2550 /* Programs that don't have their own options can use this entry point
2553 init_rtx_reader_args (int argc
, char **argv
)
2555 return init_rtx_reader_args_cb (argc
, argv
, 0);
2558 /* The entry point for reading a single rtx from an md file. Return
2559 the rtx, or NULL if the md file has been fully processed.
2560 Return the line where the rtx was found in LINENO.
2561 Return the number of code generating rtx'en read since the start
2562 of the md file in SEQNR. */
2565 read_md_rtx (int *lineno
, int *seqnr
)
2567 struct queue_elem
**queue
, *elem
;
2572 /* Read all patterns from a given queue before moving on to the next. */
2573 if (define_attr_queue
!= NULL
)
2574 queue
= &define_attr_queue
;
2575 else if (define_pred_queue
!= NULL
)
2576 queue
= &define_pred_queue
;
2577 else if (define_insn_queue
!= NULL
)
2578 queue
= &define_insn_queue
;
2579 else if (other_queue
!= NULL
)
2580 queue
= &other_queue
;
2585 *queue
= elem
->next
;
2587 read_md_filename
= elem
->filename
;
2588 *lineno
= elem
->lineno
;
2589 *seqnr
= sequence_num
;
2593 /* Discard insn patterns which we know can never match (because
2594 their C test is provably always false). If insn_elision is
2595 false, our caller needs to see all the patterns. Note that the
2596 elided patterns are never counted by the sequence numbering; it
2597 is the caller's responsibility, when insn_elision is false, not
2598 to use elided pattern numbers for anything. */
2599 switch (GET_CODE (desc
))
2604 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
2606 else if (insn_elision
)
2609 /* *seqnr is used here so the name table will match caller's
2610 idea of insn numbering, whether or not elision is active. */
2611 record_insn_name (*seqnr
, XSTR (desc
, 0));
2615 case DEFINE_PEEPHOLE
:
2616 case DEFINE_PEEPHOLE2
:
2617 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
2619 else if (insn_elision
)
2630 /* Helper functions for insn elision. */
2632 /* Compute a hash function of a c_test structure, which is keyed
2633 by its ->expr field. */
2635 hash_c_test (const void *x
)
2637 const struct c_test
*a
= (const struct c_test
*) x
;
2638 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2646 while ((c
= *s
++) != '\0')
2648 hash
+= c
+ (c
<< 17);
2653 hash
+= len
+ (len
<< 17);
2659 /* Compare two c_test expression structures. */
2661 cmp_c_test (const void *x
, const void *y
)
2663 const struct c_test
*a
= (const struct c_test
*) x
;
2664 const struct c_test
*b
= (const struct c_test
*) y
;
2666 return !strcmp (a
->expr
, b
->expr
);
2669 /* Given a string representing a C test expression, look it up in the
2670 condition_table and report whether or not its value is known
2671 at compile time. Returns a tristate: 1 for known true, 0 for
2672 known false, -1 for unknown. */
2674 maybe_eval_c_test (const char *expr
)
2676 const struct c_test
*test
;
2677 struct c_test dummy
;
2683 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2689 /* Record the C test expression EXPR in the condition_table, with
2690 value VAL. Duplicates clobber previous entries. */
2693 add_c_test (const char *expr
, int value
)
2695 struct c_test
*test
;
2700 test
= XNEW (struct c_test
);
2702 test
->value
= value
;
2704 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2707 /* For every C test, call CALLBACK with two arguments: a pointer to
2708 the condition structure and INFO. Stops when CALLBACK returns zero. */
2710 traverse_c_tests (htab_trav callback
, void *info
)
2712 if (condition_table
)
2713 htab_traverse (condition_table
, callback
, info
);
2716 /* Helper functions for define_predicate and define_special_predicate
2717 processing. Shared between genrecog.c and genpreds.c. */
2719 static htab_t predicate_table
;
2720 struct pred_data
*first_predicate
;
2721 static struct pred_data
**last_predicate
= &first_predicate
;
2724 hash_struct_pred_data (const void *ptr
)
2726 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2730 eq_struct_pred_data (const void *a
, const void *b
)
2732 return !strcmp (((const struct pred_data
*)a
)->name
,
2733 ((const struct pred_data
*)b
)->name
);
2737 lookup_predicate (const char *name
)
2739 struct pred_data key
;
2741 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2744 /* Record that predicate PRED can accept CODE. */
2747 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2749 if (!pred
->codes
[code
])
2752 pred
->codes
[code
] = true;
2754 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2755 pred
->allows_non_const
= true;
2762 && code
!= STRICT_LOW_PART
2764 pred
->allows_non_lvalue
= true;
2766 if (pred
->num_codes
== 1)
2767 pred
->singleton
= code
;
2768 else if (pred
->num_codes
== 2)
2769 pred
->singleton
= UNKNOWN
;
2774 add_predicate (struct pred_data
*pred
)
2776 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2779 error ("duplicate predicate definition for '%s'", pred
->name
);
2783 *last_predicate
= pred
;
2784 last_predicate
= &pred
->next
;
2787 /* This array gives the initial content of the predicate table. It
2788 has entries for all predicates defined in recog.c. */
2790 struct std_pred_table
2794 bool allows_const_p
;
2795 RTX_CODE codes
[NUM_RTX_CODE
];
2798 static const struct std_pred_table std_preds
[] = {
2799 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2800 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
2801 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2802 {"register_operand", false, false, {SUBREG
, REG
}},
2803 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2804 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2805 {"immediate_operand", false, true, {UNKNOWN
}},
2806 {"const_int_operand", false, false, {CONST_INT
}},
2807 #if TARGET_SUPPORTS_WIDE_INT
2808 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2809 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2811 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2813 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2814 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2815 {"push_operand", false, false, {MEM
}},
2816 {"pop_operand", false, false, {MEM
}},
2817 {"memory_operand", false, false, {SUBREG
, MEM
}},
2818 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2819 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2821 LEU
, LTU
, GEU
, GTU
}},
2822 {"comparison_operator", false, false, {EQ
, NE
,
2829 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2831 /* Initialize the table of predicate definitions, starting with
2832 the information we have on generic predicates. */
2835 init_predicate_table (void)
2838 struct pred_data
*pred
;
2840 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2841 eq_struct_pred_data
, 0,
2844 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2846 pred
= XCNEW (struct pred_data
);
2847 pred
->name
= std_preds
[i
].name
;
2848 pred
->special
= std_preds
[i
].special
;
2850 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2851 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2853 if (std_preds
[i
].allows_const_p
)
2854 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2855 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2856 add_predicate_code (pred
, (enum rtx_code
) j
);
2858 add_predicate (pred
);
2862 /* These functions allow linkage with print-rtl.c. Also, some generators
2863 like to annotate their output with insn names. */
2865 /* Holds an array of names indexed by insn_code_number. */
2866 static char **insn_name_ptr
= 0;
2867 static int insn_name_ptr_size
= 0;
2870 get_insn_name (int code
)
2872 if (code
< insn_name_ptr_size
)
2873 return insn_name_ptr
[code
];
2879 record_insn_name (int code
, const char *name
)
2881 static const char *last_real_name
= "insn";
2882 static int last_real_code
= 0;
2885 if (insn_name_ptr_size
<= code
)
2888 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
2889 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
2890 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
2891 sizeof (char *) * (new_size
- insn_name_ptr_size
));
2892 insn_name_ptr_size
= new_size
;
2895 if (!name
|| name
[0] == '\0')
2897 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
2898 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
2902 last_real_name
= new_name
= xstrdup (name
);
2903 last_real_code
= code
;
2906 insn_name_ptr
[code
] = new_name
;
2909 /* Make STATS describe the operands that appear in rtx X. */
2912 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
2922 code
= GET_CODE (x
);
2926 case MATCH_OPERATOR
:
2927 case MATCH_PARALLEL
:
2928 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
2935 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
2939 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
2946 fmt
= GET_RTX_FORMAT (code
);
2947 len
= GET_RTX_LENGTH (code
);
2948 for (i
= 0; i
< len
; i
++)
2950 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
2951 get_pattern_stats_1 (stats
, XEXP (x
, i
));
2952 else if (fmt
[i
] == 'E')
2955 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2956 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
2961 /* Make STATS describe the operands that appear in instruction pattern
2965 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
2969 stats
->max_opno
= -1;
2970 stats
->max_dup_opno
= -1;
2971 stats
->max_scratch_opno
= -1;
2972 stats
->num_dups
= 0;
2974 len
= GET_NUM_ELEM (pattern
);
2975 for (i
= 0; i
< len
; i
++)
2976 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
2978 stats
->num_generator_args
= stats
->max_opno
+ 1;
2979 stats
->num_insn_operands
= MAX (stats
->max_opno
,
2980 stats
->max_scratch_opno
) + 1;
2981 stats
->num_operand_vars
= MAX (stats
->max_opno
,
2982 MAX (stats
->max_dup_opno
,
2983 stats
->max_scratch_opno
)) + 1;
2986 /* Return the emit_* function that should be used for pattern X, or NULL
2987 if we can't pick a particular type at compile time and should instead
2988 fall back to "emit". */
2991 get_emit_function (rtx x
)
2993 switch (classify_insn (x
))
2999 return "emit_call_insn";
3002 return "emit_jump_insn";
3012 /* Return true if we must emit a barrier after pattern X. */
3015 needs_barrier_p (rtx x
)
3017 return (GET_CODE (x
) == SET
3018 && GET_CODE (SET_DEST (x
)) == PC
3019 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);