[fold-const.c] Fix bigendian HFmode in native_interpret_real

* fold-const.c (native_interpret_real): Fix HFmode for bigendian where
	UNITS_PER_WORD >= 4.

From-SVN: r227552
This commit is contained in:
Alan Lawrence 2015-09-08 19:27:30 +00:00 committed by Alan Lawrence
parent 03873eb983
commit 51aae43f23
2 changed files with 21 additions and 6 deletions

View File

@ -1,3 +1,8 @@
2015-09-08 Alan Lawrence <alan.lawrence@arm.com>
* fold-const.c (native_interpret_real): Fix HFmode for bigendian where
UNITS_PER_WORD >= 4.
2015-09-08 Alan Lawrence <alan.lawrence@arm.com>
* config/aarch64/aarch64-simd.md (aarch64_simd_vec_unpacks_lo_<mode>,

View File

@ -7182,7 +7182,6 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
{
machine_mode mode = TYPE_MODE (type);
int total_bytes = GET_MODE_SIZE (mode);
int byte, offset, word, words, bitpos;
unsigned char value;
/* There are always 32 bits in each long, no matter the size of
the hosts long. We handle floating point representations with
@ -7193,16 +7192,18 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
if (total_bytes > len || total_bytes > 24)
return NULL_TREE;
words = (32 / BITS_PER_UNIT) / UNITS_PER_WORD;
int words = (32 / BITS_PER_UNIT) / UNITS_PER_WORD;
memset (tmp, 0, sizeof (tmp));
for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
for (int bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
bitpos += BITS_PER_UNIT)
{
byte = (bitpos / BITS_PER_UNIT) & 3;
/* Both OFFSET and BYTE index within a long;
bitpos indexes the whole float. */
int offset, byte = (bitpos / BITS_PER_UNIT) & 3;
if (UNITS_PER_WORD < 4)
{
word = byte / UNITS_PER_WORD;
int word = byte / UNITS_PER_WORD;
if (WORDS_BIG_ENDIAN)
word = (words - 1) - word;
offset = word * UNITS_PER_WORD;
@ -7212,7 +7213,16 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
offset += byte % UNITS_PER_WORD;
}
else
offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
{
offset = byte;
if (BYTES_BIG_ENDIAN)
{
/* Reverse bytes within each long, or within the entire float
if it's smaller than a long (for HFmode). */
offset = MIN (3, total_bytes - 1) - offset;
gcc_assert (offset >= 0);
}
}
value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];
tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);