+2007-04-03 Richard Guenther <rguenther@suse.de>
+
+ * genpreds.c (write_insn_constraint_len): Write function
+ optimized for CONSTRAINT_LEN implementation.
+ (write_tm_preds_h): Output insn_constraint_len inline and
+ use it for CONSTRAINT_LEN.
+ (write_insn_preds_c): Don't output insn_constraint_len.
+ * doc/md.texi (define_register_constraint): Document multi-letter
+ constraints shall have the same length if they start with the same
+ letter.
+
2007-04-03 Uros Bizjak <ubizjak@gmail.com>
* config.gcc (i[34567]86-*-linux*): Add i386/t-crtpc to tm-file.
@deffn {MD Expression} define_register_constraint name regclass docstring
All three arguments are string constants.
@var{name} is the name of the constraint, as it will appear in
-@code{match_operand} expressions. @var{regclass} can be either the
+@code{match_operand} expressions. If @var{name} is a multi-letter
+constraint its length shall be the same for all constraints starting
+with the same letter. @var{regclass} can be either the
name of the corresponding register class (@pxref{Register Classes}),
or a C expression which evaluates to the appropriate register class.
If it is an expression, it must have no side effects, and it cannot
"}\n");
}
-/* Write out the function which computes constraint name lengths from
- their enumerators. */
+/* Write out a function which looks at a string and determines what
+ the constraint name length is. */
static void
write_insn_constraint_len (void)
{
- struct constraint_data *c;
-
- if (constraint_max_namelen == 1)
- return;
+ unsigned int i;
- puts ("size_t\n"
- "insn_constraint_len (enum constraint_num c)\n"
+ puts ("static inline size_t\n"
+ "insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)\n"
"{\n"
- " switch (c)\n"
+ " switch (fc)\n"
" {");
- FOR_ALL_CONSTRAINTS (c)
- if (c->namelen > 1)
- printf (" case CONSTRAINT_%s: return %lu;\n", c->c_name,
- (unsigned long int) c->namelen);
+ for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
+ {
+ struct constraint_data *c = constraints_by_letter_table[i];
+
+ if (!c
+ || c->namelen == 1)
+ continue;
+
+ /* Constraints with multiple characters should have the same
+ length. */
+ {
+ struct constraint_data *c2 = c->next_this_letter;
+ size_t len = c->namelen;
+ while (c2)
+ {
+ if (c2->namelen != len)
+ error ("Multi-letter constraints with first letter '%c' "
+ "should have same length", i);
+ c2 = c2->next_this_letter;
+ }
+ }
+
+ printf (" case '%c': return %lu;\n",
+ i, (unsigned long int) c->namelen);
+ }
puts (" default: break;\n"
" }\n"
"extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
if (constraint_max_namelen > 1)
- puts ("extern size_t insn_constraint_len (enum constraint_num);\n"
- "#define CONSTRAINT_LEN(c_,s_) "
- "insn_constraint_len (lookup_constraint (s_))\n");
+ {
+ write_insn_constraint_len ();
+ puts ("#define CONSTRAINT_LEN(c_,s_) "
+ "insn_constraint_len (c_,s_)\n");
+ }
else
puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
if (have_register_constraints)
write_regclass_for_constraint ();
write_constraint_satisfied_p ();
- if (constraint_max_namelen > 1)
- write_insn_constraint_len ();
-
if (have_const_int_constraints)
write_insn_const_int_ok_for_constraint ();