defaults.h (REG_WORDS_BIG_ENDIAN): Provide a default.
authorBernd Schmidt <bernds@codesourcery.com>
Fri, 8 Jul 2011 16:21:58 +0000 (16:21 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 8 Jul 2011 16:21:58 +0000 (16:21 +0000)
* defaults.h (REG_WORDS_BIG_ENDIAN): Provide a default.
* doc/tm.texi.in (WORDS_BIG_ENDIAN): Mention REG_WORDS_BIG_ENDIAN.
(REG_WORDS_BIG_ENDIAN): Document.
* doc/tm.texi: Regenerate.
* reload.c (operands_match_p): Take it into account.
(reload_adjust_reg_for_mode): Likewise.
* rtlanal.c (subreg_get_info): Likewise.

From-SVN: r176048

gcc/ChangeLog
gcc/defaults.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/reload.c
gcc/rtlanal.c

index 0fc7dfd0ef9fb082210aff7db12ae8de8ef2490c..60cc66d6f08b2aa0f3bf07d47f011e9e947ad227 100644 (file)
@@ -4,6 +4,14 @@
        in terms of another.
        (write_attr_value): Write a cast if necessary.
 
+       * defaults.h (REG_WORDS_BIG_ENDIAN): Provide a default.
+       * doc/tm.texi.in (WORDS_BIG_ENDIAN): Mention REG_WORDS_BIG_ENDIAN.
+       (REG_WORDS_BIG_ENDIAN): Document.
+       * doc/tm.texi: Regenerate.
+       * reload.c (operands_match_p): Take it into account.
+       (reload_adjust_reg_for_mode): Likewise.
+       * rtlanal.c (subreg_get_info): Likewise.
+
 2011-07-08  Richard Guenther  <rguenther@suse.de>
 
        * fold-const.c (fold_binary_loc): Remove index +p PTR -> PTR +p index
index 5e84cb8cd78fd02649ae7155ef1d2533835b0e84..5f83b1860f0ab3fcbf7868190952689caaedad19 100644 (file)
@@ -882,6 +882,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
 #endif
 
+#ifndef REG_WORDS_BIG_ENDIAN
+#define REG_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
+#endif
+
 #ifdef TARGET_FLT_EVAL_METHOD
 #define TARGET_FLT_EVAL_METHOD_NON_DEFAULT 1
 #else
index ae90184b4f17de5b48aef28a78004ac18125eb53..c0648a5657cc2cae6701c7ddf30688f6ca209895 100644 (file)
@@ -870,11 +870,18 @@ word has the lowest number.  This macro need not be a constant.
 @defmac WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if, in a multiword object, the
 most significant word has the lowest number.  This applies to both
-memory locations and registers; GCC fundamentally assumes that the
-order of words in memory is the same as the order in registers.  This
+memory locations and registers; see @code{REG_WORDS_BIG_ENDIAN} if the
+order of words in memory is not the same as the order in registers.  This
 macro need not be a constant.
 @end defmac
 
+@defmac REG_WORDS_BIG_ENDIAN
+On some machines, the order of words in a multiword object differs between
+registers in memory.  In such a situation, define this macro to describe
+the order of words in a register.  The macro @code{WORDS_BIG_ENDIAN} controls
+the order of words in memory.
+@end defmac
+
 @defmac FLOAT_WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if @code{DFmode}, @code{XFmode} or
 @code{TFmode} floating point numbers are stored in memory with the word
index 254ddc2c90dfe50847b9571707dace8c19a19504..3660d36d7b56de9fb18176e312654bfdd6a73720 100644 (file)
@@ -858,11 +858,18 @@ word has the lowest number.  This macro need not be a constant.
 @defmac WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if, in a multiword object, the
 most significant word has the lowest number.  This applies to both
-memory locations and registers; GCC fundamentally assumes that the
-order of words in memory is the same as the order in registers.  This
+memory locations and registers; see @code{REG_WORDS_BIG_ENDIAN} if the
+order of words in memory is not the same as the order in registers.  This
 macro need not be a constant.
 @end defmac
 
+@defmac REG_WORDS_BIG_ENDIAN
+On some machines, the order of words in a multiword object differs between
+registers in memory.  In such a situation, define this macro to describe
+the order of words in a register.  The macro @code{WORDS_BIG_ENDIAN} controls
+the order of words in memory.
+@end defmac
+
 @defmac FLOAT_WORDS_BIG_ENDIAN
 Define this macro to have the value 1 if @code{DFmode}, @code{XFmode} or
 @code{TFmode} floating point numbers are stored in memory with the word
index 605f23d596269ac2bc91f3e7489a1fb42c2a90f3..735fa6edce4bd7784e3667c9acaac67c25c85c60 100644 (file)
@@ -2218,15 +2218,15 @@ operands_match_p (rtx x, rtx y)
       else
        j = REGNO (y);
 
-      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
+      /* On a REG_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
+      if (REG_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
+      if (REG_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;
@@ -7251,7 +7251,7 @@ reload_adjust_reg_for_mode (rtx reloadreg, enum machine_mode mode)
 
   regno = REGNO (reloadreg);
 
-  if (WORDS_BIG_ENDIAN)
+  if (REG_WORDS_BIG_ENDIAN)
     regno += (int) hard_regno_nregs[regno][GET_MODE (reloadreg)]
       - (int) hard_regno_nregs[regno][mode];
 
index 76aa79a4b9a865aee5089360caad6f5778c70906..c3cdd31b6d035076115a503bff158f637f52a607 100644 (file)
@@ -3289,7 +3289,7 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
         return a negative offset so that we find the proper highpart
         of the register.  */
       if (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
-         ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)
+         ? REG_WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)
        info->offset = nregs_xmode - nregs_ymode;
       else
        info->offset = 0;
@@ -3344,6 +3344,15 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
   gcc_assert ((GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)) == 0);
   gcc_assert ((nregs_xmode % nregs_ymode) == 0);
 
+  if (WORDS_BIG_ENDIAN != REG_WORDS_BIG_ENDIAN
+      && GET_MODE_SIZE (xmode) > UNITS_PER_WORD)
+    {
+      HOST_WIDE_INT xsize = GET_MODE_SIZE (xmode);
+      HOST_WIDE_INT ysize = GET_MODE_SIZE (ymode);
+      HOST_WIDE_INT off_low = offset & (ysize - 1);
+      HOST_WIDE_INT off_high = offset & ~(ysize - 1);
+      offset = (xsize - ysize - off_high) | off_low;
+    }
   /* The XMODE value can be seen as a vector of NREGS_XMODE
      values.  The subreg must represent a lowpart of given field.
      Compute what field it is.  */