lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Inline assembler fallback for _FPU_SETCW() missing in MINGW librarie


From: ArnoldTheresius
Subject: Re: Inline assembler fallback for _FPU_SETCW() missing in MINGW libraries (issue 577450043 by address@hidden)
Date: Mon, 3 Feb 2020 00:51:21 -0700 (MST)

David Kastrup wrote
> ArnoldTheresius <

> Arnold.Wendl@

> > writes:
> 
> ...
> None of the following GCC options would help?
> ...
>        -ffloat-store
> ...
>        -fexcess-precision=style
> ...
>        -ffast-math
> ...
> -- 
> David Kastrup

Only -ffloat-store did show the desired effect in a C program with typical
situations.
I did not check speed effect.

>float_opts_test-0.exe
Compilation configuration was default.
  as compiled:
    Var - (1.0 / 7.0) = -7.928228386e-018
    Var - OneSeventh() = -7.928228386e-018
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = 6.938893904e-017
      i.e. 0 step(s) of IEEE-double difference
  after X87 config change:
    Var - (1.0 / 7.0) = 0
    Var - OneSeventh() = 0
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = -4.440892099e-015
      i.e. -20 step(s) of IEEE-double difference

>float_opts_test-1.exe
Compilation configuration: -fexcess-precision=fast
  as compiled:
    Var - (1.0 / 7.0) = -7.928228386e-018
    Var - OneSeventh() = -7.928228386e-018
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = 6.938893904e-017
      i.e. 0 step(s) of IEEE-double difference
  after X87 config change:
    ...

>float_opts_test-2.exe
Compilation configuration: -fexcess-precision=standard
  as compiled:
    Var - (1.0 / 7.0) = -7.928228386e-018
    Var - OneSeventh() = 0
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = -4.440892099e-015
      i.e. -20 step(s) of IEEE-double difference
  after X87 config change:
    ...

>float_opts_test-3.exe
Compilation configuration: -ffast-math
  as compiled:
    Var - (1.0 / 7.0) = -7.928228386e-018
    Var - OneSeventh() = -7.928228386e-018
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = 6.938893904e-017
      i.e. 0 step(s) of IEEE-double difference
  after X87 config change:
    ...

>float_opts_test-4.exe
Compilation configuration: -ffloat-store
  as compiled:
    Var - (1.0 / 7.0) = 0
    Var - OneSeventh() = 0
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = -4.440892099e-015
      i.e. -20 step(s) of IEEE-double difference
  after X87 config change:
    ...

>float_opts_test-5.exe
Compilation configuration: -ffloat-store -O3
  as compiled:
    Var - (1.0 / 7.0) = 0
    Var - OneSeventh() = 0
    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;
     X - Y = -4.440892099e-015
      i.e. -20 step(s) of IEEE-double difference
  after X87 config change:
    ...



Source code:

/* FILE: float_opts_test.c
 * compile for windows with several options
 * with MINGW installed in LILYDEV:
 *
 *  #!/bin/sh
 *  CNT=1
 *  CC=i686-w64-mingw32-gcc
 *  echo $CC $opt -ofloat_opts_test-0.exe float_opts_test.c
 *  $CC $opt -ofloat_opts_test-0.exe float_opts_test.c
 *  
 *  for opt in "-fexcess-precision=fast" "-fexcess-precision=standard"
"-ffast-math" \
 *             "-ffloat-store" "-ffloat-store -O3"
 *   do
 *    echo $CC $opt -DCOMPCONFIG='"'"$opt"'"' -ofloat_opts_test-$CNT.exe
float_opts_test.c
 *    $CC $opt -DCOMPCONFIG='"'"$opt"'"' -ofloat_opts_test-$CNT.exe
float_opts_test.c
 *    CNT=`expr $CNT + 1`
 *   done
 *
 */

#include <stdio.h>

void X87mantissa53(void)
{
  asm(
      "     push %ebp"
    "\n     mov  $0x027f, %eax"
    "\n     push %eax"
    "\n     mov  %esp, %ebp"
    "\n     fldcw (%ebp)"
    "\n     pop %eax"
    "\n     pop %ebp"
  );
}

volatile double MyFraction;
volatile double X;

double OneSeventh(void)
{ double One = 1.0;
  double Seven = 7.0;
  return (One / Seven);
}

void TestSuite(void)
{
  union {
    double d;
    long long int i;
  } u1, u2;
  double One = 1.0;
  double Seven = 7.0;

  // first typical situation: compare stored value with recalculated value
  MyFraction = One / Seven;
  printf("    Var - (1.0 / 7.0) = %.10lg\n", MyFraction - (One / Seven));

  // second typical situation: compare stored value with recalculated
function return value
  MyFraction = OneSeventh();
  printf("    Var - OneSeventh() = %.10lg\n", MyFraction - OneSeventh());
 
  { // Don't use loops controlled by inexact floating point increment!
    int cnt;
    register double y; 
    X = ((double) 19999.0) / ((double) 10000.0);
    y = 100.0;
    MyFraction = X / y;
    y = 0.0;
    for (cnt = 0; cnt < 100; cnt++) y += MyFraction;
    MyFraction = y;

    printf("    X = 1.9999; z = X / 100.0; Y = 0.0; 100 times Y += z;\n    
X - Y = %.10lg\n", X - y);
    u1.d = X; u2.d = MyFraction;
    printf("      i.e. %ld step(s) of IEEE-double difference\n", (long)
(u1.i - u2.i));
  }

}

int main(int argc, char *argv[])
{
#ifdef COMPCONFIG
  printf("Compilation configuration: %s\n", COMPCONFIG);
#else
  printf("Compilation configuration was default.\n");
#endif

  printf("  as compiled:\n");
  TestSuite();

  X87mantissa53();

  printf("  after X87 config change:\n");
  TestSuite();

  return 0;
}

ArnoldTheresius



--
Sent from: http://lilypond.1069038.n5.nabble.com/Dev-f88644.html



reply via email to

[Prev in Thread] Current Thread [Next in Thread]