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]
Other format: [Raw text]

RFA: Fix PR middle-end/29847


Both to avoid problems with existing code relying on the current behaviour, and
to accomodate cases where endianness varies between register classes (and/or
is neither big nor little endian), I have introduced a new target hook
TARGET_MATCH_ADJUST, which defaults to the current behaviour.


I've regression tested the code patches on i686-pc-linux-gnu with a native bootstrap,
and also as part of the patches for PR29845 on i686-pc-linux-gnu X sh-elf.
I've tested the tm.texi patch with 'make info' and inspecting gccint.info with
vi and info.


:ADDPATCH middle-end:

2006-11-15  J"orn Rennecke  <joern.rennecke@st.com>

	PR middle-end/29847
	* targhooks.c (regs.h): Include.
	(default_match_adjust): New function, broken out of
	reload.c:operands_match_p.
	* targhooks.h (default_match_adjust): Declare.
	* reload.c (operands_match_p): Use targetm.match_adjust.
	* target.h (struct gcc_target): New member match_adjust.
	* target-def.h (TARGET_MATCH_ADJUST): Define.
	(TARGET_INITIALIZER): Add TARGET_MATCH_ADJUST.
	* Makefile.in (targhooks.o): Depend on $(REGS_H).
	* doc/tm.texi (TARGET_MATCH_ADJUST): Document.

Index: targhooks.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L targhooks.c	(revision 118652) -L targhooks.c	(working copy) .svn/text-base/targhooks.c.svn-base targhooks.c
--- targhooks.c	(revision 118652)
+++ targhooks.c	(working copy)
@@ -66,6 +66,7 @@ Software Foundation, 51 Franklin Street,
 #include "reload.h"
 #include "optabs.h"
 #include "recog.h"
+#include "regs.h"
 
 
 void
@@ -581,6 +582,27 @@ default_secondary_reload (bool in_p ATTR
   return class;
 }
 
+/*  Given an rtx and its regno, return a regno value that shall be used for
+    purposes of comparison in operands_match_p.
+    Generally, we say that integer registers are subject to big-endian
+    adjustment.  This default target hook should generally work if the mode
+    of a register is a sufficient indication if this adjustment is to take
+    place; this will not work when software floating point is done in integer
+    registers.  */
+int
+default_match_adjust (rtx x, int regno)
+{
+  /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
+     multiple hard register group of scalar integer registers, so that
+     for example (reg:DI 0) and (reg:SI 1) will be considered the same
+     register.  */
+  if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+      && SCALAR_INT_MODE_P (GET_MODE (x))
+      && regno < FIRST_PSEUDO_REGISTER)
+    regno += hard_regno_nregs[regno][GET_MODE (x)] - 1;
+  return regno;
+}
+
 
 /* If STRICT_ALIGNMENT is true we use the container type for accessing
    volatile bitfields.  This is generally the preferred behavior for memory
Index: targhooks.h
===================================================================
/usr/bin/diff -p -d -F^( -u -L targhooks.h	(revision 118652) -L targhooks.h	(working copy) .svn/text-base/targhooks.h.svn-base targhooks.h
--- targhooks.h	(revision 118652)
+++ targhooks.h	(working copy)
@@ -77,4 +77,5 @@ extern rtx default_internal_arg_pointer 
 extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
 						enum machine_mode,
 						secondary_reload_info *);
+extern int default_match_adjust (rtx, int);
 extern void hook_void_bitmap (bitmap);
Index: reload.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L reload.c	(revision 118652) -L reload.c	(working copy) .svn/text-base/reload.c.svn-base reload.c
--- reload.c	(revision 118652)
+++ reload.c	(working copy)
@@ -2172,14 +2172,8 @@ operands_match_p (rtx x, rtx y)
 	 multiple hard register group of scalar integer registers, so that
 	 for example (reg:DI 0) and (reg:SI 1) will be considered the same
 	 register.  */
