[PATCH] standard_80387_constant_p improvements

Roger Sayle roger@www.eyesopen.com
Sat Feb 15 23:56:00 GMT 2003


On Sat, 15 Feb 2003, Richard Henderson wrote:
> On Fri, Feb 14, 2003 at 08:40:43PM -0700, Roger Sayle wrote:
> > +     "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
> > +     "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
> > +     "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
> > +     "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
> > +     "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
>
> You've verified that these produce the exact bit patterns
> generated by the 80387?  Seems to me that it'd be safer
> to use the exact bit patterns generated by the insns and
> then use ieee_extended_intel_96_format.decode to generate
> the real_value.

I wasn't aware I could use ieee_extended_intel_96_format.decode!

Not being an __asm__ expert I came up with the above constants by
bootstraping the above patch.  I initially provided approximate
values, for example, just 3.141 and build gcc with the patch and
then compiled "printf("%40.38Lf\n",3.141L);" on Linux.  The patch
recognizes 3.141, replaces it with "fldpi" and we use glibc to
print out the constant with more precision than is required for
an 80-bit mantissa.  Using these values in the next iteration,
then produced identical results with and without this patch.

To check the correct bit patterns, I also used the following code:

#include <stdio.h>

long double x;

long double lg2() { return 0.3010299956639811952256464283594894482L; }
long double ln2() { return 0.6931471805599453094286904741849753009L; }
long double l2e() { return 1.4426950408889634073876517827983434472L; }
long double l2t() { return 3.3219280948873623478083405569094566090L; }
long double pi()  { return 3.1415926535897932385128089594061862044L; }

void dump(unsigned char *ptr)
{
  int i;

  for (i = 0; i < sizeof(long double); i++)
    printf("%02x ",ptr[i]);
  printf("\n");
}

int main()
{
  x = lg2(); dump((unsigned char*)&x);
  x = ln2(); dump((unsigned char*)&x);
  x = l2e(); dump((unsigned char*)&x);
  x = l2t(); dump((unsigned char*)&x);
  x = pi();  dump((unsigned char*)&x);
  return 0;
}

which once again produces identical output with and without my patch.
I checked with -S that all five functions use the x87 opcodes with,
and an explicit fld without.

For the record, here's the output:

99 f7 cf fb 84 9a 20 9a fd 3f 00 00
ac 79 cf d1 f7 17 72 b1 fe 3f 00 00
bc f0 17 5c 29 3b aa b8 ff 3f 00 00
fe 8a 1b cd 4b 78 9a d4 00 40 00 00
35 c2 68 21 a2 da 0f c9 00 40 00 00


Would you like me to investigate ieee_extended_intel_96_format.decode
as a replacement, or do you think providing explicit decimal constants
as strings better documents whats going on?

Roger
--



More information about the Gcc-patches mailing list