===================================================================
@@ -863,11 +863,18 @@ word has the lowest number. This macro
@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
===================================================================
@@ -853,11 +853,18 @@ word has the lowest number. This macro
@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
===================================================================
@@ -882,6 +882,10 @@ see the files COPYING3 and COPYING.RUNTI
#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
===================================================================
@@ -2217,15 +2217,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;
@@ -7305,7 +7305,7 @@ reload_adjust_reg_for_mode (rtx reloadre
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];
===================================================================
@@ -3289,7 +3289,7 @@ subreg_get_info (unsigned int xregno, en
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, en
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. */