-      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
-	  && SCALAR_INT_MODE_P (GET_MODE (x))
-	  && i < FIRST_PSEUDO_REGISTER)
-	i += hard_regno_nregs[i][GET_MODE (x)] - 1;
-      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
-	  && SCALAR_INT_MODE_P (GET_MODE (y))
-	  && j < FIRST_PSEUDO_REGISTER)
-	j += hard_regno_nregs[j][GET_MODE (y)] - 1;
+      i = targetm.match_adjust (x, i);
+      j = targetm.match_adjust (y, j);
 
       return i == j;
     }
Index: target.h
===================================================================
/usr/bin/diff -p -d -F^( -u -L target.h	(revision 118652) -L target.h	(working copy) .svn/text-base/target.h.svn-base target.h
--- target.h	(revision 118652)
+++ target.h	(working copy)
@@ -744,6 +744,9 @@ struct gcc_target
   enum reg_class (*secondary_reload) (bool, rtx, enum reg_class,
 				      enum machine_mode,
 				      struct secondary_reload_info *);
+  /* Take an rtx and its regno, and return the regno for purposes of
+     checking a matching constraint.  */
+  int (*match_adjust) (rtx, int);
 
   /* Functions specific to the C++ frontend.  */
   struct cxx {
Index: target-def.h
===================================================================
/usr/bin/diff -p -d -F^( -u -L target-def.h	(revision 118652) -L target-def.h	(working copy) .svn/text-base/target-def.h.svn-base target-def.h
--- target-def.h	(revision 118652)
+++ target-def.h	(working copy)
@@ -545,6 +545,10 @@ Foundation, 51 Franklin Street, Fifth Fl
 #define TARGET_SECONDARY_RELOAD default_secondary_reload
 #endif
 
+#ifndef TARGET_MATCH_ADJUST
+#define TARGET_MATCH_ADJUST default_match_adjust
+#endif
+
 
 /* C++ specific.  */
 #ifndef TARGET_CXX_GUARD_TYPE
@@ -688,8 +692,9 @@ Foundation, 51 Franklin Street, Fifth Fl
   TARGET_INVALID_UNARY_OP,			\
   TARGET_INVALID_BINARY_OP,			\
   TARGET_SECONDARY_RELOAD,			\
+  TARGET_MATCH_ADJUST,				\
   TARGET_CXX,					\
-  TARGET_EXTRA_LIVE_ON_ENTRY,                    \
+  TARGET_EXTRA_LIVE_ON_ENTRY,			\
   TARGET_UNWIND_TABLES_DEFAULT,			\
   TARGET_HAVE_NAMED_SECTIONS,			\
   TARGET_HAVE_SWITCHABLE_BSS_SECTIONS,		\
Index: Makefile.in
===================================================================
/usr/bin/diff -p -d -F^( -u -L Makefile.in	(revision 118652) -L Makefile.in	(working copy) .svn/text-base/Makefile.in.svn-base Makefile.in
--- Makefile.in	(revision 118652)
+++ Makefile.in	(working copy)
@@ -2140,7 +2140,7 @@ opts-common.o : opts-common.c opts.h $(C
    coretypes.h intl.h
 targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
    $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h toplev.h \
-   $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h
+   $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) $(REGS_H) gt-targhooks.h
 
 toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h input.h \
Index: doc/tm.texi
===================================================================
/usr/bin/diff -p -d -F^( -u -L doc/tm.texi	(revision 118652) -L doc/tm.texi	(working copy) doc/.svn/text-base/tm.texi.svn-base doc/tm.texi
--- doc/tm.texi	(revision 118652)
+++ doc/tm.texi	(working copy)
@@ -2075,6 +2075,16 @@ registers.  You should only define this 
 @code{CCmode} is incomplete.
 @end defmac
 
+@deftypefn {Target Hook} int TARGET_MATCH_ADJUST (rtx @var{x}, int @var{regno})
+@var{regno} contains the register number of the first hard register in @var{x}.
+Return a register number suitable to test if two registers are considered
+matching for the purposes of a matching constraint.
+This is neeed to get useful results when matching registers of different
+sizes for big endian targets.
+The default is to point to the least significant hard register for
+scalar integer modes, but to the first register for any other mode.
+@end deftypefn
+
 @node Leaf Functions
 @subsection Handling Leaf Functions
 

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