Commit 0eb61c19 by Doug Evans

expmed.c (store_split_bitfield): Fix handling of bitfields that cross word boundaries...

* expmed.c (store_split_bitfield): Fix handling of bitfields that
 cross word boundaries, can only handle a word at a time.
 (extract_split_bitfield): Likewise.

From-SVN: r5012
parent 3ffeb922
...@@ -678,7 +678,9 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -678,7 +678,9 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
rtx value; rtx value;
int align; int align;
{ {
int unit = align * BITS_PER_UNIT; /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
much at a time. */
int unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
rtx word; rtx word;
int bitsdone = 0; int bitsdone = 0;
...@@ -699,7 +701,11 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -699,7 +701,11 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
offset = (bitpos + bitsdone) / unit; offset = (bitpos + bitsdone) / unit;
thispos = (bitpos + bitsdone) % unit; thispos = (bitpos + bitsdone) % unit;
thissize = unit - offset * BITS_PER_UNIT % unit; /* THISSIZE must not overrun a word boundary. Otherwise,
store_fixed_bit_field will call us again, and we will mutually
recurse forever. */
thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
thissize = MIN (thissize, unit - thispos);
#if BYTES_BIG_ENDIAN #if BYTES_BIG_ENDIAN
/* Fetch successively less significant portions. */ /* Fetch successively less significant portions. */
...@@ -736,7 +742,10 @@ store_split_bit_field (op0, bitsize, bitpos, value, align) ...@@ -736,7 +742,10 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
if (word == 0) if (word == 0)
abort (); abort ();
store_fixed_bit_field (word, offset, thissize, thispos, part, align); /* OFFSET is in UNITs, and UNIT is in bits.
store_fixed_bit_field wants offset in bytes. */
store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT,
thissize, thispos, part, align);
bitsdone += thissize; bitsdone += thissize;
} }
} }
...@@ -1434,7 +1443,9 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ...@@ -1434,7 +1443,9 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
rtx op0; rtx op0;
int bitsize, bitpos, unsignedp, align; int bitsize, bitpos, unsignedp, align;
{ {
int unit = align * BITS_PER_UNIT; /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
much at a time. */
int unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
int bitsdone = 0; int bitsdone = 0;
rtx result; rtx result;
int first = 1; int first = 1;
...@@ -1449,7 +1460,11 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ...@@ -1449,7 +1460,11 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
offset = (bitpos + bitsdone) / unit; offset = (bitpos + bitsdone) / unit;
thispos = (bitpos + bitsdone) % unit; thispos = (bitpos + bitsdone) % unit;
thissize = unit - offset * BITS_PER_UNIT % unit; /* THISSIZE must not overrun a word boundary. Otherwise,
extract_fixed_bit_field will call us again, and we will mutually
recurse forever. */
thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
thissize = MIN (thissize, unit - thispos);
/* If OP0 is a register, then handle OFFSET here. /* If OP0 is a register, then handle OFFSET here.
In the register case, UNIT must be a whole word. */ In the register case, UNIT must be a whole word. */
...@@ -1465,8 +1480,11 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ...@@ -1465,8 +1480,11 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
abort (); abort ();
/* Extract the parts in bit-counting order, /* Extract the parts in bit-counting order,
whose meaning is determined by BYTES_PER_UNIT. */ whose meaning is determined by BYTES_PER_UNIT.
part = extract_fixed_bit_field (word_mode, word, offset, OFFSET is in UNITs, and UNIT is in bits.
extract_fixed_bit_field wants offset in bytes. */
part = extract_fixed_bit_field (word_mode, word,
offset * unit / BITS_PER_UNIT,
thissize, thispos, 0, 1, align); thissize, thispos, 0, 1, align);
bitsdone += thissize; bitsdone += thissize;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment