This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to implement subreg_lsb for VRP
- From: John Wehle <john at feith dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Nov 2001 01:39:04 -0500 (EST)
- Subject: Patch to implement subreg_lsb for VRP
subreg_lsb is a generic support routine used by VRP to determine
the bit offset where a subreg begins (counting from the least
significant bit of the reg). It may be useful elsewhere.
This patch (combined with VRP) passes make bootstrap and make check
on Dec Alpha 4.0f, Solaris 7 SPARC, and Solaris 7 x86.
ChangeLog:
Wed Nov 28 00:43:31 EST 2001 John Wehle (john@feith.com)
* rtl.h (subreg_lsb): Declare.
* rtlanal.c (subreg_lsb): Implement.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/rtl.h.ORIGINAL Wed Nov 14 21:42:17 2001
--- gcc/rtl.h Wed Nov 28 00:37:36 2001
*************** extern const char * const note_insn_name
*** 817,822 ****
--- 817,823 ----
#define SUBREG_BYTE(RTX) XCUINT(RTX, 1, SUBREG)
/* in rtlanal.c */
+ extern unsigned int subreg_lsb PARAMS ((rtx));
extern unsigned int subreg_regno_offset PARAMS ((unsigned int,
enum machine_mode,
unsigned int,
*** gcc/rtlanal.c.ORIGINAL Mon Nov 12 14:19:37 2001
--- gcc/rtlanal.c Wed Nov 28 00:36:32 2001
*************** loc_mentioned_in_p (loc, in)
*** 2734,2739 ****
--- 2734,2782 ----
return 0;
}
+ /* Given a subreg X, return the bit offset where the subreg begins
+ (counting from the least significant bit of the reg). */
+
+ unsigned int
+ subreg_lsb (x)
+ rtx x;
+ {
+ enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
+ enum machine_mode mode = GET_MODE (x);
+ unsigned int bitpos;
+ unsigned int byte;
+ unsigned int word;
+
+ /* A paradoxical subreg begins at bit position 0. */
+ if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (inner_mode))
+ return 0;
+
+ if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
+ /* If the subreg crosses a word boundary ensure that
+ it also begins and ends on a word boundary. */
+ if ((SUBREG_BYTE (x) % UNITS_PER_WORD
+ + GET_MODE_SIZE (mode)) > UNITS_PER_WORD
+ && (SUBREG_BYTE (x) % UNITS_PER_WORD
+ || GET_MODE_SIZE (mode) % UNITS_PER_WORD))
+ abort ();
+
+ if (WORDS_BIG_ENDIAN)
+ word = (GET_MODE_SIZE (inner_mode)
+ - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) / UNITS_PER_WORD;
+ else
+ word = SUBREG_BYTE (x) / UNITS_PER_WORD;
+ bitpos = word * BITS_PER_WORD;
+
+ if (BYTES_BIG_ENDIAN)
+ byte = (GET_MODE_SIZE (inner_mode)
+ - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) % UNITS_PER_WORD;
+ else
+ byte = SUBREG_BYTE (x) % UNITS_PER_WORD;
+ bitpos += byte * BITS_PER_UNIT;
+
+ return bitpos;
+ }
+
/* This function returns the regno offset of a subreg expression.
xregno - A regno of an inner hard subreg_reg (or what will become one).
xmode - The mode of xregno.
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------