summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/doc/md.texi31
-rw-r--r--gcc/genconstants.c3
-rw-r--r--gcc/genenums.c66
-rw-r--r--gcc/print-rtl.c15
6 files changed, 136 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77453d9ba5e..b59e3128651 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
2010-06-10 Richard Sandiford <rdsandiford@googlemail.com>
+ * doc/md.texi: Document the "unspec" and "unspecv" enum names.
+ * Makefile.in (OBJS-common): Include insn-enums.o.
+ (insn-enums.o): New rule.
+ (simple_generated_c): Add insn-enums.c.
+ (build/genenums.o): New rule.
+ (genprogmd): Add "enums".
+ * genconstants.c (print_enum_type): Declare a C string array
+ for each enum.
+ * genenums.c: New file.
+ * print-rtl.c (print_rtx): If defined, use the "unspecv" enum
+ for UNSPEC_VOLATILE. If defined, use the "unspec" enum for both
+ UNSPEC and (as a fallback) for UNSPEC_VOLATILE.
+
+2010-06-10 Richard Sandiford <rdsandiford@googlemail.com>
+
* doc/md.texi (define_enum_attr): Document.
* rtl.def (DEFINE_ENUM_ATTR): New rtx.
* read-md.h (lookup_enum_type): Declare.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 1a543bf18bd..c47ee954d2b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1164,6 +1164,7 @@ OBJS-common = \
insn-peep.o \
insn-preds.o \
insn-recog.o \
+ insn-enums.o \
$(GGC) \
alias.o \
alloc-pool.o \
@@ -3534,6 +3535,7 @@ insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H) \
$(RESOURCE_H) reload.h $(TOPLEV_H) $(REGS_H) tm-constrs.h $(GGC_H) \
$(BASIC_BLOCK_H) $(INTEGRATE_H)
+insn-enums.o : insn-enums.c $(CONFIG_H) $(SYSTEM_H)
insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TOPLEV_H) insn-config.h $(RECOG_H)
insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -3573,7 +3575,7 @@ simple_rtl_generated_c = insn-attrtab.c insn-automata.c insn-emit.c \
simple_generated_h = $(simple_rtl_generated_h) insn-constants.h
-simple_generated_c = $(simple_rtl_generated_c)
+simple_generated_c = $(simple_rtl_generated_c) insn-enums.c
$(simple_generated_h:insn-%.h=s-%) \
$(simple_generated_c:insn-%.c=s-%): s-%: $(MD_DEPS)
@@ -3817,6 +3819,8 @@ build/genconstants.o : genconstants.c $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h errors.h $(READ_MD_H)
build/genemit.o : genemit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
+build/genenums.o : genenums.c $(BCONFIG_H) $(SYSTEM_H) \
+ coretypes.h errors.h $(READ_MD_H)
build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H) \
$(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h \
vecprim.h
@@ -3859,7 +3863,7 @@ genprogrtl = attr attrtab automata codes conditions config emit \
$(genprogrtl:%=build/gen%$(build_exeext)): $(BUILD_RTL)
# All these programs use the MD reader ($(BUILD_MD)).
-genprogmd = $(genprogrtl) mddeps constants
+genprogmd = $(genprogrtl) mddeps constants enums
$(genprogmd:%=build/gen%$(build_exeext)): $(BUILD_MD)
# All generator programs need to report errors
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index d0aa8646ede..c37bb039494 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7997,6 +7997,37 @@ synchronization instructions in a separate @file{sync.md} file,
it is convenient to define all synchronization-specific enumeration
values in @file{sync.md} rather than in the main @file{.md} file.
+Some enumeration names have special significance to GCC:
+
+@table @code
+@item unspecv
+@findex unspec_volatile
+If an enumeration called @code{unspecv} is defined, GCC will use it
+when printing out @code{unspec_volatile} expressions. For example:
+
+@smallexample
+(define_c_enum "unspecv" [
+ UNSPECV_BLOCKAGE
+])
+@end smallexample
+
+causes GCC to print @samp{(unspec_volatile @dots{} 0)} as:
+
+@smallexample
+(unspec_volatile ... UNSPECV_BLOCKAGE)
+@end smallexample
+
+@item unspec
+@findex unspec
+If an enumeration called @code{unspec} is defined, GCC will use
+it when printing out @code{unspec} expressions. GCC will also use
+it when printing out @code{unspec_volatile} expressions unless an
+@code{unspecv} enumeration is also defined. You can therefore
+decide whether to keep separate enumerations for volatile and
+non-volatile expressions or whether to use the same enumeration
+for both.
+@end table
+
@findex define_enum
@anchor{define_enum}
Another way of defining an enumeration is to use @code{define_enum}:
diff --git a/gcc/genconstants.c b/gcc/genconstants.c
index b16a88bc3ea..20b19bfd879 100644
--- a/gcc/genconstants.c
+++ b/gcc/genconstants.c
@@ -69,6 +69,9 @@ print_enum_type (void **slot, void *info ATTRIBUTE_UNUSED)
upcase_string (value_name);
printf ("#define %s %d\n", value_name, def->num_values);
+ /* Declare the array that is generated by genenum. */
+ printf ("extern const char *const %s_strings[];\n", def->name);
+
return 1;
}
diff --git a/gcc/genenums.c b/gcc/genenums.c
new file mode 100644
index 00000000000..8cb48360f62
--- /dev/null
+++ b/gcc/genenums.c
@@ -0,0 +1,66 @@
+/* Generate from machine description the strings for each enum.
+ Copyright (C) 2010 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 3, or (at your option)
+any later version.
+
+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 GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "bconfig.h"
+#include "system.h"
+#include "coretypes.h"
+#include "errors.h"
+#include "read-md.h"
+
+/* Called via traverse_enum_types. Emit an enum definition for
+ enum_type *SLOT. */
+
+static int
+print_enum_type (void **slot, void *info ATTRIBUTE_UNUSED)
+{
+ struct enum_type *def;
+ struct enum_value *value;
+
+ def = (struct enum_type *) *slot;
+ printf ("\nconst char *const %s_strings[] = {", def->name);
+ for (value = def->values; value; value = value->next)
+ {
+ printf ("\n \"%s\"", value->def->name);
+ if (value->next)
+ putc (',', stdout);
+ }
+ printf ("\n};\n");
+ return 1;
+}
+
+int
+main (int argc, char **argv)
+{
+ progname = "genenums";
+
+ if (!read_md_files (argc, argv, NULL, NULL))
+ return (FATAL_EXIT_CODE);
+
+ puts ("/* Generated automatically by the program `genenums'");
+ puts (" from the machine description file. */\n");
+ puts ("#include \"config.h\"\n");
+ puts ("#include \"system.h\"\n");
+
+ traverse_enum_types (print_enum_type, 0);
+
+ if (ferror (stdout) || fflush (stdout) || fclose (stdout))
+ return FATAL_EXIT_CODE;
+
+ return SUCCESS_EXIT_CODE;
+}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index 5cf0f9b6185..96e1485b6ae 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -411,6 +411,21 @@ print_rtx (const_rtx in_rtx)
if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL)
fprintf (outfile, " %d", XINT (in_rtx, i));
}
+#if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
+ else if (i == 1
+ && GET_CODE (in_rtx) == UNSPEC_VOLATILE
+ && XINT (in_rtx, 1) >= 0
+ && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
+ fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
+#endif
+#if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
+ else if (i == 1
+ && (GET_CODE (in_rtx) == UNSPEC
+ || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
+ && XINT (in_rtx, 1) >= 0
+ && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
+ fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
+#endif
else
{
int value = XINT (in_rtx, i);