From patchwork Tue May 10 15:39:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 95004 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id AB5EAB6EF2 for ; Wed, 11 May 2011 02:08:46 +1000 (EST) Received: (qmail 28531 invoked by alias); 10 May 2011 15:40:41 -0000 Received: (qmail 28345 invoked by uid 22791); 10 May 2011 15:40:38 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 10 May 2011 15:40:24 +0000 Received: (qmail 846 invoked from network); 10 May 2011 15:40:23 -0000 Received: from unknown (HELO ?84.152.158.68?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 10 May 2011 15:40:23 -0000 Message-ID: <4DC95C46.4040809@codesourcery.com> Date: Tue, 10 May 2011 17:39:50 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110505 Lightning/1.0b3pre Thunderbird/3.1.10 MIME-Version: 1.0 To: GCC Patches Subject: C6X port 6/11: REG_WORDS_BIG_ENDIAN References: <4DC956D0.3040306@codesourcery.com> In-Reply-To: <4DC956D0.3040306@codesourcery.com> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org C6X has little- and big-endian modes, but in both modes, registers are in little-endian order. This patch adds code to support this model in gcc. Bernd * reload.c (operands_match_p): Take it into account. (reload_adjust_reg_for_mode): Likewise. * rtlanal.c (subreg_get_info): Likewise. * 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. Index: doc/tm.texi =================================================================== --- doc/tm.texi.orig +++ doc/tm.texi @@ -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 Index: doc/tm.texi.in =================================================================== --- doc/tm.texi.in.orig +++ doc/tm.texi.in @@ -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 Index: defaults.h =================================================================== --- defaults.h.orig +++ defaults.h @@ -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 Index: reload.c =================================================================== --- reload.c.orig +++ reload.c @@ -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]; Index: rtlanal.c =================================================================== --- rtlanal.c.orig +++ rtlanal.c @@ -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. */