aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/genextract.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/genextract.c')
-rw-r--r--contrib/gcc/genextract.c561
1 files changed, 0 insertions, 561 deletions
diff --git a/contrib/gcc/genextract.c b/contrib/gcc/genextract.c
deleted file mode 100644
index 24d3d511975d..000000000000
--- a/contrib/gcc/genextract.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/* Generate code from machine description to extract operands from insn as rtl.
- Copyright (C) 1987, 91-93, 97-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-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
-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.
-
-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. */
-
-
-#include "hconfig.h"
-#include "system.h"
-#include "rtl.h"
-#include "obstack.h"
-#include "insn-config.h"
-
-static struct obstack obstack;
-struct obstack *rtl_obstack = &obstack;
-
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-/* Names for patterns. Need to allow linking with print-rtl. */
-char **insn_name_ptr;
-
-/* This structure contains all the information needed to describe one
- set of extractions methods. Each method may be used by more than
- one pattern if the operands are in the same place.
-
- The string for each operand describes that path to the operand and
- contains `0' through `9' when going into an expression and `a' through
- `z' when going into a vector. We assume here that only the first operand
- of an rtl expression is a vector. genrecog.c makes the same assumption
- (and uses the same representation) and it is currently true. */
-
-struct extraction
-{
- int op_count;
- char *oplocs[MAX_RECOG_OPERANDS];
- int dup_count;
- char *duplocs[MAX_DUP_OPERANDS];
- int dupnums[MAX_DUP_OPERANDS];
- struct code_ptr *insns;
- struct extraction *next;
-};
-
-/* Holds a single insn code that use an extraction method. */
-
-struct code_ptr
-{
- int insn_code;
- struct code_ptr *next;
-};
-
-static struct extraction *extractions;
-
-/* Number instruction patterns handled, starting at 0 for first one. */
-
-static int insn_code_number;
-
-/* Records the large operand number in this insn. */
-
-static int op_count;
-
-/* Records the location of any operands using the string format described
- above. */
-
-static char *oplocs[MAX_RECOG_OPERANDS];
-
-/* Number the occurrences of MATCH_DUP in each instruction,
- starting at 0 for the first occurrence. */
-
-static int dup_count;
-
-/* Records the location of any MATCH_DUP operands. */
-
-static char *duplocs[MAX_DUP_OPERANDS];
-
-/* Record the operand number of any MATCH_DUPs. */
-
-static int dupnums[MAX_DUP_OPERANDS];
-
-/* Record the list of insn_codes for peepholes. */
-
-static struct code_ptr *peepholes;
-
-static void gen_insn PROTO ((rtx));
-static void walk_rtx PROTO ((rtx, const char *));
-static void print_path PROTO ((char *));
-void fatal PVPROTO ((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-void fancy_abort PROTO ((void)) ATTRIBUTE_NORETURN;
-
-static void
-gen_insn (insn)
- rtx insn;
-{
- register int i;
- register struct extraction *p;
- register struct code_ptr *link;
-
- op_count = 0;
- dup_count = 0;
-
- /* No operands seen so far in this pattern. */
- memset (oplocs, 0, sizeof oplocs);
-
- /* Walk the insn's pattern, remembering at all times the path
- down to the walking point. */
-
- if (XVECLEN (insn, 1) == 1)
- walk_rtx (XVECEXP (insn, 1, 0), "");
- else
- for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
- {
- char *path = (char *) alloca (2);
-
- path[0] = 'a' + i;
- path[1] = 0;
-
- walk_rtx (XVECEXP (insn, 1, i), path);
- }
-
- link = (struct code_ptr *) xmalloc (sizeof (struct code_ptr));
- link->insn_code = insn_code_number;
-
- /* See if we find something that already had this extraction method. */
-
- for (p = extractions; p; p = p->next)
- {
- if (p->op_count != op_count || p->dup_count != dup_count)
- continue;
-
- for (i = 0; i < op_count; i++)
- if (p->oplocs[i] != oplocs[i]
- && ! (p->oplocs[i] != 0 && oplocs[i] != 0
- && ! strcmp (p->oplocs[i], oplocs[i])))
- break;
-
- if (i != op_count)
- continue;
-
- for (i = 0; i < dup_count; i++)
- if (p->dupnums[i] != dupnums[i]
- || strcmp (p->duplocs[i], duplocs[i]))
- break;
-
- if (i != dup_count)
- continue;
-
- /* This extraction is the same as ours. Just link us in. */
- link->next = p->insns;
- p->insns = link;
- return;
- }
-
- /* Otherwise, make a new extraction method. */
-
- p = (struct extraction *) xmalloc (sizeof (struct extraction));
- p->op_count = op_count;
- p->dup_count = dup_count;
- p->next = extractions;
- extractions = p;
- p->insns = link;
- link->next = 0;
-
- for (i = 0; i < op_count; i++)
- p->oplocs[i] = oplocs[i];
-
- for (i = 0; i < dup_count; i++)
- p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i];
-}
-
-static void
-walk_rtx (x, path)
- rtx x;
- const char *path;
-{
- register RTX_CODE code;
- register int i;
- register int len;
- register char *fmt;
- int depth = strlen (path);
- char *newpath;
-
- if (x == 0)
- return;
-
- code = GET_CODE (x);
-
- switch (code)
- {
- case PC:
- case CC0:
- case CONST_INT:
- case SYMBOL_REF:
- return;
-
- case MATCH_OPERAND:
- case MATCH_SCRATCH:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
- break;
-
- case MATCH_DUP:
- case MATCH_PAR_DUP:
- duplocs[dup_count] = xstrdup (path);
- dupnums[dup_count] = XINT (x, 0);
- dup_count++;
- break;
-
- case MATCH_OP_DUP:
- duplocs[dup_count] = xstrdup (path);
- dupnums[dup_count] = XINT (x, 0);
- dup_count++;
-
- newpath = (char *) alloca (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
-
- for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
- {
- newpath[depth] = '0' + i;
- walk_rtx (XVECEXP (x, 1, i), newpath);
- }
- return;
-
- case MATCH_OPERATOR:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
-
- newpath = (char *) alloca (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
-
- for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
- {
- newpath[depth] = '0' + i;
- walk_rtx (XVECEXP (x, 2, i), newpath);
- }
- return;
-
- case MATCH_PARALLEL:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
-
- newpath = (char *) alloca (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
-
- for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
- {
- newpath[depth] = 'a' + i;
- walk_rtx (XVECEXP (x, 2, i), newpath);
- }
- return;
-
- case ADDRESS:
- walk_rtx (XEXP (x, 0), path);
- return;
-
- default:
- break;
- }
-
- newpath = (char *) alloca (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
-
- fmt = GET_RTX_FORMAT (code);
- len = GET_RTX_LENGTH (code);
- for (i = 0; i < len; i++)
- {
- if (fmt[i] == 'e' || fmt[i] == 'u')
- {
- newpath[depth] = '0' + i;
- walk_rtx (XEXP (x, i), newpath);
- }
- else if (fmt[i] == 'E')
- {
- int j;
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- {
- newpath[depth] = 'a' + j;
- walk_rtx (XVECEXP (x, i, j), newpath);
- }
- }
- }
-}
-
-/* Given a PATH, representing a path down the instruction's
- pattern from the root to a certain point, output code to
- evaluate to the rtx at that point. */
-
-static void
-print_path (path)
- char *path;
-{
- register int len = strlen (path);
- register int i;
-
- if (len == 0)
- {
- /* Don't emit "pat", since we may try to take the address of it,
- which isn't what is intended. */
- printf("PATTERN (insn)");
- return;
- }
-
- /* We first write out the operations (XEXP or XVECEXP) in reverse
- order, then write "insn", then the indices in forward order. */
-
- for (i = len - 1; i >=0 ; i--)
- {
- if (path[i] >= 'a' && path[i] <= 'z')
- printf ("XVECEXP (");
- else if (path[i] >= '0' && path[i] <= '9')
- printf ("XEXP (");
- else
- abort ();
- }
-
- printf ("pat");
-
- for (i = 0; i < len; i++)
- {
- if (path[i] >= 'a' && path[i] <= 'z')
- printf (", 0, %d)", path[i] - 'a');
- else if (path[i] >= '0' && path[i] <= '9')
- printf (", %d)", path[i] - '0');
- else
- abort ();
- }
-}
-
-PTR
-xmalloc (size)
- size_t size;
-{
- register PTR val = (PTR) malloc (size);
-
- if (val == 0)
- fatal ("virtual memory exhausted");
- return val;
-}
-
-PTR
-xrealloc (old, size)
- PTR old;
- size_t size;
-{
- register PTR ptr;
- if (old)
- ptr = (PTR) realloc (old, size);
- else
- ptr = (PTR) malloc (size);
- if (!ptr)
- fatal ("virtual memory exhausted");
- return ptr;
-}
-
-void
-fatal VPROTO ((const char *format, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *format;
-#endif
- va_list ap;
-
- VA_START (ap, format);
-
-#ifndef ANSI_PROTOTYPES
- format = va_arg (ap, const char *);
-#endif
-
- fprintf (stderr, "genextract: ");
- vfprintf (stderr, format, ap);
- va_end (ap);
- fprintf (stderr, "\n");
- exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
- config.h can #define abort fancy_abort if you like that sort of thing. */
-
-void
-fancy_abort ()
-{
- fatal ("Internal gcc abort.");
-}
-
-char *
-xstrdup (input)
- const char *input;
-{
- register size_t len = strlen (input) + 1;
- register char *output = xmalloc (len);
- memcpy (output, input, len);
- return output;
-}
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- rtx desc;
- FILE *infile;
- register int c, i;
- struct extraction *p;
- struct code_ptr *link;
-
- obstack_init (rtl_obstack);
-
- if (argc <= 1)
- fatal ("No input file name.");
-
- infile = fopen (argv[1], "r");
- if (infile == 0)
- {
- perror (argv[1]);
- exit (FATAL_EXIT_CODE);
- }
-
- init_rtl ();
-
- /* Assign sequential codes to all entries in the machine description
- in parallel with the tables in insn-output.c. */
-
- insn_code_number = 0;
-
- printf ("/* Generated automatically by the program `genextract'\n\
-from the machine description file `md'. */\n\n");
-
- printf ("#include \"config.h\"\n");
- printf ("#include \"system.h\"\n");
- printf ("#include \"rtl.h\"\n");
- printf ("#include \"insn-config.h\"\n");
- printf ("#include \"recog.h\"\n");
- printf ("#include \"toplev.h\"\n\n");
-
- /* This variable exists only so it can be the "location"
- of any missing operand whose numbers are skipped by a given pattern. */
- printf ("static rtx junk ATTRIBUTE_UNUSED;\n");
-
- printf ("void\ninsn_extract (insn)\n");
- printf (" rtx insn;\n");
- printf ("{\n");
- printf (" register rtx *ro = recog_operand;\n");
- printf (" register rtx **ro_loc = recog_operand_loc;\n");
- printf (" rtx pat = PATTERN (insn);\n");
- printf (" int i ATTRIBUTE_UNUSED;\n\n");
- printf (" memset (ro, 0, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
- printf (" memset (ro_loc, 0, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
- printf (" switch (INSN_CODE (insn))\n");
- printf (" {\n");
- printf (" case -1:\n");
- printf (" fatal_insn_not_found (insn);\n\n");
-
- /* Read the machine description. */
-
- while (1)
- {
- c = read_skip_spaces (infile);
- if (c == EOF)
- break;
- ungetc (c, infile);
-
- desc = read_rtx (infile);
- if (GET_CODE (desc) == DEFINE_INSN)
- {
- gen_insn (desc);
- ++insn_code_number;
- }
-
- else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
- {
- struct code_ptr *link
- = (struct code_ptr *) xmalloc (sizeof (struct code_ptr));
-
- link->insn_code = insn_code_number;
- link->next = peepholes;
- peepholes = link;
- ++insn_code_number;
- }
-
- else if (GET_CODE (desc) == DEFINE_EXPAND
- || GET_CODE (desc) == DEFINE_SPLIT)
- ++insn_code_number;
- }
-
- /* Write out code to handle peepholes and the insn_codes that it should
- be called for. */
- if (peepholes)
- {
- for (link = peepholes; link; link = link->next)
- printf (" case %d:\n", link->insn_code);
-
- /* The vector in the insn says how many operands it has.
- And all it contains are operands. In fact, the vector was
- created just for the sake of this function. */
- printf (" for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n");
- printf (" ro[i] = XVECEXP (pat, 0, i);\n");
- printf (" break;\n\n");
- }
-
- /* Write out all the ways to extract insn operands. */
- for (p = extractions; p; p = p->next)
- {
- for (link = p->insns; link; link = link->next)
- printf (" case %d:\n", link->insn_code);
-
- for (i = 0; i < p->op_count; i++)
- {
- if (p->oplocs[i] == 0)
- {
- printf (" ro[%d] = const0_rtx;\n", i);
- printf (" ro_loc[%d] = &junk;\n", i);
- }
- else
- {
- printf (" ro[%d] = *(ro_loc[%d] = &", i, i);
- print_path (p->oplocs[i]);
- printf (");\n");
- }
- }
-
- for (i = 0; i < p->dup_count; i++)
- {
- printf (" recog_dup_loc[%d] = &", i);
- print_path (p->duplocs[i]);
- printf (";\n");
- printf (" recog_dup_num[%d] = %d;\n", i, p->dupnums[i]);
- }
-
- printf (" break;\n\n");
- }
-
- /* This should never be reached. Note that we would also reach this abort
- if we tried to extract something whose INSN_CODE was a DEFINE_EXPAND or
- DEFINE_SPLIT, but that is correct. */
- printf (" default:\n abort ();\n");
-
- printf (" }\n}\n");
-
- fflush (stdout);
- exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
- /* NOTREACHED */
- return 0;
-}