From 33aceff28557ed32a99c3944a68696a5a36dfa76 Mon Sep 17 00:00:00 2001 From: John Wehle Date: Sat, 22 Dec 2001 17:23:52 +0000 Subject: rtl.h (subreg_lsb): Declare. * rtl.h (subreg_lsb): Declare. * rtlanal.c (subreg_lsb): Implement. From-SVN: r48272 --- gcc/ChangeLog | 5 +++++ gcc/rtl.h | 1 + gcc/rtlanal.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bcc8012..99f7c5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Sat Dec 22 12:20:20 EST 2001 John Wehle (john@feith.com) + + * rtl.h (subreg_lsb): Declare. + * rtlanal.c (subreg_lsb): Implement. + Sat Dec 22 08:59:50 2001 Richard Kenner * predict.c: Reformatting and minor cleanups. diff --git a/gcc/rtl.h b/gcc/rtl.h index ff29333..e4360d6 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -818,6 +818,7 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS]; #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, diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index c2de74b..b6056de 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2881,6 +2881,49 @@ loc_mentioned_in_p (loc, in) 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. -- cgit v1.1