summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-29 18:25:20 +0000
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-29 18:25:20 +0000
commit804e9c9156d0930344e4dea29d7cc7cfa85a2dfd (patch)
tree3090aa165727f2794affe010b3a28910ea6e18e2 /gcc
parent074957f77ad0eb1fcfaba3592d7d50f2c16c294b (diff)
downloadppe42-gcc-804e9c9156d0930344e4dea29d7cc7cfa85a2dfd.tar.gz
ppe42-gcc-804e9c9156d0930344e4dea29d7cc7cfa85a2dfd.zip
* expmed.c (extract_bit_field): Fix bit-field extraction from SUBREGs.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57629 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expmed.c41
2 files changed, 19 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 89f1d7e07fe..2e488edf25a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2002-09-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * expmed.c (extract_bit_field): Fix bit-field extraction from SUBREGs.
+
2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
* builtins.def: Fix comment formatting.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 37622f5ddd0..730c4c1de03 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1031,25 +1031,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (tmode == VOIDmode)
tmode = mode;
+
while (GET_CODE (op0) == SUBREG)
{
- int outer_size = GET_MODE_BITSIZE (GET_MODE (op0));
- int inner_size = GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)));
-
- offset += SUBREG_BYTE (op0) / UNITS_PER_WORD;
-
- inner_size = MIN (inner_size, BITS_PER_WORD);
-
- if (BYTES_BIG_ENDIAN && (outer_size < inner_size))
+ bitpos += SUBREG_BYTE (op0) * BITS_PER_UNIT;
+ if (bitpos > unit)
{
- bitpos += inner_size - outer_size;
- if (bitpos > unit)
- {
- offset += (bitpos / unit);
- bitpos %= unit;
- }
+ offset += (bitpos / unit);
+ bitpos %= unit;
}
-
op0 = SUBREG_REG (op0);
}
@@ -1086,9 +1076,13 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
set_mem_expr (op0, 0);
}
- /* ??? We currently assume TARGET is at least as big as BITSIZE.
- If that's wrong, the solution is to test for it and set TARGET to 0
- if needed. */
+ /* Extraction of a full-word or multi-word value from a structure
+ in a register or aligned memory can be done with just a SUBREG.
+ A subword value in the least significant part of a register
+ can also be extracted with a SUBREG. For this, we need the
+ byte offset of the value in op0. */
+
+ byte_offset = bitpos / BITS_PER_UNIT + offset * UNITS_PER_WORD;
/* If OP0 is a register, BITPOS must count within a word.
But as we have it, it counts within whatever size OP0 now has.
@@ -1098,14 +1092,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
&& unit > GET_MODE_BITSIZE (GET_MODE (op0)))
bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
- /* Extracting a full-word or multi-word value
- from a structure in a register or aligned memory.
- This can be done with just SUBREG.
- So too extracting a subword value in
- the least significant part of the register. */
-
- byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
- + (offset * UNITS_PER_WORD);
+ /* ??? We currently assume TARGET is at least as big as BITSIZE.
+ If that's wrong, the solution is to test for it and set TARGET to 0
+ if needed. */
mode1 = (VECTOR_MODE_P (tmode)
? mode
OpenPOWER on IntegriCloud