/* Generate code from machine description to recognize rtl as insns.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
+ 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 version.
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
/* This program is used to produce insn-recog.c, which contains a
of tree nodes. Also, if a predicate can match only one code, we can
hardwire that code into the node testing the predicate. */
-static struct pred_table
+static const struct pred_table
{
- const char *name;
- RTX_CODE codes[NUM_RTX_CODE];
+ const char *const name;
+ const RTX_CODE codes[NUM_RTX_CODE];
} preds[] = {
{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM}},
#define NUM_KNOWN_PREDS ARRAY_SIZE (preds)
-static const char * special_mode_pred_table[] = {
+static const char *const special_mode_pred_table[] = {
#ifdef SPECIAL_MODE_PREDICATES
SPECIAL_MODE_PREDICATES
#endif
const char *position;
struct decision_head *last;
{
- register struct decision *new
+ struct decision *new
= (struct decision *) xmalloc (sizeof (struct decision));
memset (new, 0, sizeof (*new));
}
}
- /* A MATCH_OPERAND that is a SET should have an output reload. */
- if (set && code == MATCH_OPERAND
- && XSTR (pattern, 2)[0] != '\0')
+ if (code == MATCH_OPERAND)
{
- if (set_code == '+')
+ const char constraints0 = XSTR (pattern, 2)[0];
+
+ /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
+ don't use the MATCH_OPERAND constraint, only the predicate.
+ This is confusing to folks doing new ports, so help them
+ not make the mistake. */
+ if (GET_CODE (insn) == DEFINE_EXPAND
+ || GET_CODE (insn) == DEFINE_SPLIT
+ || GET_CODE (insn) == DEFINE_PEEPHOLE2)
{
- if (XSTR (pattern, 2)[0] == '+')
- ;
- /* If we've only got an output reload for this operand,
- we'd better have a matching input operand. */
- else if (XSTR (pattern, 2)[0] == '='
- && find_matching_operand (insn, XINT (pattern, 0)))
- ;
- else
+ if (constraints0)
+ message_with_line (pattern_lineno,
+ "warning: constraints not supported in %s",
+ rtx_name[GET_CODE (insn)]);
+ }
+
+ /* A MATCH_OPERAND that is a SET should have an output reload. */
+ else if (set && constraints0)
+ {
+ if (set_code == '+')
+ {
+ if (constraints0 == '+')
+ ;
+ /* If we've only got an output reload for this operand,
+ we'd better have a matching input operand. */
+ else if (constraints0 == '='
+ && find_matching_operand (insn, XINT (pattern, 0)))
+ ;
+ else
+ {
+ message_with_line (pattern_lineno,
+ "operand %d missing in-out reload",
+ XINT (pattern, 0));
+ error_count++;
+ }
+ }
+ else if (constraints0 != '=' && constraints0 != '+')
{
message_with_line (pattern_lineno,
- "operand %d missing in-out reload",
+ "operand %d missing output reload",
XINT (pattern, 0));
error_count++;
}
}
- else if (XSTR (pattern, 2)[0] != '='
- && XSTR (pattern, 2)[0] != '+')
- {
- message_with_line (pattern_lineno,
- "operand %d missing output reload",
- XINT (pattern, 0));
- error_count++;
- }
}
/* Allowing non-lvalues in destinations -- particularly CONST_INT --
dest = SET_DEST (pattern);
src = SET_SRC (pattern);
+ /* STRICT_LOW_PART is a wrapper. Its argument is the real
+ destination, and it's mode should match the source. */
+ if (GET_CODE (dest) == STRICT_LOW_PART)
+ dest = XEXP (dest, 0);
+
/* Find the referant for a DUP. */
if (GET_CODE (dest) == MATCH_DUP
|| GET_CODE (src) == MATCH_PAR_DUP)
src = find_operand (insn, XINT (src, 0));
- /* STRICT_LOW_PART is a wrapper. Its argument is the real
- destination, and it's mode should match the source. */
- if (GET_CODE (dest) == STRICT_LOW_PART)
- dest = XEXP (dest, 0);
-
dmode = GET_MODE (dest);
smode = GET_MODE (src);
struct decision_test *test;
struct decision_test **place;
char *subpos;
- register size_t i;
- register const char *fmt;
+ size_t i;
+ const char *fmt;
int depth = strlen (position);
int len;
enum machine_mode mode;
switch (code)
{
case PARALLEL:
- /* Toplevel peephole pattern. */
+ /* Toplevel peephole pattern. */
if (insn_type == PEEPHOLE2 && top)
{
/* We don't need the node we just created -- unlink it. */
for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++)
{
/* Which insn we're looking at is represented by A-Z. We don't
- ever use 'A', however; it is always implied. */
+ ever use 'A', however; it is always implied. */
subpos[depth] = (i > 0 ? 'A' + i : 0);
sub = add_to_sequence (XVECEXP (pattern, 0, i),
case 'E':
{
- register int j;
+ int j;
for (j = 0; j < XVECLEN (pattern, i); j++)
{
subpos[depth] = 'a' + j;
struct decision_test *t1, *t2;
/* A match_operand with no predicate can match anything. Recognize
- this by the existance of a lone DT_accept_op test. */
+ this by the existence of a lone DT_accept_op test. */
if (d1->type == DT_accept_op || d2->type == DT_accept_op)
return 1;
if (cmp != 0)
{
if (toplevel)
- abort();
+ abort ();
/* If the d2->position was lexically lower, swap. */
if (cmp > 0)
{
struct decision *p, *q, *afterward;
- /* We can't propogate alternatives across subroutine boundaries.
+ /* We can't propagate alternatives across subroutine boundaries.
This is not incorrect, merely a minor optimization loss. */
p = head->first;
new state, branch to node AFTERWARD if non-zero, otherwise return.
Failure to move to the new state can only occur if we are trying to
- match multiple insns and we try to step past the end of the stream. */
+ match multiple insns and we try to step past the end of the stream. */
static void
change_state (oldpos, newpos, afterward, indent)
/* Hunt for the last [A-Z] in both strings. */
for (old_has_insn = odepth - 1; old_has_insn >= 0; --old_has_insn)
- if (oldpos[old_has_insn] >= 'A' && oldpos[old_has_insn] <= 'Z')
+ if (ISUPPER (oldpos[old_has_insn]))
break;
for (new_has_insn = ndepth - 1; new_has_insn >= 0; --new_has_insn)
- if (newpos[new_has_insn] >= 'A' && newpos[new_has_insn] <= 'Z')
+ if (ISUPPER (newpos[new_has_insn]))
break;
/* Go down to desired level. */
while (depth < ndepth)
{
- /* It's a different insn from the first one. */
- if (newpos[depth] >= 'A' && newpos[depth] <= 'Z')
+ /* It's a different insn from the first one. */
+ if (ISUPPER (newpos[depth]))
{
/* We can only fail if we're moving down the tree. */
if (old_has_insn >= 0 && oldpos[old_has_insn] >= newpos[depth])
}
printf ("%sx%d = PATTERN (tem);\n", indent, depth + 1);
}
- else if (newpos[depth] >= 'a' && newpos[depth] <= 'z')
+ else if (ISLOWER (newpos[depth]))
printf ("%sx%d = XVECEXP (x%d, 0, %d);\n",
indent, depth + 1, depth, newpos[depth] - 'a');
else
print_code (code)
enum rtx_code code;
{
- register const char *p;
+ const char *p;
for (p = GET_RTX_NAME (code); *p; p++)
putchar (TOUPPER (*p));
}
|| type == DT_elt_one_int
|| type == DT_elt_zero_wide_safe)
{
- printf (" switch (");
+ const char *indent = "";
+
+ /* We cast switch parameter to integer, so we must ensure that the value
+ fits. */
+ if (type == DT_elt_zero_wide_safe)
+ {
+ indent = " ";
+ printf(" if ((int) XWINT (x%d, 0) == XWINT (x%d, 0))\n", depth, depth);
+ }
+ printf ("%s switch (", indent);
switch (type)
{
case DT_mode:
default:
abort ();
}
- printf (")\n {\n");
+ printf (")\n%s {\n", indent);
do
{
if (p != start && p->need_label && needs_label == NULL)
needs_label = p;
- printf (" case ");
+ printf ("%s case ", indent);
switch (type)
{
case DT_mode:
default:
abort ();
}
- printf (":\n goto L%d;\n", p->success.first->number);
+ printf (":\n%s goto L%d;\n", indent, p->success.first->number);
p->success.first->need_label = 1;
p = p->next;
while (p && p->tests->type == type && !p->tests->next);
case_done:
- printf (" default:\n break;\n }\n");
+ printf ("%s default:\n%s break;\n%s }\n",
+ indent, indent, indent);
return needs_label != NULL ? needs_label : p;
}
int match_len = 0, i;
for (i = strlen (p->position) - 1; i >= 0; --i)
- if (p->position[i] >= 'A' && p->position[i] <= 'Z')
+ if (ISUPPER (p->position[i]))
{
match_len = p->position[i] - 'A';
break;
enum routine_type type;
int initial;
{
- register struct decision *p = head->first;
+ struct decision *p = head->first;
putchar ('\n');
if (p->need_label)
printf ("%sint recog%s PARAMS ((rtx, rtx, int *));\n", s_or_e, extension);
printf ("%sint\n\
recog%s (x0, insn, pnum_clobbers)\n\
- register rtx x0;\n\
+ rtx x0 ATTRIBUTE_UNUSED;\n\
rtx insn ATTRIBUTE_UNUSED;\n\
int *pnum_clobbers ATTRIBUTE_UNUSED;\n", s_or_e, extension);
break;
printf ("%srtx split%s PARAMS ((rtx, rtx));\n", s_or_e, extension);
printf ("%srtx\n\
split%s (x0, insn)\n\
- register rtx x0;\n\
+ rtx x0 ATTRIBUTE_UNUSED;\n\
rtx insn ATTRIBUTE_UNUSED;\n", s_or_e, extension);
break;
case PEEPHOLE2:
s_or_e, extension);
printf ("%srtx\n\
peephole2%s (x0, insn, _pmatch_len)\n\
- register rtx x0;\n\
+ rtx x0 ATTRIBUTE_UNUSED;\n\
rtx insn ATTRIBUTE_UNUSED;\n\
int *_pmatch_len ATTRIBUTE_UNUSED;\n", s_or_e, extension);
break;
}
- printf ("{\n register rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0];\n");
+ printf ("{\n rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0];\n");
for (i = 1; i <= max_depth; i++)
- printf (" register rtx x%d ATTRIBUTE_UNUSED;\n", i);
+ printf (" rtx x%d ATTRIBUTE_UNUSED;\n", i);
printf (" %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int");
memset (&peephole2_tree, 0, sizeof peephole2_tree);
if (argc <= 1)
- fatal ("No input file name.");
+ fatal ("no input file name");
- if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
+ if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
next_insn_code = 0;