1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 2010, Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
30 #include "gensupport.h"
33 /* In case some macros used by files we include need it, define this here. */
38 static struct obstack obstack
;
39 struct obstack
*rtl_obstack
= &obstack
;
41 static int sequence_num
;
43 static int predicable_default
;
44 static const char *predicable_true
;
45 static const char *predicable_false
;
47 static htab_t condition_table
;
49 /* We initially queue all patterns, process the define_insn and
50 define_cond_exec patterns, then return them one at a time. */
57 struct queue_elem
*next
;
58 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
59 points to the generated DEFINE_SPLIT. */
60 struct queue_elem
*split
;
63 #define MNEMONIC_ATTR_NAME "mnemonic"
64 #define MNEMONIC_HTAB_SIZE 1024
66 static struct queue_elem
*define_attr_queue
;
67 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
68 static struct queue_elem
*define_pred_queue
;
69 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
70 static struct queue_elem
*define_insn_queue
;
71 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
72 static struct queue_elem
*define_cond_exec_queue
;
73 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
74 static struct queue_elem
*other_queue
;
75 static struct queue_elem
**other_tail
= &other_queue
;
77 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
80 static void remove_constraints (rtx
);
81 static void process_rtx (rtx
, int);
83 static int is_predicable (struct queue_elem
*);
84 static void identify_predicable_attribute (void);
85 static int n_alternatives (const char *);
86 static void collect_insn_data (rtx
, int *, int *);
87 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
88 static const char *alter_test_for_insn (struct queue_elem
*,
90 static char *shift_output_template (char *, const char *, int);
91 static const char *alter_output_for_insn (struct queue_elem
*,
94 static void process_one_cond_exec (struct queue_elem
*);
95 static void process_define_cond_exec (void);
96 static void init_predicate_table (void);
97 static void record_insn_name (int, const char *);
99 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
100 the gensupport programs. */
103 gen_rtx_CONST_INT (enum machine_mode
ARG_UNUSED (mode
),
106 rtx rt
= rtx_alloc (CONST_INT
);
112 /* Predicate handling.
114 We construct from the machine description a table mapping each
115 predicate to a list of the rtl codes it can possibly match. The
116 function 'maybe_both_true' uses it to deduce that there are no
117 expressions that can be matches by certain pairs of tree nodes.
118 Also, if a predicate can match only one code, we can hardwire that
119 code into the node testing the predicate.
121 Some predicates are flagged as special. validate_pattern will not
122 warn about modeless match_operand expressions if they have a
123 special predicate. Predicates that allow only constants are also
124 treated as special, for this purpose.
126 validate_pattern will warn about predicates that allow non-lvalues
127 when they appear in destination operands.
129 Calculating the set of rtx codes that can possibly be accepted by a
130 predicate expression EXP requires a three-state logic: any given
131 subexpression may definitively accept a code C (Y), definitively
132 reject a code C (N), or may have an indeterminate effect (I). N
133 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
144 We represent Y with 1, N with 0, I with 2. If any code is left in
145 an I state by the complete expression, we must assume that that
146 code can be accepted. */
152 #define TRISTATE_AND(a,b) \
153 ((a) == I ? ((b) == N ? N : I) : \
154 (b) == I ? ((a) == N ? N : I) : \
157 #define TRISTATE_OR(a,b) \
158 ((a) == I ? ((b) == Y ? Y : I) : \
159 (b) == I ? ((a) == Y ? Y : I) : \
162 #define TRISTATE_NOT(a) \
163 ((a) == I ? I : !(a))
165 /* 0 means no warning about that code yet, 1 means warned. */
166 static char did_you_mean_codes
[NUM_RTX_CODE
];
168 /* Recursively calculate the set of rtx codes accepted by the
169 predicate expression EXP, writing the result to CODES. LINENO is
170 the line number on which the directive containing EXP appeared. */
173 compute_predicate_codes (rtx exp
, int lineno
, char codes
[NUM_RTX_CODE
])
175 char op0_codes
[NUM_RTX_CODE
];
176 char op1_codes
[NUM_RTX_CODE
];
177 char op2_codes
[NUM_RTX_CODE
];
180 switch (GET_CODE (exp
))
183 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
184 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
185 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
186 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
190 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
191 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
192 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
193 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
196 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
197 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
198 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
202 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
203 compute_predicate_codes (XEXP (exp
, 0), lineno
, op0_codes
);
204 compute_predicate_codes (XEXP (exp
, 1), lineno
, op1_codes
);
205 compute_predicate_codes (XEXP (exp
, 2), lineno
, op2_codes
);
206 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
207 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
208 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
213 /* MATCH_CODE allows a specified list of codes. However, if it
214 does not apply to the top level of the expression, it does not
215 constrain the set of codes for the top level. */
216 if (XSTR (exp
, 1)[0] != '\0')
218 memset (codes
, Y
, NUM_RTX_CODE
);
222 memset (codes
, N
, NUM_RTX_CODE
);
224 const char *next_code
= XSTR (exp
, 0);
227 if (*next_code
== '\0')
229 error_with_line (lineno
, "empty match_code expression");
233 while ((code
= scan_comma_elt (&next_code
)) != 0)
235 size_t n
= next_code
- code
;
238 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
239 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
240 && GET_RTX_NAME (i
)[n
] == '\0')
248 error_with_line (lineno
,
249 "match_code \"%.*s\" matches nothing",
251 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
252 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
253 && GET_RTX_NAME (i
)[n
] == '\0'
254 && !did_you_mean_codes
[i
])
256 did_you_mean_codes
[i
] = 1;
257 message_with_line (lineno
, "(did you mean \"%s\"?)",
266 /* MATCH_OPERAND disallows the set of codes that the named predicate
267 disallows, and is indeterminate for the codes that it does allow. */
269 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
272 error_with_line (lineno
, "reference to unknown predicate '%s'",
276 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
277 codes
[i
] = p
->codes
[i
] ? I
: N
;
283 /* (match_test WHATEVER) is completely indeterminate. */
284 memset (codes
, I
, NUM_RTX_CODE
);
288 error_with_line (lineno
,
289 "'%s' cannot be used in a define_predicate expression",
290 GET_RTX_NAME (GET_CODE (exp
)));
291 memset (codes
, I
, NUM_RTX_CODE
);
300 /* Return true if NAME is a valid predicate name. */
303 valid_predicate_name_p (const char *name
)
307 if (!ISALPHA (name
[0]) && name
[0] != '_')
309 for (p
= name
+ 1; *p
; p
++)
310 if (!ISALNUM (*p
) && *p
!= '_')
315 /* Process define_predicate directive DESC, which appears on line number
316 LINENO. Compute the set of codes that can be matched, and record this
317 as a known predicate. */
320 process_define_predicate (rtx desc
, int lineno
)
322 struct pred_data
*pred
;
323 char codes
[NUM_RTX_CODE
];
326 if (!valid_predicate_name_p (XSTR (desc
, 0)))
328 error_with_line (lineno
,
329 "%s: predicate name must be a valid C function name",
334 pred
= XCNEW (struct pred_data
);
335 pred
->name
= XSTR (desc
, 0);
336 pred
->exp
= XEXP (desc
, 1);
337 pred
->c_block
= XSTR (desc
, 2);
338 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
339 pred
->special
= true;
341 compute_predicate_codes (XEXP (desc
, 1), lineno
, codes
);
343 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
345 add_predicate_code (pred
, (enum rtx_code
) i
);
347 add_predicate (pred
);
353 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
356 static struct queue_elem
*
357 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
358 const char *filename
, int lineno
)
360 struct queue_elem
*e
= XNEW(struct queue_elem
);
362 e
->filename
= filename
;
367 *list_tail
= &e
->next
;
371 /* Build a define_attr for an binary attribute with name NAME and
372 possible values "yes" and "no", and queue it. */
374 add_define_attr (const char *name
)
376 struct queue_elem
*e
= XNEW(struct queue_elem
);
377 rtx t1
= rtx_alloc (DEFINE_ATTR
);
379 XSTR (t1
, 1) = "no,yes";
380 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
381 XSTR (XEXP (t1
, 2), 0) = "yes";
383 e
->filename
= "built-in";
385 e
->next
= define_attr_queue
;
386 define_attr_queue
= e
;
390 /* Recursively remove constraints from an rtx. */
393 remove_constraints (rtx part
)
396 const char *format_ptr
;
401 if (GET_CODE (part
) == MATCH_OPERAND
)
403 else if (GET_CODE (part
) == MATCH_SCRATCH
)
406 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
408 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
409 switch (*format_ptr
++)
413 remove_constraints (XEXP (part
, i
));
416 if (XVEC (part
, i
) != NULL
)
417 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
418 remove_constraints (XVECEXP (part
, i
, j
));
423 /* Process a top level rtx in some way, queuing as appropriate. */
426 process_rtx (rtx desc
, int lineno
)
428 switch (GET_CODE (desc
))
431 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
434 case DEFINE_COND_EXEC
:
435 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
439 case DEFINE_ENUM_ATTR
:
440 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
443 case DEFINE_PREDICATE
:
444 case DEFINE_SPECIAL_PREDICATE
:
445 process_define_predicate (desc
, lineno
);
448 case DEFINE_CONSTRAINT
:
449 case DEFINE_REGISTER_CONSTRAINT
:
450 case DEFINE_MEMORY_CONSTRAINT
:
451 case DEFINE_ADDRESS_CONSTRAINT
:
452 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
455 case DEFINE_INSN_AND_SPLIT
:
457 const char *split_cond
;
461 struct queue_elem
*insn_elem
;
462 struct queue_elem
*split_elem
;
464 /* Create a split with values from the insn_and_split. */
465 split
= rtx_alloc (DEFINE_SPLIT
);
467 i
= XVECLEN (desc
, 1);
468 XVEC (split
, 0) = rtvec_alloc (i
);
471 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
472 remove_constraints (XVECEXP (split
, 0, i
));
475 /* If the split condition starts with "&&", append it to the
476 insn condition to create the new split condition. */
477 split_cond
= XSTR (desc
, 4);
478 if (split_cond
[0] == '&' && split_cond
[1] == '&')
480 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
481 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
483 XSTR (split
, 1) = split_cond
;
484 XVEC (split
, 2) = XVEC (desc
, 5);
485 XSTR (split
, 3) = XSTR (desc
, 6);
487 /* Fix up the DEFINE_INSN. */
488 attr
= XVEC (desc
, 7);
489 PUT_CODE (desc
, DEFINE_INSN
);
490 XVEC (desc
, 4) = attr
;
494 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
497 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
498 insn_elem
->split
= split_elem
;
503 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
508 /* Return true if attribute PREDICABLE is true for ELEM, which holds
512 is_predicable (struct queue_elem
*elem
)
514 rtvec vec
= XVEC (elem
->data
, 4);
519 return predicable_default
;
521 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
523 rtx sub
= RTVEC_ELT (vec
, i
);
524 switch (GET_CODE (sub
))
527 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
529 value
= XSTR (sub
, 1);
534 case SET_ATTR_ALTERNATIVE
:
535 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
537 error_with_line (elem
->lineno
,
538 "multiple alternatives for `predicable'");
544 if (GET_CODE (SET_DEST (sub
)) != ATTR
545 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
548 if (GET_CODE (sub
) == CONST_STRING
)
550 value
= XSTR (sub
, 0);
554 /* ??? It would be possible to handle this if we really tried.
555 It's not easy though, and I'm not going to bother until it
556 really proves necessary. */
557 error_with_line (elem
->lineno
,
558 "non-constant value for `predicable'");
566 return predicable_default
;
569 /* Find out which value we're looking at. Multiple alternatives means at
570 least one is predicable. */
571 if (strchr (value
, ',') != NULL
)
573 if (strcmp (value
, predicable_true
) == 0)
575 if (strcmp (value
, predicable_false
) == 0)
578 error_with_line (elem
->lineno
,
579 "unknown value `%s' for `predicable' attribute", value
);
583 /* Examine the attribute "predicable"; discover its boolean values
587 identify_predicable_attribute (void)
589 struct queue_elem
*elem
;
590 char *p_true
, *p_false
;
593 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
594 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
595 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
598 error_with_line (define_cond_exec_queue
->lineno
,
599 "attribute `predicable' not defined");
603 value
= XSTR (elem
->data
, 1);
604 p_false
= xstrdup (value
);
605 p_true
= strchr (p_false
, ',');
606 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
608 error_with_line (elem
->lineno
, "attribute `predicable' is not a boolean");
614 predicable_true
= p_true
;
615 predicable_false
= p_false
;
617 switch (GET_CODE (XEXP (elem
->data
, 2)))
620 value
= XSTR (XEXP (elem
->data
, 2), 0);
624 error_with_line (elem
->lineno
, "attribute `predicable' cannot be const");
629 error_with_line (elem
->lineno
,
630 "attribute `predicable' must have a constant default");
635 if (strcmp (value
, p_true
) == 0)
636 predicable_default
= 1;
637 else if (strcmp (value
, p_false
) == 0)
638 predicable_default
= 0;
641 error_with_line (elem
->lineno
,
642 "unknown value `%s' for `predicable' attribute", value
);
647 /* Return the number of alternatives in constraint S. */
650 n_alternatives (const char *s
)
661 /* Determine how many alternatives there are in INSN, and how many
665 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
671 code
= GET_CODE (pattern
);
675 i
= n_alternatives (XSTR (pattern
, 2));
676 *palt
= (i
> *palt
? i
: *palt
);
682 i
= XINT (pattern
, 0);
691 fmt
= GET_RTX_FORMAT (code
);
692 len
= GET_RTX_LENGTH (code
);
693 for (i
= 0; i
< len
; i
++)
698 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
702 if (XVEC (pattern
, i
) == NULL
)
706 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
707 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
710 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
720 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
726 code
= GET_CODE (pattern
);
731 const char *c
= XSTR (pattern
, 2);
733 if (n_alternatives (c
) != 1)
735 error_with_line (lineno
, "too many alternatives for operand %d",
740 /* Replicate C as needed to fill out ALT alternatives. */
741 if (c
&& *c
&& alt
> 1)
743 size_t c_len
= strlen (c
);
744 size_t len
= alt
* (c_len
+ 1);
745 char *new_c
= XNEWVEC(char, len
);
747 memcpy (new_c
, c
, c_len
);
748 for (i
= 1; i
< alt
; ++i
)
750 new_c
[i
* (c_len
+ 1) - 1] = ',';
751 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
753 new_c
[len
- 1] = '\0';
754 XSTR (pattern
, 2) = new_c
;
762 XINT (pattern
, 0) += max_op
;
769 fmt
= GET_RTX_FORMAT (code
);
770 len
= GET_RTX_LENGTH (code
);
771 for (i
= 0; i
< len
; i
++)
778 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
785 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
787 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
788 alt
, max_op
, lineno
);
794 case 'i': case 'w': case '0': case 's':
806 alter_test_for_insn (struct queue_elem
*ce_elem
,
807 struct queue_elem
*insn_elem
)
809 return join_c_conditions (XSTR (ce_elem
->data
, 1),
810 XSTR (insn_elem
->data
, 2));
813 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
814 to take "ce_enabled" into account. Return the new expression. */
816 modify_attr_enabled_ce (rtx val
)
820 eq_attr
= rtx_alloc (EQ_ATTR
);
821 ite
= rtx_alloc (IF_THEN_ELSE
);
822 str
= rtx_alloc (CONST_STRING
);
824 XSTR (eq_attr
, 0) = "ce_enabled";
825 XSTR (eq_attr
, 1) = "yes";
826 XSTR (str
, 0) = "no";
827 XEXP (ite
, 0) = eq_attr
;
834 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
835 from a define_insn pattern. We must modify the "predicable" attribute
836 to be named "ce_enabled", and also change any "enabled" attribute that's
837 present so that it takes ce_enabled into account.
838 We rely on the fact that INSN was created with copy_rtx, and modify data
842 alter_attrs_for_insn (rtx insn
)
844 static bool global_changes_made
= false;
845 rtvec vec
= XVEC (insn
, 4);
849 int predicable_idx
= -1;
850 int enabled_idx
= -1;
856 num_elem
= GET_NUM_ELEM (vec
);
857 for (i
= num_elem
- 1; i
>= 0; --i
)
859 rtx sub
= RTVEC_ELT (vec
, i
);
860 switch (GET_CODE (sub
))
863 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
866 XSTR (sub
, 0) = "ce_enabled";
868 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
871 XSTR (sub
, 0) = "nonce_enabled";
875 case SET_ATTR_ALTERNATIVE
:
876 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
877 /* We already give an error elsewhere. */
879 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
882 XSTR (sub
, 0) = "nonce_enabled";
887 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
889 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
892 if (GET_CODE (sub
) == CONST_STRING
)
895 XSTR (sub
, 0) = "ce_enabled";
898 /* We already give an error elsewhere. */
902 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
905 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
913 if (predicable_idx
== -1)
916 if (!global_changes_made
)
918 struct queue_elem
*elem
;
920 global_changes_made
= true;
921 add_define_attr ("ce_enabled");
922 add_define_attr ("nonce_enabled");
924 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
925 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
928 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
931 if (enabled_idx
== -1)
934 new_vec
= rtvec_alloc (num_elem
+ 1);
935 for (i
= 0; i
< num_elem
; i
++)
936 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
937 val
= rtx_alloc (IF_THEN_ELSE
);
938 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
939 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
940 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
941 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
942 XSTR (XEXP (val
, 0), 1) = "yes";
943 XSTR (XEXP (val
, 1), 0) = "yes";
944 XSTR (XEXP (val
, 2), 0) = "no";
945 set
= rtx_alloc (SET
);
946 SET_DEST (set
) = rtx_alloc (ATTR
);
947 XSTR (SET_DEST (set
), 0) = "enabled";
948 SET_SRC (set
) = modify_attr_enabled_ce (val
);
949 RTVEC_ELT (new_vec
, i
) = set
;
950 XVEC (insn
, 4) = new_vec
;
953 /* Adjust all of the operand numbers in SRC to match the shift they'll
954 get from an operand displacement of DISP. Return a pointer after the
958 shift_output_template (char *dest
, const char *src
, int disp
)
967 if (ISDIGIT ((unsigned char) c
))
969 else if (ISALPHA (c
))
982 alter_output_for_insn (struct queue_elem
*ce_elem
,
983 struct queue_elem
*insn_elem
,
986 const char *ce_out
, *insn_out
;
988 size_t len
, ce_len
, insn_len
;
990 /* ??? Could coordinate with genoutput to not duplicate code here. */
992 ce_out
= XSTR (ce_elem
->data
, 2);
993 insn_out
= XTMPL (insn_elem
->data
, 3);
994 if (!ce_out
|| *ce_out
== '\0')
997 ce_len
= strlen (ce_out
);
998 insn_len
= strlen (insn_out
);
1000 if (*insn_out
== '*')
1001 /* You must take care of the predicate yourself. */
1004 if (*insn_out
== '@')
1006 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1007 p
= result
= XNEWVEC(char, len
);
1013 while (ISSPACE ((unsigned char) *insn_out
));
1015 if (*insn_out
!= '#')
1017 p
= shift_output_template (p
, ce_out
, max_op
);
1023 while (*insn_out
&& *insn_out
!= '\n');
1030 len
= ce_len
+ 1 + insn_len
+ 1;
1031 result
= XNEWVEC (char, len
);
1033 p
= shift_output_template (result
, ce_out
, max_op
);
1035 memcpy (p
, insn_out
, insn_len
+ 1);
1041 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1044 process_one_cond_exec (struct queue_elem
*ce_elem
)
1046 struct queue_elem
*insn_elem
;
1047 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1049 int alternatives
, max_operand
;
1050 rtx pred
, insn
, pattern
, split
;
1054 if (! is_predicable (insn_elem
))
1059 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1062 if (XVECLEN (ce_elem
->data
, 0) != 1)
1064 error_with_line (ce_elem
->lineno
, "too many patterns in predicate");
1068 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1069 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1074 /* Construct a new pattern for the new insn. */
1075 insn
= copy_rtx (insn_elem
->data
);
1076 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1077 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1078 XSTR (insn
, 0) = new_name
;
1079 pattern
= rtx_alloc (COND_EXEC
);
1080 XEXP (pattern
, 0) = pred
;
1081 if (XVECLEN (insn
, 1) == 1)
1083 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
1084 XVECEXP (insn
, 1, 0) = pattern
;
1085 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
1089 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1090 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
1091 XVEC (insn
, 1) = rtvec_alloc (1);
1092 XVECEXP (insn
, 1, 0) = pattern
;
1095 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1096 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1097 alternatives
, max_operand
);
1098 alter_attrs_for_insn (insn
);
1100 /* Put the new pattern on the `other' list so that it
1101 (a) is not reprocessed by other define_cond_exec patterns
1102 (b) appears after all normal define_insn patterns.
1104 ??? B is debatable. If one has normal insns that match
1105 cond_exec patterns, they will be preferred over these
1106 generated patterns. Whether this matters in practice, or if
1107 it's a good thing, or whether we should thread these new
1108 patterns into the define_insn chain just after their generator
1109 is something we'll have to experiment with. */
1111 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
1114 if (!insn_elem
->split
)
1117 /* If the original insn came from a define_insn_and_split,
1118 generate a new split to handle the predicated insn. */
1119 split
= copy_rtx (insn_elem
->split
->data
);
1120 /* Predicate the pattern matched by the split. */
1121 pattern
= rtx_alloc (COND_EXEC
);
1122 XEXP (pattern
, 0) = pred
;
1123 if (XVECLEN (split
, 0) == 1)
1125 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
1126 XVECEXP (split
, 0, 0) = pattern
;
1127 PUT_NUM_ELEM (XVEC (split
, 0), 1);
1131 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
1132 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
1133 XVEC (split
, 0) = rtvec_alloc (1);
1134 XVECEXP (split
, 0, 0) = pattern
;
1136 /* Predicate all of the insns generated by the split. */
1137 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1139 pattern
= rtx_alloc (COND_EXEC
);
1140 XEXP (pattern
, 0) = pred
;
1141 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1142 XVECEXP (split
, 2, i
) = pattern
;
1144 /* Add the new split to the queue. */
1145 queue_pattern (split
, &other_tail
, read_md_filename
,
1146 insn_elem
->split
->lineno
);
1150 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
1151 patterns appropriately. */
1154 process_define_cond_exec (void)
1156 struct queue_elem
*elem
;
1158 identify_predicable_attribute ();
1162 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
1163 process_one_cond_exec (elem
);
1166 /* A read_md_files callback for reading an rtx. */
1169 rtx_handle_directive (int lineno
, const char *rtx_name
)
1173 if (read_rtx (rtx_name
, &queue
))
1174 for (x
= queue
; x
; x
= XEXP (x
, 1))
1175 process_rtx (XEXP (x
, 0), lineno
);
1178 /* Comparison function for the mnemonic hash table. */
1181 htab_eq_string (const void *s1
, const void *s2
)
1183 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
1186 /* Add mnemonic STR with length LEN to the mnemonic hash table
1187 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
1188 and a permanent heap copy of STR is created. */
1191 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, int len
)
1195 char *str_zero
= (char*)alloca (len
+ 1);
1197 memcpy (str_zero
, str
, len
);
1198 str_zero
[len
] = '\0';
1200 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
1205 /* Not found; create a permanent copy and add it to the hash table. */
1206 new_str
= XNEWVAR (char, len
+ 1);
1207 memcpy (new_str
, str_zero
, len
+ 1);
1211 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
1212 table in MNEMONIC_HTAB.
1214 The mnemonics cannot be found if they are emitted using C code.
1216 If a mnemonic string contains ';' or a newline the string assumed
1217 to consist of more than a single instruction. The attribute value
1218 will then be set to the user defined default value. */
1221 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
1223 const char *template_code
, *cp
;
1230 template_code
= XTMPL (insn
, 3);
1232 /* Skip patterns which use C code to emit the template. */
1233 if (template_code
[0] == '*')
1236 if (template_code
[0] == '@')
1237 cp
= &template_code
[1];
1239 cp
= &template_code
[0];
1243 const char *ep
, *sp
;
1246 while (ISSPACE (*cp
))
1249 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
1254 obstack_1grow (&string_obstack
, ',');
1256 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
1257 || (*cp
>= 'a' && *cp
<= 'z')))
1260 obstack_1grow (&string_obstack
, *cp
);
1267 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
1269 /* Don't set a value if there are more than one
1270 instruction in the string. */
1271 obstack_next_free (&string_obstack
) =
1272 obstack_next_free (&string_obstack
) - size
;
1281 obstack_1grow (&string_obstack
, '*');
1283 add_mnemonic_string (mnemonic_htab
,
1284 obstack_next_free (&string_obstack
) - size
,
1289 /* An insn definition might emit an empty string. */
1290 if (obstack_object_size (&string_obstack
) == 0)
1293 obstack_1grow (&string_obstack
, '\0');
1295 set_attr
= rtx_alloc (SET_ATTR
);
1296 XSTR (set_attr
, 1) = XOBFINISH (&string_obstack
, char *);
1297 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
1298 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
1299 XSTR (set_attr
, 0) = attr_name
;
1301 if (!XVEC (insn
, 4))
1304 vec_len
= XVECLEN (insn
, 4);
1306 new_vec
= rtvec_alloc (vec_len
+ 1);
1307 for (i
= 0; i
< vec_len
; i
++)
1308 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
1309 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
1310 XVEC (insn
, 4) = new_vec
;
1313 /* This function is called for the elements in the mnemonic hashtable
1314 and generates a comma separated list of the mnemonics. */
1317 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
1319 obstack_grow (&string_obstack
, (char*)*slot
, strlen ((char*)*slot
));
1320 obstack_1grow (&string_obstack
, ',');
1324 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
1325 insn definition in case the back end requests it by defining the
1326 mnemonic attribute. The values for the attribute will be extracted
1327 from the output patterns of the insn definitions as far as
1331 gen_mnemonic_attr (void)
1333 struct queue_elem
*elem
;
1334 rtx mnemonic_attr
= NULL
;
1335 htab_t mnemonic_htab
;
1336 const char *str
, *p
;
1342 /* Look for the DEFINE_ATTR for `mnemonic'. */
1343 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
1344 if (GET_CODE (elem
->data
) == DEFINE_ATTR
1345 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
1347 mnemonic_attr
= elem
->data
;
1351 /* A (define_attr "mnemonic" "...") indicates that the back-end
1352 wants a mnemonic attribute to be generated. */
1356 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
1357 htab_eq_string
, 0, xcalloc
, free
);
1359 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
1361 rtx insn
= elem
->data
;
1364 /* Check if the insn definition already has
1365 (set_attr "mnemonic" ...). */
1367 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1368 if (strcmp (XSTR (XVECEXP (insn
, 4, i
), 0), MNEMONIC_ATTR_NAME
) == 0)
1375 gen_mnemonic_setattr (mnemonic_htab
, insn
);
1378 /* Add the user defined values to the hash table. */
1379 str
= XSTR (mnemonic_attr
, 1);
1380 while ((p
= scan_comma_elt (&str
)) != NULL
)
1381 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
1383 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
1385 /* Replace the last ',' with the zero end character. */
1386 *((char *)obstack_next_free (&string_obstack
) - 1) = '\0';
1387 XSTR (mnemonic_attr
, 1) = XOBFINISH (&string_obstack
, char *);
1390 /* The entry point for initializing the reader. */
1393 init_rtx_reader_args_cb (int argc
, char **argv
,
1394 bool (*parse_opt
) (const char *))
1396 /* Prepare to read input. */
1397 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
1398 init_predicate_table ();
1399 obstack_init (rtl_obstack
);
1402 read_md_files (argc
, argv
, parse_opt
, rtx_handle_directive
);
1404 /* Process define_cond_exec patterns. */
1405 if (define_cond_exec_queue
!= NULL
)
1406 process_define_cond_exec ();
1408 if (define_attr_queue
!= NULL
)
1409 gen_mnemonic_attr ();
1414 /* Programs that don't have their own options can use this entry point
1417 init_rtx_reader_args (int argc
, char **argv
)
1419 return init_rtx_reader_args_cb (argc
, argv
, 0);
1422 /* The entry point for reading a single rtx from an md file. */
1425 read_md_rtx (int *lineno
, int *seqnr
)
1427 struct queue_elem
**queue
, *elem
;
1432 /* Read all patterns from a given queue before moving on to the next. */
1433 if (define_attr_queue
!= NULL
)
1434 queue
= &define_attr_queue
;
1435 else if (define_pred_queue
!= NULL
)
1436 queue
= &define_pred_queue
;
1437 else if (define_insn_queue
!= NULL
)
1438 queue
= &define_insn_queue
;
1439 else if (other_queue
!= NULL
)
1440 queue
= &other_queue
;
1445 *queue
= elem
->next
;
1447 read_md_filename
= elem
->filename
;
1448 *lineno
= elem
->lineno
;
1449 *seqnr
= sequence_num
;
1453 /* Discard insn patterns which we know can never match (because
1454 their C test is provably always false). If insn_elision is
1455 false, our caller needs to see all the patterns. Note that the
1456 elided patterns are never counted by the sequence numbering; it
1457 is the caller's responsibility, when insn_elision is false, not
1458 to use elided pattern numbers for anything. */
1459 switch (GET_CODE (desc
))
1463 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
1465 else if (insn_elision
)
1468 /* *seqnr is used here so the name table will match caller's
1469 idea of insn numbering, whether or not elision is active. */
1470 record_insn_name (*seqnr
, XSTR (desc
, 0));
1474 case DEFINE_PEEPHOLE
:
1475 case DEFINE_PEEPHOLE2
:
1476 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
1478 else if (insn_elision
)
1489 /* Helper functions for insn elision. */
1491 /* Compute a hash function of a c_test structure, which is keyed
1492 by its ->expr field. */
1494 hash_c_test (const void *x
)
1496 const struct c_test
*a
= (const struct c_test
*) x
;
1497 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
1505 while ((c
= *s
++) != '\0')
1507 hash
+= c
+ (c
<< 17);
1512 hash
+= len
+ (len
<< 17);
1518 /* Compare two c_test expression structures. */
1520 cmp_c_test (const void *x
, const void *y
)
1522 const struct c_test
*a
= (const struct c_test
*) x
;
1523 const struct c_test
*b
= (const struct c_test
*) y
;
1525 return !strcmp (a
->expr
, b
->expr
);
1528 /* Given a string representing a C test expression, look it up in the
1529 condition_table and report whether or not its value is known
1530 at compile time. Returns a tristate: 1 for known true, 0 for
1531 known false, -1 for unknown. */
1533 maybe_eval_c_test (const char *expr
)
1535 const struct c_test
*test
;
1536 struct c_test dummy
;
1542 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
1548 /* Record the C test expression EXPR in the condition_table, with
1549 value VAL. Duplicates clobber previous entries. */
1552 add_c_test (const char *expr
, int value
)
1554 struct c_test
*test
;
1559 test
= XNEW (struct c_test
);
1561 test
->value
= value
;
1563 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
1566 /* For every C test, call CALLBACK with two arguments: a pointer to
1567 the condition structure and INFO. Stops when CALLBACK returns zero. */
1569 traverse_c_tests (htab_trav callback
, void *info
)
1571 if (condition_table
)
1572 htab_traverse (condition_table
, callback
, info
);
1575 /* Helper functions for define_predicate and define_special_predicate
1576 processing. Shared between genrecog.c and genpreds.c. */
1578 static htab_t predicate_table
;
1579 struct pred_data
*first_predicate
;
1580 static struct pred_data
**last_predicate
= &first_predicate
;
1583 hash_struct_pred_data (const void *ptr
)
1585 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
1589 eq_struct_pred_data (const void *a
, const void *b
)
1591 return !strcmp (((const struct pred_data
*)a
)->name
,
1592 ((const struct pred_data
*)b
)->name
);
1596 lookup_predicate (const char *name
)
1598 struct pred_data key
;
1600 return (struct pred_data
*) htab_find (predicate_table
, &key
);
1603 /* Record that predicate PRED can accept CODE. */
1606 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
1608 if (!pred
->codes
[code
])
1611 pred
->codes
[code
] = true;
1613 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
1614 pred
->allows_non_const
= true;
1621 && code
!= STRICT_LOW_PART
)
1622 pred
->allows_non_lvalue
= true;
1624 if (pred
->num_codes
== 1)
1625 pred
->singleton
= code
;
1626 else if (pred
->num_codes
== 2)
1627 pred
->singleton
= UNKNOWN
;
1632 add_predicate (struct pred_data
*pred
)
1634 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
1637 error ("duplicate predicate definition for '%s'", pred
->name
);
1641 *last_predicate
= pred
;
1642 last_predicate
= &pred
->next
;
1645 /* This array gives the initial content of the predicate table. It
1646 has entries for all predicates defined in recog.c. */
1648 struct std_pred_table
1652 bool allows_const_p
;
1653 RTX_CODE codes
[NUM_RTX_CODE
];
1656 static const struct std_pred_table std_preds
[] = {
1657 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
1658 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
}},
1659 {"register_operand", false, false, {SUBREG
, REG
}},
1660 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
1661 {"scratch_operand", false, false, {SCRATCH
, REG
}},
1662 {"immediate_operand", false, true, {UNKNOWN
}},
1663 {"const_int_operand", false, false, {CONST_INT
}},
1664 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
1665 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
1666 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
1667 {"push_operand", false, false, {MEM
}},
1668 {"pop_operand", false, false, {MEM
}},
1669 {"memory_operand", false, false, {SUBREG
, MEM
}},
1670 {"indirect_operand", false, false, {SUBREG
, MEM
}},
1671 {"ordered_comparison_operator", false, false, {EQ
, NE
,
1673 LEU
, LTU
, GEU
, GTU
}},
1674 {"comparison_operator", false, false, {EQ
, NE
,
1681 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1683 /* Initialize the table of predicate definitions, starting with
1684 the information we have on generic predicates. */
1687 init_predicate_table (void)
1690 struct pred_data
*pred
;
1692 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
1693 eq_struct_pred_data
, 0,
1696 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
1698 pred
= XCNEW (struct pred_data
);
1699 pred
->name
= std_preds
[i
].name
;
1700 pred
->special
= std_preds
[i
].special
;
1702 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
1703 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
1705 if (std_preds
[i
].allows_const_p
)
1706 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
1707 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
1708 add_predicate_code (pred
, (enum rtx_code
) j
);
1710 add_predicate (pred
);
1714 /* These functions allow linkage with print-rtl.c. Also, some generators
1715 like to annotate their output with insn names. */
1717 /* Holds an array of names indexed by insn_code_number. */
1718 static char **insn_name_ptr
= 0;
1719 static int insn_name_ptr_size
= 0;
1722 get_insn_name (int code
)
1724 if (code
< insn_name_ptr_size
)
1725 return insn_name_ptr
[code
];
1731 record_insn_name (int code
, const char *name
)
1733 static const char *last_real_name
= "insn";
1734 static int last_real_code
= 0;
1737 if (insn_name_ptr_size
<= code
)
1740 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
1741 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
1742 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
1743 sizeof(char *) * (new_size
- insn_name_ptr_size
));
1744 insn_name_ptr_size
= new_size
;
1747 if (!name
|| name
[0] == '\0')
1749 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
1750 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
1754 last_real_name
= new_name
= xstrdup (name
);
1755 last_real_code
= code
;
1758 insn_name_ptr
[code
] = new_name
;
1761 /* Make STATS describe the operands that appear in rtx X. */
1764 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
1774 code
= GET_CODE (x
);
1778 case MATCH_OPERATOR
:
1779 case MATCH_PARALLEL
:
1780 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
1787 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
1791 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
1798 fmt
= GET_RTX_FORMAT (code
);
1799 len
= GET_RTX_LENGTH (code
);
1800 for (i
= 0; i
< len
; i
++)
1802 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
1803 get_pattern_stats_1 (stats
, XEXP (x
, i
));
1804 else if (fmt
[i
] == 'E')
1807 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1808 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
1813 /* Make STATS describe the operands that appear in instruction pattern
1817 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
1821 stats
->max_opno
= -1;
1822 stats
->max_dup_opno
= -1;
1823 stats
->max_scratch_opno
= -1;
1824 stats
->num_dups
= 0;
1826 len
= GET_NUM_ELEM (pattern
);
1827 for (i
= 0; i
< len
; i
++)
1828 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
1830 stats
->num_generator_args
= stats
->max_opno
+ 1;
1831 stats
->num_insn_operands
= MAX (stats
->max_opno
,
1832 stats
->max_scratch_opno
) + 1;
1833 stats
->num_operand_vars
= MAX (stats
->max_opno
,
1834 MAX (stats
->max_dup_opno
,
1835 stats
->max_scratch_opno
)) + 1;