/* Generate code from to output assembler insns as recognized from rtl.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
- 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This program reads the machine description for the compiler target machine
{
struct data *next;
const char *name;
- const char *template;
+ const char *template_code;
int code_number;
int index_number;
const char *filename;
printf ("#include \"toplev.h\"\n");
printf ("#include \"output.h\"\n");
printf ("#include \"target.h\"\n");
+ printf ("#include \"tm-constrs.h\"\n");
}
static void
break;
case INSN_OUTPUT_FORMAT_SINGLE:
{
- const char *p = d->template;
+ const char *p = d->template_code;
char prev = 0;
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
templates, or C code to generate the assembler code template. */
static void
-process_template (struct data *d, const char *template)
+process_template (struct data *d, const char *template_code)
{
const char *cp;
int i;
/* Templates starting with * contain straight code to be run. */
- if (template[0] == '*')
+ if (template_code[0] == '*')
{
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
puts ("\nstatic const char *");
printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
d->code_number);
puts ("{");
- print_rtx_ptr_loc (template);
- puts (template + 1);
+ print_rtx_ptr_loc (template_code);
+ puts (template_code + 1);
puts ("}");
}
/* If the assembler code template starts with a @ it is a newline-separated
list of assembler code templates, one for each alternative. */
- else if (template[0] == '@')
+ else if (template_code[0] == '@')
{
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_MULTI;
printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
- for (i = 0, cp = &template[1]; *cp; )
+ for (i = 0, cp = &template_code[1]; *cp; )
{
const char *ep, *sp;
}
else
{
- d->template = template;
+ d->template_code = template_code;
d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
}
}
have_error = 1;
}
}
+
+static void
+validate_optab_operands (struct data *d)
+{
+ if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
+ return;
+
+ /* Miscellaneous tests. */
+ if (strncmp (d->name, "cstore", 6) == 0
+ && d->name[strlen (d->name) - 1] == '4'
+ && d->operand[0].mode == VOIDmode)
+ {
+ message_with_line (d->lineno, "missing mode for operand 0 of cstore");
+ have_error = 1;
+ }
+}
\f
/* Look at a define_insn just read. Assign its code number. Record
on idata the template and the number of arguments. If the insn has
#endif
validate_insn_operands (d);
validate_insn_alternatives (d);
+ validate_optab_operands (d);
place_operands (d);
process_template (d, XTMPL (insn, 3));
}
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_NONE;
validate_insn_alternatives (d);
+ validate_optab_operands (d);
place_operands (d);
}
\f
d->n_operands = max_opno + 1;
d->n_dups = 0;
d->n_alternatives = 0;
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_NONE;
place_operands (d);
{
const char *name = XSTR (exp, 0);
unsigned int namelen = strlen (name);
- struct constraint_data **iter, **slot, *new;
+ struct constraint_data **iter, **slot, *new_cdata;
- if (strchr (indep_constraints, name[0]))
+ /* The 'm' constraint is special here since that constraint letter
+ can be overridden by the back end by defining the
+ TARGET_MEM_CONSTRAINT macro. */
+ if (strchr (indep_constraints, name[0]) && name[0] != 'm')
{
if (name[1] == '\0')
message_with_line (lineno, "constraint letter '%s' cannot be "
return;
}
}
- new = xmalloc (sizeof (struct constraint_data) + namelen);
- strcpy ((char *)new + offsetof(struct constraint_data, name), name);
- new->namelen = namelen;
- new->lineno = lineno;
- new->next_this_letter = *slot;
- *slot = new;
+ new_cdata = XNEWVAR (struct constraint_data, sizeof (struct constraint_data) + namelen);
+ strcpy ((char *)new_cdata + offsetof(struct constraint_data, name), name);
+ new_cdata->namelen = namelen;
+ new_cdata->lineno = lineno;
+ new_cdata->next_this_letter = *slot;
+ *slot = new_cdata;
}
/* Return the length of the constraint name beginning at position S