From: Bernd Schmidt Date: Fri, 8 Jul 2011 16:21:58 +0000 (+0000) Subject: defaults.h (REG_WORDS_BIG_ENDIAN): Provide a default. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0a6a1eff605142d06a4d873fb5074cb9b61c77e;p=gcc.git defaults.h (REG_WORDS_BIG_ENDIAN): Provide a default. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0fc7dfd0ef9..60cc66d6f08 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 * fold-const.c (fold_binary_loc): Remove index +p PTR -> PTR +p index diff --git a/gcc/defaults.h b/gcc/defaults.h index 5e84cb8cd78..5f83b1860f0 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -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 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ae90184b4f1..c0648a5657c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 254ddc2c90d..3660d36d7b5 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -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 diff --git a/gcc/reload.c b/gcc/reload.c index 605f23d5962..735fa6edce4 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -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]; diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 76aa79a4b9a..c3cdd31b6d0 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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. */