This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: SH: use register names instead of numbers


> 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 *));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]