From 3ea4b099db3dc24efdb57f615a36dba4e11f92d7 Mon Sep 17 00:00:00 2001 From: alalaw01 Date: Tue, 8 Sep 2015 19:27:30 +0000 Subject: [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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227552 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fold-const.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'gcc/fold-const.c') diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a79bfa7b060..e9366e2de6e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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); -- cgit v1.2.1