diff options
author | wehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-12-22 17:23:52 +0000 |
---|---|---|
committer | wehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-12-22 17:23:52 +0000 |
commit | ef4e675537f5b1b0d6bf2ced3865308f07cf98a6 (patch) | |
tree | 6bcb256bb7123d660768c9efef33482d5e05d5b3 /gcc/rtlanal.c | |
parent | 64dd4b4355a90bb8d7ff9657df6638830f1942a5 (diff) | |
download | gcc-ef4e675537f5b1b0d6bf2ced3865308f07cf98a6.tar.gz |
* rtl.h (subreg_lsb): Declare.
* rtlanal.c (subreg_lsb): Implement.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48272 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index c2de74b3cc8..b6056de14a1 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. |