aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wehle <john@feith.com>2001-12-22 17:23:52 +0000
committerJohn Wehle <wehle@gcc.gnu.org>2001-12-22 17:23:52 +0000
commit33aceff28557ed32a99c3944a68696a5a36dfa76 (patch)
tree6bcb256bb7123d660768c9efef33482d5e05d5b3
parentd599b3fc8a66a32a79a91359985b295f81e62a4d (diff)
downloadgcc-33aceff28557ed32a99c3944a68696a5a36dfa76.zip
gcc-33aceff28557ed32a99c3944a68696a5a36dfa76.tar.gz
gcc-33aceff28557ed32a99c3944a68696a5a36dfa76.tar.bz2
rtl.h (subreg_lsb): Declare.
* rtl.h (subreg_lsb): Declare. * rtlanal.c (subreg_lsb): Implement. From-SVN: r48272
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c43
3 files changed, 49 insertions, 0 deletions
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 <kenner@vlsi1.ultra.nyu.edu>
* 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.