summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/genrecog.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-10-16 06:09:09 +0000
committerobrien <obrien@FreeBSD.org>1999-10-16 06:09:09 +0000
commitcae8fa8120c70195f34a2456f18c4c848a2d3e0c (patch)
treef7d3a3ab9c32694206552e767626366f016f2062 /contrib/gcc/genrecog.c
parent84656b55b6e25e30322dc903a05de53706361d3d (diff)
downloadFreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.zip
FreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.tar.gz
Virgin import of the GCC 2.95.1 compilers
Diffstat (limited to 'contrib/gcc/genrecog.c')
-rw-r--r--contrib/gcc/genrecog.c206
1 files changed, 113 insertions, 93 deletions
diff --git a/contrib/gcc/genrecog.c b/contrib/gcc/genrecog.c
index a4b14e3..546f922 100644
--- a/contrib/gcc/genrecog.c
+++ b/contrib/gcc/genrecog.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to recognize rtl as insns.
- Copyright (C) 1987, 88, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-95, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -47,23 +47,22 @@ Boston, MA 02111-1307, USA. */
it returns the split rtl in a SEQUENCE. */
#include "hconfig.h"
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include "system.h"
#include "rtl.h"
#include "obstack.h"
+#define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
+ printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER))
+
static struct obstack obstack;
struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* Define this so we can link with print-rtl.o to get debug_rtx function. */
+/* Holds an array of names indexed by insn_code_number. */
char **insn_name_ptr = 0;
+int insn_name_ptr_size = 0;
/* Data structure for a listhead of decision trees. The alternatives
to a node are kept in a doublely-linked list so we can easily add nodes
@@ -91,7 +90,7 @@ struct decision
int elt_one_int; /* Required value for XINT (rtl, 1) */
int test_elt_zero_wide; /* Nonzero if should test XWINT (rtl, 0) */
HOST_WIDE_INT elt_zero_wide; /* Required value for XWINT (rtl, 0) */
- char *tests; /* If nonzero predicate to call */
+ const char *tests; /* If nonzero predicate to call */
int pred; /* `preds' index of predicate or -1 */
char *c_test; /* Additional test to perform */
struct decision_head success; /* Nodes to test on success */
@@ -142,7 +141,7 @@ static int max_depth;
static struct pred_table
{
- char *name;
+ const char *name;
RTX_CODE codes[NUM_RTX_CODE];
} preds[]
= {{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
@@ -162,6 +161,7 @@ static struct pred_table
{"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG}},
{"push_operand", {MEM}},
+ {"pop_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}},
{"indirect_operand", {SUBREG, MEM}},
{"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU}},
@@ -172,7 +172,7 @@ static struct pred_table
static struct decision_head make_insn_sequence PROTO((rtx, enum routine_type));
static struct decision *add_to_sequence PROTO((rtx, struct decision_head *,
- char *));
+ const char *));
static int not_both_true PROTO((struct decision *, struct decision *,
int));
static int position_merit PROTO((struct decision *, enum machine_mode,
@@ -182,24 +182,20 @@ static struct decision_head merge_trees PROTO((struct decision_head,
static int break_out_subroutines PROTO((struct decision_head,
enum routine_type, int));
static void write_subroutine PROTO((struct decision *, enum routine_type));
-static void write_tree_1 PROTO((struct decision *, char *,
+static void write_tree_1 PROTO((struct decision *, const char *,
struct decision *, enum routine_type));
static void print_code PROTO((enum rtx_code));
static int same_codes PROTO((struct decision *, enum rtx_code));
static void clear_codes PROTO((struct decision *));
static int same_modes PROTO((struct decision *, enum machine_mode));
static void clear_modes PROTO((struct decision *));
-static void write_tree PROTO((struct decision *, char *,
+static void write_tree PROTO((struct decision *, const char *,
struct decision *, int,
enum routine_type));
-static void change_state PROTO((char *, char *, int));
-static char *copystr PROTO((char *));
-static void mybzero PROTO((char *, unsigned));
-static void mybcopy PROTO((char *, char *, unsigned));
-static void fatal PVPROTO((char *, ...)) ATTRIBUTE_PRINTF_1;
-char *xrealloc PROTO((char *, unsigned));
-char *xmalloc PROTO((unsigned));
-void fancy_abort PROTO((void));
+static void change_state PROTO((const char *, const char *, int));
+void fatal PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Construct and return a sequence of decisions
that will recognize INSN.
@@ -216,6 +212,38 @@ make_insn_sequence (insn, type)
struct decision *last;
struct decision_head head;
+ {
+ static char *last_real_name = "insn";
+ static int last_real_code = 0;
+ char *name;
+
+ if (insn_name_ptr_size <= next_insn_code)
+ {
+ int new_size;
+ new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
+ insn_name_ptr =
+ (char **) xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ bzero ((PTR)(insn_name_ptr + insn_name_ptr_size),
+ sizeof(char *) * (new_size - insn_name_ptr_size));
+ insn_name_ptr_size = new_size;
+ }
+
+ name = XSTR (insn, 0);
+ if (!name || name[0] == '\0')
+ {
+ name = xmalloc (strlen (last_real_name) + 10);
+ sprintf (name, "%s+%d", last_real_name,
+ next_insn_code - last_real_code);
+ }
+ else
+ {
+ last_real_name = name;
+ last_real_code = next_insn_code;
+ }
+
+ insn_name_ptr[next_insn_code] = name;
+ }
+
if (XVECLEN (insn, type == RECOG) == 1)
x = XVECEXP (insn, type == RECOG, 0);
else
@@ -297,7 +325,7 @@ static struct decision *
add_to_sequence (pattern, last, position)
rtx pattern;
struct decision_head *last;
- char *position;
+ const char *position;
{
register RTX_CODE code;
register struct decision *new
@@ -313,7 +341,7 @@ add_to_sequence (pattern, last, position)
max_depth = depth;
new->number = next_number++;
- new->position = copystr (position);
+ new->position = xstrdup (position);
new->ignore_code = 0;
new->ignore_mode = 0;
new->enforce_mode = 1;
@@ -421,7 +449,7 @@ add_to_sequence (pattern, last, position)
if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
{
- for (i = 0; i < XVECLEN (pattern, 2); i++)
+ for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++)
{
newpos[depth] = i + (code == MATCH_OPERATOR ? '0': 'a');
new = add_to_sequence (XVECEXP (pattern, 2, i),
@@ -436,7 +464,7 @@ add_to_sequence (pattern, last, position)
new->dupno = XINT (pattern, 0);
new->code = UNKNOWN;
new->tests = 0;
- for (i = 0; i < XVECLEN (pattern, 1); i++)
+ for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
{
newpos[depth] = i + '0';
new = add_to_sequence (XVECEXP (pattern, 1, i),
@@ -456,6 +484,19 @@ add_to_sequence (pattern, last, position)
goto restart;
case SET:
+ /* The operands of a SET must have the same mode unless one is VOIDmode. */
+ if (GET_MODE (SET_SRC (pattern)) != VOIDmode
+ && GET_MODE (SET_DEST (pattern)) != VOIDmode
+ && GET_MODE (SET_SRC (pattern)) != GET_MODE (SET_DEST (pattern))
+ /* The mode of an ADDRESS_OPERAND is the mode of the memory reference,
+ not the mode of the address. */
+ && ! (GET_CODE (SET_SRC (pattern)) == MATCH_OPERAND
+ && ! strcmp (XSTR (SET_SRC (pattern), 1), "address_operand")))
+ {
+ print_rtl (stderr, pattern);
+ fputc ('\n', stderr);
+ fatal ("mode mismatch in SET");
+ }
newpos[depth] = '0';
new = add_to_sequence (SET_DEST (pattern), &new->success, newpos);
this->success.first->enforce_mode = 1;
@@ -520,7 +561,7 @@ add_to_sequence (pattern, last, position)
fmt = GET_RTX_FORMAT (code);
len = GET_RTX_LENGTH (code);
- for (i = 0; i < len; i++)
+ for (i = 0; i < (size_t) len; i++)
{
newpos[depth] = '0' + i;
if (fmt[i] == 'e' || fmt[i] == 'u')
@@ -823,8 +864,7 @@ merge_trees (oldh, addh)
struct decision *split
= (struct decision *) xmalloc (sizeof (struct decision));
- mybcopy ((char *) old, (char *) split,
- sizeof (struct decision));
+ memcpy (split, old, sizeof (struct decision));
old->success.first = old->success.last = split;
old->c_test = 0;
@@ -850,8 +890,7 @@ merge_trees (oldh, addh)
struct decision *split
= (struct decision *) xmalloc (sizeof (struct decision));
- mybcopy ((char *) add, (char *) split,
- sizeof (struct decision));
+ memcpy (split, add, sizeof (struct decision));
add->success.first = add->success.last = split;
add->c_test = 0;
@@ -891,7 +930,11 @@ merge_trees (oldh, addh)
old->num_clobbers_to_add = 0;
}
else
- fatal ("Two actions at one point in tree");
+ fatal ("Two actions at one point in tree for insns \"%s\" (%d) and \"%s\" (%d)",
+ insn_name_ptr[old->insn_code_number],
+ old->insn_code_number,
+ insn_name_ptr[add->insn_code_number],
+ add->insn_code_number);
}
if (old->insn_code_number == -1)
@@ -1024,7 +1067,7 @@ write_subroutine (tree, type)
conditions or switch statements. We only support small indentations
and always indent at least two spaces. */
-static char *indents[]
+static const char *indents[]
= {" ", " ", " ", " ", " ", " ", " ", " ",
"\t", "\t ", "\t ", "\t ", "\t ", "\t ", "\t ",
"\t\t", "\t\t ", "\t\t ", "\t\t ", "\t\t ", "\t\t "};
@@ -1053,7 +1096,7 @@ static char *indents[]
static void
write_tree_1 (tree, prevpos, afterward, type)
struct decision *tree;
- char *prevpos;
+ const char *prevpos;
struct decision *afterward;
enum routine_type type;
{
@@ -1096,7 +1139,7 @@ write_tree_1 (tree, prevpos, afterward, type)
printf ("\n");
if (tree && tree->subroutine_number == 0)
{
- printf (" L%d:\n", tree->number);
+ OUTPUT_LABEL (" ", tree->number);
tree->label_needed = 0;
}
@@ -1232,7 +1275,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (p->label_needed && (p->retest_mode || p->retest_code))
{
- printf ("%sL%d:\n", indents[indent - 2], p->number);
+ OUTPUT_LABEL (indents[indent - 2], p->number);
p->label_needed = 0;
}
@@ -1290,7 +1333,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (switch_mode == VOIDmode && mode != VOIDmode && p->next != 0
&& p->next->enforce_mode && p->next->mode != VOIDmode)
{
- mybzero (modemap, sizeof modemap);
+ memset (modemap, 0, sizeof modemap);
printf ("%sswitch (GET_MODE (x%d))\n", indents[indent], depth);
printf ("%s{\n", indents[indent + 2]);
indent += 4;
@@ -1307,7 +1350,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (switch_code == UNKNOWN && p->code != UNKNOWN && ! p->ignore_code
&& p->next != 0 && p->next->code != UNKNOWN)
{
- mybzero (codemap, sizeof codemap);
+ memset (codemap, 0, sizeof codemap);
printf ("%sswitch (GET_CODE (x%d))\n", indents[indent], depth);
printf ("%s{\n", indents[indent + 2]);
indent += 4;
@@ -1323,7 +1366,7 @@ write_tree_1 (tree, prevpos, afterward, type)
/* Now that most mode and code tests have been done, we can write out
a label for an inner node, if we haven't already. */
if (p->label_needed)
- printf ("%sL%d:\n", indents[indent - 2], p->number);
+ OUTPUT_LABEL (indents[indent - 2], p->number);
inner_indent = indent;
@@ -1545,18 +1588,18 @@ clear_modes (p)
static void
write_tree (tree, prevpos, afterward, initial, type)
struct decision *tree;
- char *prevpos;
+ const char *prevpos;
struct decision *afterward;
int initial;
enum routine_type type;
{
register struct decision *p;
- char *name_prefix = (type == SPLIT ? "split" : "recog");
- char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers");
+ const char *name_prefix = (type == SPLIT ? "split" : "recog");
+ const char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers");
if (! initial && tree->subroutine_number > 0)
{
- printf (" L%d:\n", tree->number);
+ OUTPUT_LABEL (" ", tree->number);
if (afterward)
{
@@ -1591,8 +1634,8 @@ write_tree (tree, prevpos, afterward, initial, type)
static void
change_state (oldpos, newpos, indent)
- char *oldpos;
- char *newpos;
+ const char *oldpos;
+ const char *newpos;
int indent;
{
int odepth = strlen (oldpos);
@@ -1618,73 +1661,54 @@ change_state (oldpos, newpos, indent)
}
}
-static char *
-copystr (s1)
- char *s1;
-{
- register char *tem;
-
- if (s1 == 0)
- return 0;
-
- tem = (char *) xmalloc (strlen (s1) + 1);
- strcpy (tem, s1);
-
- return tem;
-}
-
-static void
-mybzero (b, length)
- register char *b;
- register unsigned length;
+char *
+xstrdup (input)
+ const char *input;
{
- while (length-- > 0)
- *b++ = 0;
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
+ return output;
}
-static void
-mybcopy (in, out, length)
- register char *in, *out;
- register unsigned length;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- while (length-- > 0)
- *out++ = *in++;
-}
-
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
-{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-static void
-fatal VPROTO ((char *format, ...))
+void
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genrecog: ");
@@ -1793,10 +1817,6 @@ from the machine description file `md'. */\n\n");
printf ("*/\n\n");
- printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n");
- printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n");
- printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n");
- printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n");
printf ("#define operands recog_operand\n\n");
next_subroutine_number = 0;
OpenPOWER on IntegriCloud