* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160582
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
insn-peep.o \
insn-preds.o \
insn-recog.o \
+ insn-enums.o \
$(GGC) \
alias.o \
alloc-pool.o \
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) \
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)
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
$(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
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}:
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;
}
--- /dev/null
+/* 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;
+}
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);