Commit 51aae43f by Alan Lawrence Committed by Alan Lawrence

[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
parent 03873eb9
2015-09-08 Alan Lawrence <alan.lawrence@arm.com> 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>, * config/aarch64/aarch64-simd.md (aarch64_simd_vec_unpacks_lo_<mode>,
aarch64_simd_vec_unpacks_hi_<mode>): New insn. aarch64_simd_vec_unpacks_hi_<mode>): New insn.
(vec_unpacks_lo_v4sf, vec_unpacks_hi_v4sf): Delete insn. (vec_unpacks_lo_v4sf, vec_unpacks_hi_v4sf): Delete insn.
......
...@@ -7182,7 +7182,6 @@ native_interpret_real (tree type, const unsigned char *ptr, int len) ...@@ -7182,7 +7182,6 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
{ {
machine_mode mode = TYPE_MODE (type); machine_mode mode = TYPE_MODE (type);
int total_bytes = GET_MODE_SIZE (mode); int total_bytes = GET_MODE_SIZE (mode);
int byte, offset, word, words, bitpos;
unsigned char value; unsigned char value;
/* There are always 32 bits in each long, no matter the size of /* There are always 32 bits in each long, no matter the size of
the hosts long. We handle floating point representations with the hosts long. We handle floating point representations with
...@@ -7193,16 +7192,18 @@ native_interpret_real (tree type, const unsigned char *ptr, int len) ...@@ -7193,16 +7192,18 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
total_bytes = GET_MODE_SIZE (TYPE_MODE (type)); total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
if (total_bytes > len || total_bytes > 24) if (total_bytes > len || total_bytes > 24)
return NULL_TREE; 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)); 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) 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) if (UNITS_PER_WORD < 4)
{ {
word = byte / UNITS_PER_WORD; int word = byte / UNITS_PER_WORD;
if (WORDS_BIG_ENDIAN) if (WORDS_BIG_ENDIAN)
word = (words - 1) - word; word = (words - 1) - word;
offset = word * UNITS_PER_WORD; offset = word * UNITS_PER_WORD;
...@@ -7212,7 +7213,16 @@ native_interpret_real (tree type, const unsigned char *ptr, int len) ...@@ -7212,7 +7213,16 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
offset += byte % UNITS_PER_WORD; offset += byte % UNITS_PER_WORD;
} }
else 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)]; value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];
tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31); tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
......
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