This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: SH: use register names instead of numbers
- To: rth at redhat dot com (Richard Henderson)
- Subject: Re: SH: use register names instead of numbers
- From: Joern Rennecke <amylaar at redhat dot com>
- Date: Wed, 22 Nov 2000 00:10:33 +0000 (GMT)
- Cc: amylaar at redhat dot com (Joern Rennecke), zackw at Stanford dot EDU (Zack Weinberg), aoliva at redhat dot com (Alexandre Oliva), gcc-patches at gcc dot gnu dot org
> One, documentation needs to be added to md.texi. Two,
>
> > + hashtab.o: $(srcdir)/../libiberty/hashtab.c $(CONFIG_H)
> > + rm -f hashtab.c
> > + $(LN_S) $(srcdir)/../libiberty/hashtab.c hashtab.c
> > + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) hashtab.c
>
> This needs to be using HOST_CC etc.
Done. I have also resolved a few merge problems with the most recent
fsf sources. Most notably, I had to put xcalloc into gensupport.c
(libiberty/xmalloc.c has it, but it not only needs xexit, but also provides
lots of functions that are already in gensupport.c .)
I have looked at the new md.texi paragraph as dvi with xdvi and as info
with a text editor. I don't know if is completely info-matically correct,
though.
Wed Nov 22 00:04:09 2000 J"orn Rennecke <amylaar@redhat.com>
* rtl.h (traverse_md_constants): Declare.
(struct md_constant): Define.
* Makefile.in (HOST_RTL): Add hashtab.o .
(OBJS): Add hashtab.o .
(hashtab.o): New rule.
(rtl.o): Depends on HASHTAB_H.
* rtl.c (hashtab.h): #include.
(md_constants): New static variable.
(def_hash, def_name_eq_p, read_constants): New static functions.
(traverse_md_constants): New function.
(read_name): Do constant expansion.
(read_rtx): Recognize define_constants.
* gencodes.c (print_md_constant): New function.
(main): Emit #defines for all constant definitions encountered.
* md.texi (Constant Definitions): New node.
* gensupport.c (xcalloc): New function.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.545
diff -p -r1.545 Makefile.in
*** Makefile.in 2000/11/19 00:30:05 1.545
--- Makefile.in 2000/11/22 00:06:02
*************** HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HO
*** 633,639 ****
$(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) $(HOST_CLIB)
HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o \
! $(HOST_PREFIX)ggc-none.o gensupport.o
HOST_PRINT = $(HOST_PREFIX)print-rtl.o
HOST_ERRORS = $(HOST_PREFIX)errors.o
--- 633,639 ----
$(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) $(HOST_CLIB)
HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o \
! $(HOST_PREFIX)ggc-none.o gensupport.o hashtab.o
HOST_PRINT = $(HOST_PREFIX)print-rtl.o
HOST_ERRORS = $(HOST_PREFIX)errors.o
*************** OBJS = diagnostic.o version.o tree.o pri
*** 735,741 ****
profile.o insn-attrtab.o $(out_object_file) $(EXTRA_OBJS) convert.o \
mbchar.o splay-tree.o graph.o sbitmap.o resource.o hash.o predict.o \
lists.o ggc-common.o $(GGC) stringpool.o simplify-rtx.o ssa.o bb-reorder.o \
! sibcall.o conflict.o timevar.o ifcvt.o dominance.o dependence.o dce.o
BACKEND = toplev.o libbackend.a
--- 735,742 ----
profile.o insn-attrtab.o $(out_object_file) $(EXTRA_OBJS) convert.o \
mbchar.o splay-tree.o graph.o sbitmap.o resource.o hash.o predict.o \
lists.o ggc-common.o $(GGC) stringpool.o simplify-rtx.o ssa.o bb-reorder.o \
! sibcall.o conflict.o timevar.o ifcvt.o dominance.o dependence.o dce.o \
! hashtab.o
BACKEND = toplev.o libbackend.a
*************** $(MD_FILE): $(MD_DEPS)
*** 1653,1658 ****
--- 1654,1664 ----
gensupport.o: gensupport.c $(RTL_H) $(OBSTACK_H) system.h errors.h gensupport.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gensupport.c
+ hashtab.o: $(srcdir)/../libiberty/hashtab.c $(CONFIG_H)
+ rm -f hashtab.c
+ $(LN_S) $(srcdir)/../libiberty/hashtab.c hashtab.c
+ $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) hashtab.c
+
genconfig : genconfig.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
genconfig.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
*************** gengenrtl.o : gengenrtl.c $(RTL_BASE_H)
*** 1749,1755 ****
# and HOST_PREFIX_1 is `foobar', just to ensure these rules don't conflict
# with the rules for rtl.o, alloca.o, etc.
$(HOST_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(CONFIG_H) system.h $(RTL_H) \
! bitmap.h $(GGC_H) toplev.h
rm -f $(HOST_PREFIX)rtl.c
sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(HOST_PREFIX)rtl.c
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)rtl.c
--- 1755,1761 ----
# and HOST_PREFIX_1 is `foobar', just to ensure these rules don't conflict
# with the rules for rtl.o, alloca.o, etc.
$(HOST_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(CONFIG_H) system.h $(RTL_H) \
! bitmap.h $(GGC_H) toplev.h $(HASHTAB_H)
rm -f $(HOST_PREFIX)rtl.c
sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(HOST_PREFIX)rtl.c
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)rtl.c
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gencodes.c,v
retrieving revision 1.32
diff -p -r1.32 gencodes.c
*** gencodes.c 2000/08/04 07:01:30 1.32
--- gencodes.c 2000/11/22 00:06:02
*************** Boston, MA 02111-1307, USA. */
*** 32,37 ****
--- 32,38 ----
static int insn_code_number;
static void gen_insn PARAMS ((rtx));
+ static int print_md_constant PARAMS ((void **, void *));
static void
gen_insn (insn)
*************** from the machine description file `md'.
*** 86,95 ****
printf (" CODE_FOR_nothing = %d };\n", insn_code_number + 1);
! printf ("\n#define MAX_INSN_CODE ((int) CODE_FOR_nothing)\n");
! printf ("#endif /* MAX_INSN_CODE */\n");
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
--- 87,98 ----
printf (" CODE_FOR_nothing = %d };\n", insn_code_number + 1);
! printf ("\n#define MAX_INSN_CODE ((int) CODE_FOR_nothing)\n\n");
! traverse_md_constants (print_md_constant, stdout);
+ printf ("\n#endif /* MAX_INSN_CODE */\n");
+
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
*************** get_insn_name (code)
*** 100,103 ****
--- 103,120 ----
int code ATTRIBUTE_UNUSED;
{
return NULL;
+ }
+
+ /* Called via traverse_md_constants; emit a #define for
+ the current constant definition. */
+ static int
+ print_md_constant (slot, info)
+ void **slot;
+ void *info;
+ {
+ struct md_constant *def = *slot;
+ FILE *file = info;
+
+ fprintf (file, "#define %s %s\n", def->name, def->value);
+ return 1;
}
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.c,v
retrieving revision 1.11
diff -p -r1.11 gensupport.c
*** gensupport.c 2000/07/12 16:17:15 1.11
--- gensupport.c 2000/11/22 00:06:02
*************** xstrdup (input)
*** 863,868 ****
--- 863,883 ----
}
PTR
+ xcalloc (nelem, elsize)
+ size_t nelem, elsize;
+ {
+ PTR newmem;
+
+ if (nelem == 0 || elsize == 0)
+ nelem = elsize = 1;
+
+ newmem = calloc (nelem, elsize);
+ if (!newmem)
+ fatal ("virtual memory exhausted");
+ return (newmem);
+ }
+
+ PTR
xrealloc (old, size)
PTR old;
size_t size;
Index: md.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/md.texi,v
retrieving revision 1.48
diff -p -r1.48 md.texi
*** md.texi 2000/09/13 19:23:34 1.48
--- md.texi 2000/11/22 00:06:04
*************** See the next chapter for information on
*** 39,44 ****
--- 39,46 ----
* Insn Attributes:: Specifying the value of attributes for generated insns.
* Conditional Execution::Generating @code{define_insn} patterns for
predication.
+ * Constant Definitions::Defining symbolic constants that can be used in the
+ md file.
@end menu
@node Patterns
*************** generates a new pattern
*** 4690,4692 ****
--- 4692,4741 ----
"(@var{test2}) && (@var{test1})"
"(%3) add %2,%1,%0")
@end smallexample
+
+ @node Constant Definitions
+ @section Constant Definitions
+ @cindex constant definitions
+ @findex define_constants
+
+ Using literal constants inside instruction patterns reduced legibility and
+ can be a maintenance problem.
+
+ To overcome these problems, the @code{define_constants} built-in is provided.
+ It contains a vector of name-value pairs.
+
+ To come back to the a29k load multiple example, instead of
+
+ @smallexample
+ (define_insn ""
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (match_operand:SI 2 "memory_operand" "m"))
+ (use (reg:SI 179))
+ (clobber (reg:SI 179))])]
+ ""
+ "loadm 0,0,%1,%2")
+ @end smallexample
+
+ You could write:
+
+ @smallexample
+ (define_constants [
+ (R_BP 177)
+ (R_FC 178)
+ (R_CR 179)
+ (R_Q 180)
+ ])
+
+ (define_insn ""
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (match_operand:SI 2 "memory_operand" "m"))
+ (use (reg:SI R_CR))
+ (clobber (reg:SI R_CR))])]
+ ""
+ "loadm 0,0,%1,%2")
+ @end smallexample
+
+ The constants that are defined with a define_constant are also output
+ in the insn-codes.h header file as #defines.
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.c,v
retrieving revision 1.83
diff -p -r1.83 rtl.c
*** rtl.c 2000/11/16 15:21:50 1.83
--- rtl.c 2000/11/22 00:06:04
*************** Boston, MA 02111-1307, USA. */
*** 28,33 ****
--- 28,34 ----
#include "ggc.h"
#include "obstack.h"
#include "toplev.h"
+ #include "hashtab.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
*************** const char * const reg_note_name[] =
*** 290,299 ****
--- 291,305 ----
"REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN"
};
+ static htab_t md_constants;
+
static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
static void fatal_expected_char PARAMS ((FILE *, int, int)) ATTRIBUTE_NORETURN;
static void read_name PARAMS ((char *, FILE *));
+ static unsigned def_hash PARAMS ((const void *));
+ static int def_name_eq_p PARAMS ((const void *, const void *));
+ static void read_constants PARAMS ((FILE *infile, char *tmp_char));
/* Allocate an rtx vector of N elements.
*************** read_name (str, infile)
*** 829,834 ****
--- 835,859 ----
read_rtx_lineno++;
*p = 0;
+
+ if (md_constants)
+ {
+ /* Do constant expansion. */
+ struct md_constant *def;
+
+ p = str;
+ do
+ {
+ struct md_constant tmp_def;
+
+ tmp_def.name = p;
+ def = htab_find (md_constants, &tmp_def);
+ if (def)
+ p = def->value;
+ } while (def);
+ if (p != str)
+ strcpy (str, p);
+ }
}
/* Provide a version of a function to read a long long if the system does
*************** atoll(p)
*** 868,873 ****
--- 893,990 ----
}
#endif
+ /* Given a constant definition, return a hash code for its name. */
+ static unsigned
+ def_hash (def)
+ const void *def;
+ {
+ unsigned result, i;
+ const char *string = ((const struct md_constant *)def)->name;
+
+ for (result = i = 0;*string++ != '\0'; i++)
+ result += ((unsigned char) *string << (i % CHAR_BIT));
+ return result;
+ }
+
+ /* Given two constant definitions, return true if they have the same name. */
+ static int
+ def_name_eq_p (def1, def2)
+ const void *def1, *def2;
+ {
+ return ! strcmp (((const struct md_constant *)def1)->name,
+ ((const struct md_constant *)def2)->name);
+ }
+
+ /* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer suitable
+ to read a name or number into. Process a define_constants directive,
+ starting with the optional space after the "define_constants". */
+ static void
+ read_constants (infile, tmp_char)
+ FILE *infile;
+ char *tmp_char;
+ {
+ int c;
+ htab_t defs;
+
+ c = read_skip_spaces (infile);
+ if (c != '[')
+ fatal_expected_char (infile, '[', c);
+ defs = md_constants;
+ if (! defs)
+ defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0);
+ /* Disable constant expansion during definition processing. */
+ md_constants = 0;
+ while ( (c = read_skip_spaces (infile)) != ']')
+ {
+ struct md_constant *def;
+ void **entry_ptr;
+
+ if (c != '(')
+ fatal_expected_char (infile, '(', c);
+ def = xmalloc (sizeof (struct md_constant));
+ def->name = tmp_char;
+ read_name (tmp_char, infile);
+ entry_ptr = htab_find_slot (defs, def, TRUE);
+ if (! *entry_ptr)
+ def->name = xstrdup (tmp_char);
+ c = read_skip_spaces (infile);
+ ungetc (c, infile);
+ read_name (tmp_char, infile);
+ if (! *entry_ptr)
+ {
+ def->value = xstrdup (tmp_char);
+ *entry_ptr = def;
+ }
+ else
+ {
+ def = *entry_ptr;
+ if (strcmp (def->value, tmp_char))
+ fatal_with_file_and_line (infile,
+ "redefinition of %s, was %s, now %s",
+ def->name, def->value, tmp_char);
+ }
+ c = read_skip_spaces (infile);
+ if (c != ')')
+ fatal_expected_char (infile, ')', c);
+ }
+ md_constants = defs;
+ c = read_skip_spaces (infile);
+ if (c != ')')
+ fatal_expected_char (infile, ')', c);
+ }
+
+ /* For every constant definition, call CALLBACK with two arguments:
+ a pointer a pointer to the constant definition and INFO.
+ Stops when CALLBACK returns zero. */
+ void
+ traverse_md_constants (callback, info)
+ htab_trav callback;
+ void *info;
+ {
+ if (md_constants)
+ htab_traverse (md_constants, callback, info);
+ }
+
/* Read an rtx in printed representation from INFILE
and return an actual rtx in core constructed accordingly.
read_rtx is not used in the compiler proper, but rather in
*************** read_rtx (infile)
*** 907,912 ****
--- 1024,1030 ----
initialized = 1;
}
+ again:
c = read_skip_spaces (infile); /* Should be open paren. */
if (c != '(')
fatal_expected_char (infile, '(', c);
*************** read_rtx (infile)
*** 915,920 ****
--- 1033,1043 ----
tmp_code = UNKNOWN;
+ if (! strcmp (tmp_char, "define_constants"))
+ {
+ read_constants (infile, tmp_char);
+ goto again;
+ }
for (i = 0; i < NUM_RTX_CODE; i++)
if (! strcmp (tmp_char, GET_RTX_NAME (i)))
{
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.229
diff -p -r1.229 rtl.h
*** rtl.h 2000/11/14 17:37:18 1.229
--- rtl.h 2000/11/22 00:06:05
*************** extern void init_varasm_once PARAMS ((v
*** 1946,1951 ****
--- 1946,1954 ----
/* In rtl.c */
extern void init_rtl PARAMS ((void));
+ extern void traverse_md_constants PARAMS ((int (*) (void **, void *),
+ void *));
+ struct md_constant { char *name, *value; };
#ifdef BUFSIZ
extern int read_skip_spaces PARAMS ((FILE *));