diff options
author | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-29 18:25:20 +0000 |
---|---|---|
committer | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-29 18:25:20 +0000 |
commit | 804e9c9156d0930344e4dea29d7cc7cfa85a2dfd (patch) | |
tree | 3090aa165727f2794affe010b3a28910ea6e18e2 /gcc | |
parent | 074957f77ad0eb1fcfaba3592d7d50f2c16c294b (diff) | |
download | ppe42-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/expmed.c | 41 |
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 |