re PR middle-end/30704 (Incorrect constant generation for long long)
PR middle-end/30704 * fold-const.c (native_encode_real): Encode real.c provided longs as a series of 32-bit native integers. (native_interpret_real): Interpret buffer as a series of 32-bit native integers. * gcc.c-torture/execute/ieee/pr30704.c: New test. From-SVN: r123455
This commit is contained in:
parent
eb9af792f2
commit
0a9430a831
|
@ -1,3 +1,11 @@
|
|||
2007-04-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/30704
|
||||
* fold-const.c (native_encode_real): Encode real.c provided longs
|
||||
as a series of 32-bit native integers.
|
||||
(native_interpret_real): Interpret buffer as a series of 32-bit
|
||||
native integers.
|
||||
|
||||
2007-04-03 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* genpreds.c (write_insn_constraint_len): Write function
|
||||
|
|
|
@ -7162,7 +7162,7 @@ native_encode_real (tree expr, unsigned char *ptr, int len)
|
|||
{
|
||||
tree type = TREE_TYPE (expr);
|
||||
int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
|
||||
int byte, offset, word, words;
|
||||
int byte, offset, word, words, bitpos;
|
||||
unsigned char value;
|
||||
|
||||
/* There are always 32 bits in each long, no matter the size of
|
||||
|
@ -7172,19 +7172,20 @@ native_encode_real (tree expr, unsigned char *ptr, int len)
|
|||
|
||||
if (total_bytes > len)
|
||||
return 0;
|
||||
words = total_bytes / UNITS_PER_WORD;
|
||||
words = 32 / UNITS_PER_WORD;
|
||||
|
||||
real_to_target (tmp, TREE_REAL_CST_PTR (expr), TYPE_MODE (type));
|
||||
|
||||
for (byte = 0; byte < total_bytes; byte++)
|
||||
for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
|
||||
bitpos += BITS_PER_UNIT)
|
||||
{
|
||||
int bitpos = byte * BITS_PER_UNIT;
|
||||
byte = (bitpos / BITS_PER_UNIT) & 3;
|
||||
value = (unsigned char) (tmp[bitpos / 32] >> (bitpos & 31));
|
||||
|
||||
if (total_bytes > UNITS_PER_WORD)
|
||||
if (UNITS_PER_WORD < 4)
|
||||
{
|
||||
word = byte / UNITS_PER_WORD;
|
||||
if (FLOAT_WORDS_BIG_ENDIAN)
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
word = (words - 1) - word;
|
||||
offset = word * UNITS_PER_WORD;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
|
@ -7193,8 +7194,8 @@ native_encode_real (tree expr, unsigned char *ptr, int len)
|
|||
offset += byte % UNITS_PER_WORD;
|
||||
}
|
||||
else
|
||||
offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
|
||||
ptr[offset] = value;
|
||||
offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
|
||||
ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)] = value;
|
||||
}
|
||||
return total_bytes;
|
||||
}
|
||||
|
@ -7350,7 +7351,7 @@ native_interpret_real (tree type, unsigned char *ptr, int len)
|
|||
{
|
||||
enum machine_mode mode = TYPE_MODE (type);
|
||||
int total_bytes = GET_MODE_SIZE (mode);
|
||||
int byte, offset, word, words;
|
||||
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
|
||||
|
@ -7361,16 +7362,17 @@ native_interpret_real (tree type, unsigned char *ptr, int len)
|
|||
total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
|
||||
if (total_bytes > len || total_bytes > 24)
|
||||
return NULL_TREE;
|
||||
words = total_bytes / UNITS_PER_WORD;
|
||||
words = 32 / UNITS_PER_WORD;
|
||||
|
||||
memset (tmp, 0, sizeof (tmp));
|
||||
for (byte = 0; byte < total_bytes; byte++)
|
||||
for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
|
||||
bitpos += BITS_PER_UNIT)
|
||||
{
|
||||
int bitpos = byte * BITS_PER_UNIT;
|
||||
if (total_bytes > UNITS_PER_WORD)
|
||||
byte = (bitpos / BITS_PER_UNIT) & 3;
|
||||
if (UNITS_PER_WORD < 4)
|
||||
{
|
||||
word = byte / UNITS_PER_WORD;
|
||||
if (FLOAT_WORDS_BIG_ENDIAN)
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
word = (words - 1) - word;
|
||||
offset = word * UNITS_PER_WORD;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
|
@ -7379,8 +7381,8 @@ native_interpret_real (tree type, unsigned char *ptr, int len)
|
|||
offset += byte % UNITS_PER_WORD;
|
||||
}
|
||||
else
|
||||
offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
|
||||
value = ptr[offset];
|
||||
offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
|
||||
value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];
|
||||
|
||||
tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2007-04-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/30704
|
||||
* gcc.c-torture/execute/ieee/pr30704.c: New test.
|
||||
|
||||
2007-04-02 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/31187
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* PR middle-end/30704 */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
extern void abort (void);
|
||||
extern int memcmp (const void *, const void *, size_t);
|
||||
extern void *memcpy (void *, const void *, size_t);
|
||||
|
||||
long long
|
||||
__attribute__((noinline))
|
||||
f1 (void)
|
||||
{
|
||||
long long t;
|
||||
double d = 0x0.fffffffffffff000p-1022;
|
||||
memcpy (&t, &d, sizeof (long long));
|
||||
return t;
|
||||
}
|
||||
|
||||
double
|
||||
__attribute__((noinline))
|
||||
f2 (void)
|
||||
{
|
||||
long long t = 0x000fedcba9876543LL;
|
||||
double d;
|
||||
memcpy (&d, &t, sizeof (long long));
|
||||
return d;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
union
|
||||
{
|
||||
long long ll;
|
||||
double d;
|
||||
} u;
|
||||
|
||||
if (sizeof (long long) != sizeof (double) || __DBL_MIN_EXP__ != -1021)
|
||||
return 0;
|
||||
|
||||
u.ll = f1 ();
|
||||
if (u.d != 0x0.fffffffffffff000p-1022)
|
||||
abort ();
|
||||
|
||||
u.d = f2 ();
|
||||
if (u.ll != 0x000fedcba9876543LL)
|
||||
abort ();
|
||||
|
||||
double b = 234.0;
|
||||
long long c;
|
||||
double d = b;
|
||||
memcpy (&c, &b, sizeof (double));
|
||||
long long e = c;
|
||||
if (memcmp (&e, &d, sizeof (double)) != 0)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue