* RFA fix conversion of little-byte big-word floats to doublest
@ 2004-12-04 15:27 Richard Earnshaw
2004-12-04 15:47 ` Daniel Jacobowitz
2004-12-04 16:01 ` Richard Earnshaw
0 siblings, 2 replies; 9+ messages in thread
From: Richard Earnshaw @ 2004-12-04 15:27 UTC (permalink / raw)
To: gdb-patches; +Cc: Richard.Earnshaw
[-- Attachment #1: Type: text/plain, Size: 347 bytes --]
This patch fixes a bug in get_field which meant that we incorrectly
converted mixed-endian floats (ARM FPA style) into the internal doublest
format. This short change fixes over 300 testsuite failures in a combined
arm/thumb testsuite run on arm-elf.
* doublest.c (get_field): Correctly extract floatformat_littebyte_bigword
fields.
OK?
[-- Attachment #2: doublest.patch --]
[-- Type: text/x-patch , Size: 859 bytes --]
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.22
diff -p -p -r1.22 doublest.c
*** doublest.c 24 Aug 2004 22:49:27 -0000 1.22
--- doublest.c 4 Dec 2004 14:33:34 -0000
*************** get_field (unsigned char *data, enum flo
*** 94,106 ****
switch (order)
{
case floatformat_little:
++cur_byte;
break;
case floatformat_big:
--cur_byte;
break;
- case floatformat_littlebyte_bigword:
- break;
}
}
if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
--- 94,105 ----
switch (order)
{
case floatformat_little:
+ case floatformat_littlebyte_bigword:
++cur_byte;
break;
case floatformat_big:
--cur_byte;
break;
}
}
if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 15:27 RFA fix conversion of little-byte big-word floats to doublest Richard Earnshaw
@ 2004-12-04 15:47 ` Daniel Jacobowitz
2004-12-04 16:01 ` Richard Earnshaw
1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2004-12-04 15:47 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: gdb-patches
On Sat, Dec 04, 2004 at 02:38:00PM +0000, Richard Earnshaw wrote:
>
> This patch fixes a bug in get_field which meant that we incorrectly
> converted mixed-endian floats (ARM FPA style) into the internal doublest
> format. This short change fixes over 300 testsuite failures in a combined
> arm/thumb testsuite run on arm-elf.
>
> * doublest.c (get_field): Correctly extract floatformat_littebyte_bigword
> fields.
>
> OK?
Could you summarize for me how this is supposed to work? This means
that get_field treats littlebyte_bigword exactly the same as little.
There's another copy of get_field in libiberty (I don't know why there
are two) which treats it exactly the same as big, instead. I don't
know how that works either, but it seems the two ought to agree.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 15:27 RFA fix conversion of little-byte big-word floats to doublest Richard Earnshaw
2004-12-04 15:47 ` Daniel Jacobowitz
@ 2004-12-04 16:01 ` Richard Earnshaw
2004-12-04 16:57 ` Daniel Jacobowitz
` (2 more replies)
1 sibling, 3 replies; 9+ messages in thread
From: Richard Earnshaw @ 2004-12-04 16:01 UTC (permalink / raw)
To: Richard Earnshaw, gdb-patches
On Sat, 04 Dec 2004 10:44:30 EST, Daniel Jacobowitz <drow@false.org>
wrote:
> On Sat, Dec 04, 2004 at 02:38:00PM +0000, Richard Earnshaw wrote:
> >
> > This patch fixes a bug in get_field which meant that we incorrectly
> > converted mixed-endian floats (ARM FPA style) into the internal doublest
> > format. This short change fixes over 300 testsuite failures in a combined
> > arm/thumb testsuite run on arm-elf.
> >
> > * doublest.c (get_field): Correctly extract floatformat_littebyte_bigwo
> rd
> > fields.
> >
> > OK?
>
> Could you summarize for me how this is supposed to work? This means
> that get_field treats littlebyte_bigword exactly the same as little.
> There's another copy of get_field in libiberty (I don't know why there
> are two) which treats it exactly the same as big, instead. I don't
> know how that works either, but it seems the two ought to agree.
The caller has pre-converted the word order into a pure little-endian
format. See convert_format_to_doublest.
Similar tricks are played on the reverse conversion.
R.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 16:01 ` Richard Earnshaw
@ 2004-12-04 16:57 ` Daniel Jacobowitz
2004-12-04 17:23 ` Richard Earnshaw
2004-12-04 17:33 ` Richard Earnshaw
2 siblings, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2004-12-04 16:57 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: gdb-patches
On Sat, Dec 04, 2004 at 03:46:24PM +0000, Richard Earnshaw wrote:
> On Sat, 04 Dec 2004 10:44:30 EST, Daniel Jacobowitz <drow@false.org>
> wrote:
> > On Sat, Dec 04, 2004 at 02:38:00PM +0000, Richard Earnshaw wrote:
> > >
> > > This patch fixes a bug in get_field which meant that we incorrectly
> > > converted mixed-endian floats (ARM FPA style) into the internal doublest
> > > format. This short change fixes over 300 testsuite failures in a combined
> > > arm/thumb testsuite run on arm-elf.
> > >
> > > * doublest.c (get_field): Correctly extract floatformat_littebyte_bigwo
> > rd
> > > fields.
> > >
> > > OK?
> >
> > Could you summarize for me how this is supposed to work? This means
> > that get_field treats littlebyte_bigword exactly the same as little.
> > There's another copy of get_field in libiberty (I don't know why there
> > are two) which treats it exactly the same as big, instead. I don't
> > know how that works either, but it seems the two ought to agree.
>
> The caller has pre-converted the word order into a pure little-endian
> format. See convert_format_to_doublest.
>
> Similar tricks are played on the reverse conversion.
Huh; it looks like the copy in libiberty is just broken for this case.
Is the code which does the swapping correct for the 96-bit format?
It converts ABCD EFGH IJKL to EFGH ABCD IJKL; I would have guessed that
pure little-endian representation would have been IJKL EFGH ABCD.
The swap-back code only swaps the first two words also.
Meanwhile, patch is OK; I'd appreciate it if you could add a comment in
get_field/put_field somewhere explaining what's going on.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 16:01 ` Richard Earnshaw
2004-12-04 16:57 ` Daniel Jacobowitz
@ 2004-12-04 17:23 ` Richard Earnshaw
2004-12-04 17:33 ` Richard Earnshaw
2 siblings, 0 replies; 9+ messages in thread
From: Richard Earnshaw @ 2004-12-04 17:23 UTC (permalink / raw)
To: Richard Earnshaw, gdb-patches
On Sat, 04 Dec 2004 11:00:54 EST, Daniel Jacobowitz <drow@false.org>
wrote:
> On Sat, Dec 04, 2004 at 03:46:24PM +0000, Richard Earnshaw wrote:
> > On Sat, 04 Dec 2004 10:44:30 EST, Daniel Jacobowitz <drow@false.org>
> > wrote:
> > > Could you summarize for me how this is supposed to work? This means
> > > that get_field treats littlebyte_bigword exactly the same as little.
> > > There's another copy of get_field in libiberty (I don't know why there
> > > are two) which treats it exactly the same as big, instead. I don't
> > > know how that works either, but it seems the two ought to agree.
> >
> > The caller has pre-converted the word order into a pure little-endian
> > format. See convert_format_to_doublest.
> >
> > Similar tricks are played on the reverse conversion.
>
> Huh; it looks like the copy in libiberty is just broken for this case.
>
> Is the code which does the swapping correct for the 96-bit format?
> It converts ABCD EFGH IJKL to EFGH ABCD IJKL; I would have guessed that
> pure little-endian representation would have been IJKL EFGH ABCD.
I suspect it's completely broken.
> The swap-back code only swaps the first two words also.
>
It wouldn't surprise me in the least.
> Meanwhile, patch is OK; I'd appreciate it if you could add a comment in
> get_field/put_field somewhere explaining what's going on.
Will do.
R.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 16:01 ` Richard Earnshaw
2004-12-04 16:57 ` Daniel Jacobowitz
2004-12-04 17:23 ` Richard Earnshaw
@ 2004-12-04 17:33 ` Richard Earnshaw
2004-12-04 19:39 ` Daniel Jacobowitz
2004-12-05 1:51 ` Richard Earnshaw
2 siblings, 2 replies; 9+ messages in thread
From: Richard Earnshaw @ 2004-12-04 17:33 UTC (permalink / raw)
To: Richard Earnshaw, gdb-patches
On Sat, 04 Dec 2004 16:56:44 GMT, Richard Earnshaw wrote:
> On Sat, 04 Dec 2004 11:00:54 EST, Daniel Jacobowitz <drow@false.org>
> wrote:
> > On Sat, Dec 04, 2004 at 03:46:24PM +0000, Richard Earnshaw wrote:
> > > On Sat, 04 Dec 2004 10:44:30 EST, Daniel Jacobowitz <drow@false.org>
> > > wrote:
> > > > Could you summarize for me how this is supposed to work? This means
> > > > that get_field treats littlebyte_bigword exactly the same as little.
> > > > There's another copy of get_field in libiberty (I don't know why there
> > > > are two) which treats it exactly the same as big, instead. I don't
> > > > know how that works either, but it seems the two ought to agree.
> > >
> > > The caller has pre-converted the word order into a pure little-endian
> > > format. See convert_format_to_doublest.
> > >
> > > Similar tricks are played on the reverse conversion.
> >
> > Huh; it looks like the copy in libiberty is just broken for this case.
> >
> > Is the code which does the swapping correct for the 96-bit format?
> > It converts ABCD EFGH IJKL to EFGH ABCD IJKL; I would have guessed that
> > pure little-endian representation would have been IJKL EFGH ABCD.
>
> I suspect it's completely broken.
>
> > The swap-back code only swaps the first two words also.
> >
>
> It wouldn't surprise me in the least.
>
> > Meanwhile, patch is OK; I'd appreciate it if you could add a comment in
> > get_field/put_field somewhere explaining what's going on.
>
> Will do.
I've just been thinking.
The current code (for both conversions to and from doublest) tries to work
by normalizing the word order to match the byte order. This clearly makes
things quite difficult when the number of words involved is variable.
I think it would be a more tractable problem to change all this around so
that the byte order is normalized to match the word order. This can be
done by simply repeating a word-normalization step for each word in the
value.
Thoughts?
R.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 17:33 ` Richard Earnshaw
@ 2004-12-04 19:39 ` Daniel Jacobowitz
2004-12-05 1:51 ` Richard Earnshaw
1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2004-12-04 19:39 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: gdb-patches
On Sat, Dec 04, 2004 at 05:25:21PM +0000, Richard Earnshaw wrote:
> I've just been thinking.
>
> The current code (for both conversions to and from doublest) tries to work
> by normalizing the word order to match the byte order. This clearly makes
> things quite difficult when the number of words involved is variable.
>
> I think it would be a more tractable problem to change all this around so
> that the byte order is normalized to match the word order. This can be
> done by simply repeating a word-normalization step for each word in the
> value.
>
> Thoughts?
That sounds good to me - much simpler.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-04 17:33 ` Richard Earnshaw
2004-12-04 19:39 ` Daniel Jacobowitz
@ 2004-12-05 1:51 ` Richard Earnshaw
2004-12-05 15:54 ` Daniel Jacobowitz
1 sibling, 1 reply; 9+ messages in thread
From: Richard Earnshaw @ 2004-12-05 1:51 UTC (permalink / raw)
To: Richard Earnshaw, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1610 bytes --]
On Sat, 04 Dec 2004 12:32:57 EST, Daniel Jacobowitz <drow@false.org>
wrote:
> On Sat, Dec 04, 2004 at 05:25:21PM +0000, Richard Earnshaw wrote:
> > I've just been thinking.
> >
> > The current code (for both conversions to and from doublest) tries to work
> > by normalizing the word order to match the byte order. This clearly makes
> > things quite difficult when the number of words involved is variable.
> >
> > I think it would be a more tractable problem to change all this around so
> > that the byte order is normalized to match the word order. This can be
> > done by simply repeating a word-normalization step for each word in the
> > value.
> >
> > Thoughts?
>
> That sounds good to me - much simpler.
I withdraw my previous patch and substitute this one. This should also
fix handling of mixed endian formats that are larger than 64 bits.
Unlike the previous patch this one also correctly handles NaNs; though it
appears that nothing in the testsuite currently tests this.
* doublest.c (FLOATFORMAT_LARGEST_BYTES): New define.
(get_field, put_field): Assert that the format is one we can handle.
Simplify logic accordingly.
(floatformat_normalize_byteorder): New function.
(convert_floatformat_to_doublest): Use floatformat_normalize_byteorder to
normalize and select modified byte order. Pass modified byte order to
get_field.
(floatformat_is_negative, floatformat_is_nan, floatformat_mantissa):
Likewise.
(convert_doublest_to_floatformat): Select an appropriate intermediate
byte order if necessary. Always convert to the final format before
returning.
OK?
R.
[-- Attachment #2: doublest2.patch --]
[-- Type: text/x-patch , Size: 17940 bytes --]
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.22
diff -p -p -r1.22 doublest.c
*** doublest.c 24 Aug 2004 22:49:27 -0000 1.22
--- doublest.c 4 Dec 2004 23:42:51 -0000
***************
*** 40,45 ****
--- 40,49 ----
a system header, what we do if not, etc. */
#define FLOATFORMAT_CHAR_BIT 8
+ /* The number of bytes that the largest floating-point type that we
+ can convert to doublest will need. */
+ #define FLOATFORMAT_LARGEST_BYTES 16
+
static unsigned long get_field (unsigned char *,
enum floatformat_byteorders,
unsigned int, unsigned int, unsigned int);
*************** get_field (unsigned char *data, enum flo
*** 54,61 ****
unsigned int cur_byte;
int cur_bitshift;
/* Start at the least significant part of the field. */
! if (order == floatformat_little || order == floatformat_littlebyte_bigword)
{
/* We start counting from the other end (i.e, from the high bytes
rather than the low bytes). As such, we need to be concerned
--- 58,68 ----
unsigned int cur_byte;
int cur_bitshift;
+ /* Caller must byte-swap words before calling this routine. */
+ gdb_assert (order == floatformat_little || order == floatformat_big);
+
/* Start at the least significant part of the field. */
! if (order == floatformat_little)
{
/* We start counting from the other end (i.e, from the high bytes
rather than the low bytes). As such, we need to be concerned
*************** get_field (unsigned char *data, enum flo
*** 81,87 ****
else
result = 0;
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
--- 88,94 ----
else
result = 0;
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little)
++cur_byte;
else
--cur_byte;
*************** get_field (unsigned char *data, enum flo
*** 99,106 ****
case floatformat_big:
--cur_byte;
break;
- case floatformat_littlebyte_bigword:
- break;
}
}
if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
--- 106,111 ----
*************** get_field (unsigned char *data, enum flo
*** 109,114 ****
--- 114,153 ----
return result;
}
+ /* Normalize the byte order of FROM into TO. If no normalization is needed
+ then FMT->byteorder is returned and TO is not changed; otherwise the format
+ of the normalized form in TO is returned. */
+ static enum floatformat_byteorders
+ floatformat_normalize_byteorder (const struct floatformat *fmt,
+ const void *from, void *to)
+ {
+ const unsigned char *swapin;
+ unsigned char *swapout;
+ int words;
+
+ if (fmt->byteorder == floatformat_little
+ || fmt->byteorder == floatformat_big)
+ return fmt->byteorder;
+
+ gdb_assert (fmt->byteorder == floatformat_littlebyte_bigword);
+
+ words = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
+ words >>= 2;
+
+ swapout = (unsigned char *)to;
+ swapin = (const unsigned char *)from;
+
+ while (words-- > 0)
+ {
+ *swapout++ = swapin[3];
+ *swapout++ = swapin[2];
+ *swapout++ = swapin[1];
+ *swapout++ = swapin[0];
+ swapin += 4;
+ }
+ return floatformat_big;
+ }
+
/* Convert from FMT to a DOUBLEST.
FROM is the address of the extended float.
Store the DOUBLEST in *TO. */
*************** convert_floatformat_to_doublest (const s
*** 125,175 ****
unsigned int mant_bits, mant_off;
int mant_bits_left;
int special_exponent; /* It's a NaN, denorm or zero */
! /* If the mantissa bits are not contiguous from one end of the
! mantissa to the other, we need to make a private copy of the
! source bytes that is in the right order since the unpacking
! algorithm assumes that the bits are contiguous.
!
! Swap the bytes individually rather than accessing them through
! "long *" since we have no guarantee that they start on a long
! alignment, and also sizeof(long) for the host could be different
! than sizeof(long) for the target. FIXME: Assumes sizeof(long)
! for the target is 4. */
!
! if (fmt->byteorder == floatformat_littlebyte_bigword)
! {
! static unsigned char *newfrom;
! unsigned char *swapin, *swapout;
! int longswaps;
!
! longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
! longswaps >>= 3;
! if (newfrom == NULL)
! {
! newfrom = (unsigned char *) xmalloc (fmt->totalsize);
! }
! swapout = newfrom;
! swapin = ufrom;
! ufrom = newfrom;
! while (longswaps-- > 0)
! {
! /* This is ugly, but efficient */
! *swapout++ = swapin[4];
! *swapout++ = swapin[5];
! *swapout++ = swapin[6];
! *swapout++ = swapin[7];
! *swapout++ = swapin[0];
! *swapout++ = swapin[1];
! *swapout++ = swapin[2];
! *swapout++ = swapin[3];
! swapin += 8;
! }
! }
! exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
! fmt->exp_start, fmt->exp_len);
/* Note that if exponent indicates a NaN, we can't really do anything useful
(not knowing if the host has NaN's, or how to build one). So it will
end up as an infinity or something close; that is OK. */
--- 164,182 ----
unsigned int mant_bits, mant_off;
int mant_bits_left;
int special_exponent; /* It's a NaN, denorm or zero */
+ enum floatformat_byteorders order;
+ unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
+
+ gdb_assert (fmt->totalsize
+ <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
! order = floatformat_normalize_byteorder (fmt, ufrom, newfrom);
! if (order != fmt->byteorder)
! ufrom = newfrom;
! exponent = get_field (ufrom, order, fmt->totalsize, fmt->exp_start,
! fmt->exp_len);
/* Note that if exponent indicates a NaN, we can't really do anything useful
(not knowing if the host has NaN's, or how to build one). So it will
end up as an infinity or something close; that is OK. */
*************** convert_floatformat_to_doublest (const s
*** 207,214 ****
{
mant_bits = min (mant_bits_left, 32);
! mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
! mant_off, mant_bits);
dto += ldexp ((double) mant, exponent - mant_bits);
exponent -= mant_bits;
--- 214,220 ----
{
mant_bits = min (mant_bits_left, 32);
! mant = get_field (ufrom, order, fmt->totalsize, mant_off, mant_bits);
dto += ldexp ((double) mant, exponent - mant_bits);
exponent -= mant_bits;
*************** convert_floatformat_to_doublest (const s
*** 217,223 ****
}
/* Negate it if negative. */
! if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
dto = -dto;
*to = dto;
}
--- 223,229 ----
}
/* Negate it if negative. */
! if (get_field (ufrom, order, fmt->totalsize, fmt->sign_start, 1))
dto = -dto;
*to = dto;
}
*************** put_field (unsigned char *data, enum flo
*** 236,243 ****
unsigned int cur_byte;
int cur_bitshift;
/* Start at the least significant part of the field. */
! if (order == floatformat_little || order == floatformat_littlebyte_bigword)
{
int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
--- 242,252 ----
unsigned int cur_byte;
int cur_bitshift;
+ /* Caller must byte-swap words before calling this routine. */
+ gdb_assert (order == floatformat_little || order == floatformat_big);
+
/* Start at the least significant part of the field. */
! if (order == floatformat_little)
{
int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
*************** put_field (unsigned char *data, enum flo
*** 260,266 ****
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
}
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
--- 269,275 ----
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
}
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little)
++cur_byte;
else
--cur_byte;
*************** put_field (unsigned char *data, enum flo
*** 279,285 ****
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
--- 288,294 ----
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
cur_bitshift += FLOATFORMAT_CHAR_BIT;
! if (order == floatformat_little)
++cur_byte;
else
--cur_byte;
*************** convert_doublest_to_floatformat (CONST s
*** 347,352 ****
--- 356,365 ----
unsigned int mant_bits, mant_off;
int mant_bits_left;
unsigned char *uto = (unsigned char *) to;
+ enum floatformat_byteorders order = fmt->byteorder;
+
+ if (order == floatformat_littlebyte_bigword)
+ order = floatformat_big;
memcpy (&dfrom, from, sizeof (dfrom));
memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1)
*************** convert_doublest_to_floatformat (CONST s
*** 356,385 ****
if (dfrom != dfrom) /* Result is NaN */
{
/* From is NaN */
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
/* Be sure it's not infinity, but NaN value is irrel */
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
32, 1);
! return;
}
/* If negative, set the sign bit. */
if (dfrom < 0)
{
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
dfrom = -dfrom;
}
if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
{
/* Infinity exponent is same as NaN's. */
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
/* Infinity mantissa is all zeroes. */
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
fmt->man_len, 0);
! return;
}
#ifdef HAVE_LONG_DOUBLE
--- 369,398 ----
if (dfrom != dfrom) /* Result is NaN */
{
/* From is NaN */
! put_field (uto, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
/* Be sure it's not infinity, but NaN value is irrel */
! put_field (uto, order, fmt->totalsize, fmt->man_start,
32, 1);
! goto finalize_byteorder;
}
/* If negative, set the sign bit. */
if (dfrom < 0)
{
! put_field (uto, order, fmt->totalsize, fmt->sign_start, 1, 1);
dfrom = -dfrom;
}
if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
{
/* Infinity exponent is same as NaN's. */
! put_field (uto, order, fmt->totalsize, fmt->exp_start,
fmt->exp_len, fmt->exp_nan);
/* Infinity mantissa is all zeroes. */
! put_field (uto, order, fmt->totalsize, fmt->man_start,
fmt->man_len, 0);
! goto finalize_byteorder;
}
#ifdef HAVE_LONG_DOUBLE
*************** convert_doublest_to_floatformat (CONST s
*** 388,394 ****
mant = frexp (dfrom, &exponent);
#endif
! put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
exponent + fmt->exp_bias - 1);
mant_bits_left = fmt->man_len;
--- 401,407 ----
mant = frexp (dfrom, &exponent);
#endif
! put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
exponent + fmt->exp_bias - 1);
mant_bits_left = fmt->man_len;
*************** convert_doublest_to_floatformat (CONST s
*** 429,451 ****
mant_long >>= 32 - mant_bits;
}
! put_field (uto, fmt->byteorder, fmt->totalsize,
mant_off, mant_bits, mant_long);
mant_off += mant_bits;
mant_bits_left -= mant_bits;
}
! if (fmt->byteorder == floatformat_littlebyte_bigword)
{
! int count;
! unsigned char *swaplow = uto;
! unsigned char *swaphigh = uto + 4;
unsigned char tmp;
! for (count = 0; count < 4; count++)
{
! tmp = *swaplow;
! *swaplow++ = *swaphigh;
! *swaphigh++ = tmp;
}
}
}
--- 442,472 ----
mant_long >>= 32 - mant_bits;
}
! put_field (uto, order, fmt->totalsize,
mant_off, mant_bits, mant_long);
mant_off += mant_bits;
mant_bits_left -= mant_bits;
}
!
! finalize_byteorder:
! /* Do we need to byte-swap the words in the result? */
! if (order != fmt->byteorder)
{
! int words;
! unsigned char *curword = uto;
unsigned char tmp;
! words = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
! words >>= 2;
! while (words-- > 0)
{
! tmp = curword[0];
! curword[0] = curword[3];
! curword[3] = tmp;
! tmp = curword[1];
! curword[1] = curword[2];
! curword[2] = tmp;
! curword += 4;
}
}
}
*************** int
*** 457,464 ****
floatformat_is_negative (const struct floatformat *fmt, char *val)
{
unsigned char *uval = (unsigned char *) val;
gdb_assert (fmt != NULL);
! return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1);
}
/* Check if VAL is "not a number" (NaN) for FMT. */
--- 478,496 ----
floatformat_is_negative (const struct floatformat *fmt, char *val)
{
unsigned char *uval = (unsigned char *) val;
+ enum floatformat_byteorders order;
+ unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
+
gdb_assert (fmt != NULL);
! gdb_assert (fmt->totalsize
! <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
!
! order = floatformat_normalize_byteorder (fmt, uval, newfrom);
!
! if (order != fmt->byteorder)
! uval = newfrom;
!
! return get_field (uval, order, fmt->totalsize, fmt->sign_start, 1);
}
/* Check if VAL is "not a number" (NaN) for FMT. */
*************** floatformat_is_nan (const struct floatfo
*** 471,484 ****
unsigned long mant;
unsigned int mant_bits, mant_off;
int mant_bits_left;
!
gdb_assert (fmt != NULL);
if (! fmt->exp_nan)
return 0;
! exponent = get_field (uval, fmt->byteorder, fmt->totalsize,
! fmt->exp_start, fmt->exp_len);
if (exponent != fmt->exp_nan)
return 0;
--- 503,525 ----
unsigned long mant;
unsigned int mant_bits, mant_off;
int mant_bits_left;
! enum floatformat_byteorders order;
! unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
!
gdb_assert (fmt != NULL);
+ gdb_assert (fmt->totalsize
+ <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
+
+ order = floatformat_normalize_byteorder (fmt, uval, newfrom);
+
+ if (order != fmt->byteorder)
+ uval = newfrom;
if (! fmt->exp_nan)
return 0;
! exponent = get_field (uval, order, fmt->totalsize, fmt->exp_start,
! fmt->exp_len);
if (exponent != fmt->exp_nan)
return 0;
*************** floatformat_is_nan (const struct floatfo
*** 490,497 ****
{
mant_bits = min (mant_bits_left, 32);
! mant = get_field (uval, fmt->byteorder, fmt->totalsize,
! mant_off, mant_bits);
/* If there is an explicit integer bit, mask it off. */
if (mant_off == fmt->man_start
--- 531,537 ----
{
mant_bits = min (mant_bits_left, 32);
! mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits);
/* If there is an explicit integer bit, mask it off. */
if (mant_off == fmt->man_start
*************** floatformat_mantissa (const struct float
*** 521,537 ****
int mant_bits_left;
static char res[50];
char buf[9];
/* Make sure we have enough room to store the mantissa. */
- gdb_assert (fmt != NULL);
gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
mant_off = fmt->man_start;
mant_bits_left = fmt->man_len;
mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
! mant = get_field (uval, fmt->byteorder, fmt->totalsize,
! mant_off, mant_bits);
sprintf (res, "%lx", mant);
--- 561,589 ----
int mant_bits_left;
static char res[50];
char buf[9];
+ enum floatformat_byteorders order;
+ unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
+
+ gdb_assert (fmt != NULL);
+ gdb_assert (fmt->totalsize
+ <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
+
+ order = floatformat_normalize_byteorder (fmt, uval, newfrom);
+
+ if (order != fmt->byteorder)
+ uval = newfrom;
+
+ if (! fmt->exp_nan)
+ return 0;
/* Make sure we have enough room to store the mantissa. */
gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
mant_off = fmt->man_start;
mant_bits_left = fmt->man_len;
mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
! mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits);
sprintf (res, "%lx", mant);
*************** floatformat_mantissa (const struct float
*** 540,547 ****
while (mant_bits_left > 0)
{
! mant = get_field (uval, fmt->byteorder, fmt->totalsize,
! mant_off, 32);
sprintf (buf, "%08lx", mant);
strcat (res, buf);
--- 592,598 ----
while (mant_bits_left > 0)
{
! mant = get_field (uval, order, fmt->totalsize, mant_off, 32);
sprintf (buf, "%08lx", mant);
strcat (res, buf);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA fix conversion of little-byte big-word floats to doublest
2004-12-05 1:51 ` Richard Earnshaw
@ 2004-12-05 15:54 ` Daniel Jacobowitz
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2004-12-05 15:54 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: gdb-patches
On Sat, Dec 04, 2004 at 11:58:54PM +0000, Richard Earnshaw wrote:
> On Sat, 04 Dec 2004 12:32:57 EST, Daniel Jacobowitz <drow@false.org>
> wrote:
> > On Sat, Dec 04, 2004 at 05:25:21PM +0000, Richard Earnshaw wrote:
> > > I've just been thinking.
> > >
> > > The current code (for both conversions to and from doublest) tries to work
> > > by normalizing the word order to match the byte order. This clearly makes
> > > things quite difficult when the number of words involved is variable.
> > >
> > > I think it would be a more tractable problem to change all this around so
> > > that the byte order is normalized to match the word order. This can be
> > > done by simply repeating a word-normalization step for each word in the
> > > value.
> > >
> > > Thoughts?
> >
> > That sounds good to me - much simpler.
>
> I withdraw my previous patch and substitute this one. This should also
> fix handling of mixed endian formats that are larger than 64 bits.
>
> Unlike the previous patch this one also correctly handles NaNs; though it
> appears that nothing in the testsuite currently tests this.
Yes, the revised patch is OK. Thanks.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-12-05 1:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-04 15:27 RFA fix conversion of little-byte big-word floats to doublest Richard Earnshaw
2004-12-04 15:47 ` Daniel Jacobowitz
2004-12-04 16:01 ` Richard Earnshaw
2004-12-04 16:57 ` Daniel Jacobowitz
2004-12-04 17:23 ` Richard Earnshaw
2004-12-04 17:33 ` Richard Earnshaw
2004-12-04 19:39 ` Daniel Jacobowitz
2004-12-05 1:51 ` Richard Earnshaw
2004-12-05 15:54 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox