summaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorwehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-22 17:23:52 +0000
committerwehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-22 17:23:52 +0000
commitef4e675537f5b1b0d6bf2ced3865308f07cf98a6 (patch)
tree6bcb256bb7123d660768c9efef33482d5e05d5b3 /gcc/rtlanal.c
parent64dd4b4355a90bb8d7ff9657df6638830f1942a5 (diff)
downloadgcc-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.c43
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.