aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2006-01-23 15:14:59 +0000
committerZack Weinberg <zackw@panix.com>2006-01-23 15:14:59 +0000
commit2a5f86a5a1d18ea19a227e212ecd5471408bc602 (patch)
tree44bbde76abf99e1ceeb5bf0420cf8e1a2d685e6c /gcc
parent4277068ecb33a7d9c9513c1f261d2e03242c0a08 (diff)
r110122@banpei: zack | 2006-01-22 14:41:17 -0800
* genextract.c: Don't include insn-config.h. Do include vec.h. Declare vectors of int, char, and locstr. (locstr): New typedef. (struct extraction): Make all array fields into bare pointers. (insn_name_ptr, insn_name_ptr_size): Move down by get_insn_name. (insn_code_number): Delete. (accum_extract): New struct. (VEC_safe_set_locstr, VEC_char_to_string): New functions. (gen_insn): Take insn_code_number as an argument. Use an accum_extract structure instead of loading data directly into a struct extraction, and having to know how big it might get. (walk_rtx): Operate entirely on an accum_extract structure. (print_path): Avoid unnecessary use of printf. (print_header): New function, split out of main. Distinguish more carefully between an unrecognizable insn and an insn that has the code number of a define_expand. (main): Pass insn_code_number to gen_insn. Call print_header only after parsing. Avoid unnecessary use of printf. * Makefile.in (build/vec.o): New rule. (build/genextract): Depend on build/vec.o. (build/genextract.o): Don't depend on insn-config.h. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@110118 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/genextract.c424
3 files changed, 246 insertions, 207 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e2855d8f774..8f01cd23c13 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,29 @@
2006-01-22 Zack Weinberg <zackw@panix.com>
+ * genextract.c: Don't include insn-config.h. Do include vec.h.
+ Declare vectors of int, char, and locstr.
+ (locstr): New typedef.
+ (struct extraction): Make all array fields into bare pointers.
+ (insn_name_ptr, insn_name_ptr_size): Move down by get_insn_name.
+ (insn_code_number): Delete.
+ (accum_extract): New struct.
+ (VEC_safe_set_locstr, VEC_char_to_string): New functions.
+ (gen_insn): Take insn_code_number as an argument. Use an
+ accum_extract structure instead of loading data directly into
+ a struct extraction, and having to know how big it might get.
+ (walk_rtx): Operate entirely on an accum_extract structure.
+ (print_path): Avoid unnecessary use of printf.
+ (print_header): New function, split out of main. Distinguish
+ more carefully between an unrecognizable insn and an insn that
+ has the code number of a define_expand.
+ (main): Pass insn_code_number to gen_insn. Call print_header
+ only after parsing. Avoid unnecessary use of printf.
+ * Makefile.in (build/vec.o): New rule.
+ (build/genextract): Depend on build/vec.o.
+ (build/genextract.o): Don't depend on insn-config.h.
+
+2006-01-22 Zack Weinberg <zackw@panix.com>
+
* Makefile.in: Consolidate most rules that use $(CC_FOR_BUILD) and/or
$(RUN_GEN). Use pattern rules to factor out as much boilerplate as
practical. Eliminate per-generator-program link rules.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6e8553c5099..68bbb698f3c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2876,6 +2876,8 @@ build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(RTL_H) real.h $(GGC_H) errors.h
build/varray.o: varray.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(VARRAY_H) $(RTL_BASE_H) $(GGC_H) $(TREE_H) bitmap.h errors.h
+build/vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h \
+ $(GGC_H) toplev.h
build/insn-conditions.o : insn-conditions.c $(CONFIG_H) $(SYSTEM_H) \
$(GTM_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) $(RECOG_H) real.h \
output.h $(FLAGS_H) hard-reg-set.h $(RESOURCE_H) toplev.h reload.h \
@@ -2904,7 +2906,7 @@ build/genconstants.o : genconstants.c $(RTL_BASE_H) $(BCONFIG_H) \
build/genemit.o : genemit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h
build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H) \
- $(SYSTEM_H) coretypes.h $(GTM_H) insn-config.h errors.h gensupport.h
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H) \
$(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
@@ -2952,6 +2954,7 @@ build/genpreds$(build_exeext) : $(BUILD_PRINT)
build/gengenrtl$(build_exeext) : $(BUILD_ERRORS)
build/genmodes$(build_exeext) : $(BUILD_ERRORS)
+build/genextract$(build_exeext): build/vec.o
# These programs are made from more than one source file.
# The primary source file comes from the pattern rule above.
diff --git a/gcc/genextract.c b/gcc/genextract.c
index 75ff6cec2d7..1fd684228cf 100644
--- a/gcc/genextract.c
+++ b/gcc/genextract.c
@@ -27,9 +27,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "tm.h"
#include "rtl.h"
#include "errors.h"
-#include "insn-config.h"
#include "gensupport.h"
-
+#include "vec.h"
/* This structure contains all the information needed to describe one
set of extractions methods. Each method may be used by more than
@@ -41,131 +40,127 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
of an rtl expression is a vector. genrecog.c makes the same assumption
(and uses the same representation) and it is currently true. */
+typedef char *locstr;
+
struct extraction
{
- int op_count;
- char *oplocs[MAX_RECOG_OPERANDS];
- int dup_count;
- char *duplocs[MAX_DUP_OPERANDS];
- int dupnums[MAX_DUP_OPERANDS];
+ unsigned int op_count;
+ unsigned int dup_count;
+ locstr *oplocs;
+ locstr *duplocs;
+ int *dupnums;
struct code_ptr *insns;
struct extraction *next;
};
-/* Holds a single insn code that use an extraction method. */
-
+/* Holds a single insn code that uses an extraction method. */
struct code_ptr
{
int insn_code;
struct code_ptr *next;
};
+/* All extractions needed for this machine description. */
static struct extraction *extractions;
-/* Holds an array of names indexed by insn_code_number. */
-static char **insn_name_ptr = 0;
-static int insn_name_ptr_size = 0;
-
-/* 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. */
+/* All insn codes for old-style peepholes. */
+static struct code_ptr *peepholes;
-static int dupnums[MAX_DUP_OPERANDS];
+/* This structure is used by gen_insn and walk_rtx to accumulate the
+ data that will be used to produce an extractions structure. */
-/* Record the list of insn_codes for peepholes. */
+DEF_VEC_I(int);
+DEF_VEC_I(char);
+DEF_VEC_P(locstr);
+DEF_VEC_ALLOC_I(int,heap);
+DEF_VEC_ALLOC_I(char,heap);
+DEF_VEC_ALLOC_P(locstr,heap);
-static struct code_ptr *peepholes;
+struct accum_extract
+{
+ VEC(locstr,heap) *oplocs;
+ VEC(locstr,heap) *duplocs;
+ VEC(int,heap) *dupnums;
+ VEC(char,heap) *pathstr;
+};
-static void gen_insn (rtx);
-static void walk_rtx (rtx, const char *);
-static void print_path (const char *);
+/* Forward declarations. */
+static void walk_rtx (rtx, struct accum_extract *);
static void record_insn_name (int, const char *);
static void
-gen_insn (rtx insn)
+gen_insn (rtx insn, int insn_code_number)
{
int i;
+ unsigned int op_count, dup_count, j;
struct extraction *p;
struct code_ptr *link;
+ struct accum_extract acc;
- op_count = 0;
- dup_count = 0;
-
- /* No operands seen so far in this pattern. */
- memset (oplocs, 0, sizeof oplocs);
+ acc.oplocs = VEC_alloc (locstr,heap, 10);
+ acc.duplocs = VEC_alloc (locstr,heap, 10);
+ acc.dupnums = VEC_alloc (int,heap, 10);
+ acc.pathstr = VEC_alloc (char,heap, 20);
/* 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), "");
+ walk_rtx (XVECEXP (insn, 1, 0), &acc);
else
for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
{
- char path[2];
-
- path[0] = 'a' + i;
- path[1] = 0;
-
- walk_rtx (XVECEXP (insn, 1, i), path);
+ VEC_safe_push (char,heap, acc.pathstr, 'a' + i);
+ walk_rtx (XVECEXP (insn, 1, i), &acc);
+ VEC_pop (char, acc.pathstr);
}
- link = xmalloc (sizeof (struct code_ptr));
+ link = XNEW (struct code_ptr);
link->insn_code = insn_code_number;
/* See if we find something that already had this extraction method. */
+ op_count = VEC_length (locstr, acc.oplocs);
+ dup_count = VEC_length (locstr, acc.duplocs);
+ gcc_assert (dup_count == VEC_length (int, acc.dupnums));
+
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;
+ for (j = 0; j < op_count; j++)
+ {
+ char *a = p->oplocs[j];
+ char *b = VEC_index (locstr, acc.oplocs, j);
+ if (a != b && (!a || !b || strcmp (a, b)))
+ break;
+ }
- if (i != op_count)
+ if (j != op_count)
continue;
- for (i = 0; i < dup_count; i++)
- if (p->dupnums[i] != dupnums[i]
- || strcmp (p->duplocs[i], duplocs[i]))
+ for (j = 0; j < dup_count; j++)
+ if (p->dupnums[j] != VEC_index (int, acc.dupnums, j)
+ || strcmp (p->duplocs[j], VEC_index (locstr, acc.duplocs, j)))
break;
- if (i != dup_count)
+ if (j != dup_count)
continue;
/* This extraction is the same as ours. Just link us in. */
link->next = p->insns;
p->insns = link;
- return;
+ goto done;
}
- /* Otherwise, make a new extraction method. */
+ /* Otherwise, make a new extraction method. We stash the arrays
+ after the extraction structure in memory. */
- p = xmalloc (sizeof (struct extraction));
+ p = xmalloc (sizeof (struct extraction)
+ + op_count*sizeof (char *)
+ + dup_count*sizeof (char *)
+ + dup_count*sizeof (int));
p->op_count = op_count;
p->dup_count = dup_count;
p->next = extractions;
@@ -173,28 +168,64 @@ gen_insn (rtx insn)
p->insns = link;
link->next = 0;
- for (i = 0; i < op_count; i++)
- p->oplocs[i] = oplocs[i];
+ p->oplocs = (char **)((char *)p + sizeof (struct extraction));
+ p->duplocs = p->oplocs + op_count;
+ p->dupnums = (int *)(p->duplocs + dup_count);
- for (i = 0; i < dup_count; i++)
- p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i];
+ memcpy(p->oplocs, VEC_address(locstr,acc.oplocs), op_count*sizeof(locstr));
+ memcpy(p->duplocs, VEC_address(locstr,acc.duplocs), dup_count*sizeof(locstr));
+ memcpy(p->dupnums, VEC_address(int, acc.dupnums), dup_count*sizeof(int));
+
+ done:
+ VEC_free (locstr,heap, acc.oplocs);
+ VEC_free (locstr,heap, acc.duplocs);
+ VEC_free (int,heap, acc.dupnums);
+ VEC_free (char,heap, acc.pathstr);
}
+/* Helper subroutine of walk_rtx: given a VEC(locstr), an index, and a
+ string, insert the string at the index, which should either already
+ exist and be NULL, or not yet exist within the vector. In the latter
+ case the vector is enlarged as appropriate. */
static void
-walk_rtx (rtx x, const char *path)
+VEC_safe_set_locstr (VEC(locstr,heap) *v, unsigned int ix, char *str)
+{
+ if (ix < VEC_length (locstr, v))
+ {
+ gcc_assert (VEC_index (locstr, v, ix) == 0);
+ VEC_replace (locstr, v, ix, str);
+ }
+ else
+ {
+ while (ix > VEC_length (locstr, v))
+ VEC_safe_push (locstr,heap, v, 0);
+ VEC_safe_push (locstr,heap, v, str);
+ }
+}
+
+/* Another helper subroutine of walk_rtx: given a VEC(char), convert it
+ to a NUL-terminated string in malloc memory. */
+static char *
+VEC_char_to_string (VEC(char,heap) *v)
+{
+ size_t n = VEC_length (char, v);
+ char *s = xmalloc (n + 1);
+ memcpy (s, VEC_address (char, v), n);
+ s[n] = '\0';
+ return s;
+}
+
+static void
+walk_rtx (rtx x, struct accum_extract *acc)
{
RTX_CODE code;
- int i;
- int len;
+ int i, len, base;
const char *fmt;
- int depth = strlen (path);
- char *newpath;
if (x == 0)
return;
code = GET_CODE (x);
-
switch (code)
{
case PC:
@@ -205,98 +236,68 @@ walk_rtx (rtx x, const char *path)
case MATCH_OPERAND:
case MATCH_SCRATCH:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
+ VEC_safe_set_locstr (acc->oplocs, XINT (x, 0),
+ VEC_char_to_string (acc->pathstr));
break;
- case MATCH_DUP:
- duplocs[dup_count] = xstrdup (path);
- dupnums[dup_count] = XINT (x, 0);
- dup_count++;
- break;
-
- case MATCH_PAR_DUP:
- case MATCH_OP_DUP:
- duplocs[dup_count] = xstrdup (path);
- dupnums[dup_count] = XINT (x, 0);
- dup_count++;
-
- newpath = xmalloc (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
-
- for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
- {
- newpath[depth] = (code == MATCH_OP_DUP ? '0' : 'a') + i;
- walk_rtx (XVECEXP (x, 1, i), newpath);
- }
- free (newpath);
- return;
-
case MATCH_OPERATOR:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
-
- newpath = xmalloc (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
+ case MATCH_PARALLEL:
+ VEC_safe_set_locstr (acc->oplocs, XINT (x, 0),
+ VEC_char_to_string (acc->pathstr));
+ base = (code == MATCH_OPERATOR ? '0' : 'a');
for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
{
- newpath[depth] = '0' + i;
- walk_rtx (XVECEXP (x, 2, i), newpath);
- }
- free (newpath);
+ VEC_safe_push (char,heap, acc->pathstr, base + i);
+ walk_rtx (XVECEXP (x, 2, i), acc);
+ VEC_pop (char, acc->pathstr);
+ }
return;
- case MATCH_PARALLEL:
- oplocs[XINT (x, 0)] = xstrdup (path);
- op_count = MAX (op_count, XINT (x, 0) + 1);
-
- newpath = xmalloc (depth + 2);
- strcpy (newpath, path);
- newpath[depth + 1] = 0;
+ case MATCH_DUP:
+ case MATCH_PAR_DUP:
+ case MATCH_OP_DUP:
+ VEC_safe_push (locstr,heap, acc->duplocs,
+ VEC_char_to_string (acc->pathstr));
+ VEC_safe_push (int,heap, acc->dupnums, XINT (x, 0));
- for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
- {
- newpath[depth] = 'a' + i;
- walk_rtx (XVECEXP (x, 2, i), newpath);
- }
- free (newpath);
- return;
+ if (code == MATCH_DUP)
+ break;
- case ADDRESS:
- walk_rtx (XEXP (x, 0), path);
+ base = (code == MATCH_OP_DUP ? '0' : 'a');
+ for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
+ {
+ VEC_safe_push (char,heap, acc->pathstr, base + i);
+ walk_rtx (XVECEXP (x, 1, i), acc);
+ VEC_pop (char, acc->pathstr);
+ }
return;
default:
break;
}
- newpath = xmalloc (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);
+ VEC_safe_push (char,heap, acc->pathstr, '0' + i);
+ walk_rtx (XEXP (x, i), acc);
+ VEC_pop (char, acc->pathstr);
}
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);
+ VEC_safe_push (char,heap, acc->pathstr, 'a' + j);
+ walk_rtx (XVECEXP (x, i, j), acc);
+ VEC_pop (char, acc->pathstr);
}
}
}
- free (newpath);
}
/* Given a PATH, representing a path down the instruction's
@@ -313,28 +314,28 @@ print_path (const char *path)
{
/* Don't emit "pat", since we may try to take the address of it,
which isn't what is intended. */
- printf("PATTERN (insn)");
+ fputs ("PATTERN (insn)", stdout);
return;
}
/* We first write out the operations (XEXP or XVECEXP) in reverse
- order, then write "insn", then the indices in forward order. */
+ order, then write "pat", then the indices in forward order. */
for (i = len - 1; i >= 0 ; i--)
{
- if (ISLOWER(path[i]))
- printf ("XVECEXP (");
- else if (ISDIGIT(path[i]))
- printf ("XEXP (");
+ if (ISLOWER (path[i]))
+ fputs ("XVECEXP (", stdout);
+ else if (ISDIGIT (path[i]))
+ fputs ("XEXP (", stdout);
else
gcc_unreachable ();
}
- printf ("pat");
+ fputs ("pat", stdout);
for (i = 0; i < len; i++)
{
- if (ISLOWER(path[i]))
+ if (ISLOWER (path[i]))
printf (", 0, %d)", path[i] - 'a');
else if (ISDIGIT(path[i]))
printf (", %d)", path[i] - '0');
@@ -343,71 +344,81 @@ print_path (const char *path)
}
}
+static void
+print_header (void)
+{
+ /* N.B. Code below avoids putting squiggle braces in column 1 inside
+ a string, because this confuses some editors' syntax highlighting
+ engines. */
+
+ puts ("\
+/* Generated automatically by the program `genextract'\n\
+ from the machine description file `md'. */\n\
+\n\
+#include \"config.h\"\n\
+#include \"system.h\"\n\
+#include \"coretypes.h\"\n\
+#include \"tm.h\"\n\
+#include \"rtl.h\"\n\
+#include \"insn-config.h\"\n\
+#include \"recog.h\"\n\
+#include \"toplev.h\"\n\
+\n\
+/* This variable is used as the \"location\" of any missing operand\n\
+ whose numbers are skipped by a given pattern. */\n\
+static rtx junk ATTRIBUTE_UNUSED;\n");
+
+ puts ("\
+void\n\
+insn_extract (rtx insn)\n{\n\
+ rtx *ro = recog_data.operand;\n\
+ rtx **ro_loc = recog_data.operand_loc;\n\
+ rtx pat = PATTERN (insn);\n\
+ int i ATTRIBUTE_UNUSED; /* only for peepholes */\n\
+\n\
+#ifdef ENABLE_CHECKING\n\
+ memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
+ memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
+#endif\n");
+
+ puts ("\
+ switch (INSN_CODE (insn))\n\
+ {\n\
+ default:\n\
+ /* Control reaches here if insn_extract has been called with an\n\
+ unrecognizable insn (code -1), or an insn whose INSN_CODE\n\
+ corresponds to a DEFINE_EXPAND in the machine description;\n\
+ either way, a bug. */\n\
+ if (INSN_CODE (insn) < 0)\n\
+ fatal_insn (\"unrecognizable insn:\", insn);\n\
+ else\n\
+ fatal_insn (\"insn with invalid code number:\", insn);\n");
+}
int
main (int argc, char **argv)
{
rtx desc;
- int i;
+ unsigned int i;
struct extraction *p;
struct code_ptr *link;
const char *name;
+ int insn_code_number;
+ int line_no;
progname = "genextract";
if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
- /* 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 \"coretypes.h\"\n");
- printf ("#include \"tm.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 (rtx insn)\n");
- printf ("{\n");
- printf (" rtx *ro = recog_data.operand;\n");
- printf (" rtx **ro_loc = recog_data.operand_loc;\n");
- printf (" rtx pat = PATTERN (insn);\n");
- printf (" int i ATTRIBUTE_UNUSED;\n\n");
-#ifdef ENABLE_CHECKING
- printf (" memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
- printf (" memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
-#endif
- 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)
+ while ((desc = read_md_rtx (&line_no, &insn_code_number)) != NULL)
{
- int line_no;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
- break;
-
if (GET_CODE (desc) == DEFINE_INSN)
{
record_insn_name (insn_code_number, XSTR (desc, 0));
- gen_insn (desc);
+ gen_insn (desc, insn_code_number);
}
else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
@@ -420,6 +431,8 @@ from the machine description file `md'. */\n\n");
}
}
+ print_header ();
+
/* Write out code to handle peepholes and the insn_codes that it should
be called for. */
if (peepholes)
@@ -432,9 +445,9 @@ from the machine description file `md'. */\n\n");
created just for the sake of this function. We need to set the
location of the operands for sake of simplifications after
extraction, like eliminating subregs. */
- printf (" for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n");
- printf (" ro[i] = *(ro_loc[i] = &XVECEXP (pat, 0, i));\n");
- printf (" break;\n\n");
+ puts (" for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n"
+ " ro[i] = *(ro_loc[i] = &XVECEXP (pat, 0, i));\n"
+ " break;\n");
}
/* Write out all the ways to extract insn operands. */
@@ -461,7 +474,7 @@ from the machine description file `md'. */\n\n");
{
printf (" ro[%d] = *(ro_loc[%d] = &", i, i);
print_path (p->oplocs[i]);
- printf (");\n");
+ puts (");");
}
}
@@ -469,25 +482,24 @@ from the machine description file `md'. */\n\n");
{
printf (" recog_data.dup_loc[%d] = &", i);
print_path (p->duplocs[i]);
- printf (";\n");
+ puts (";");
printf (" recog_data.dup_num[%d] = %d;\n", i, p->dupnums[i]);
}
- printf (" break;\n\n");
+ puts (" break;\n");
}
- /* This should never be reached. Note that we would also reach here
- if we tried to extract something whose INSN_CODE was a
- DEFINE_EXPAND or DEFINE_SPLIT, but that is correct. */
- printf (" default:\n gcc_unreachable ();\n");
-
- printf (" }\n}\n");
-
+ puts (" }\n}");
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
/* 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. */
+static char **insn_name_ptr = 0;
+static int insn_name_ptr_size = 0;
+
const char *
get_insn_name (int code ATTRIBUTE_UNUSED)
{