[Mingw-w64-public] Wrong output from %La specifier in printf()?

2016-09-08 Thread lhmouse
When the `%La` specifier is used in `printf()` to format
the C99 hexdecimal floating point value `0x5p-80l`,
a wrong result is generated, as shown in this example:

E:\Desktop>cat test.c
extern int __mingw_printf(const char *, ...);
int main(){
__mingw_printf("%La\n", 0x5p-80l);
}

E:\Desktop>gcc test.c -std=c99

E:\Desktop>a.exe
0x0p-141

Removing the `__mingw_` prefix and testing the same program
on Linux gives the correct result:

lh_mouse@lhmouse-dev:~$ uname -a
Linux lhmouse-dev 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 
(2016-07-02) x86_64 GNU/Linux
lh_mouse@lhmouse-dev:~$ gcc test.c -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out 
0xap-81

Is this a bug in `printf()`?

--
Best regards,
lh_mouse
2016-09-09


--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] winstorecompat: Add a GetStartupInfo stub

2016-09-08 Thread David Wohlferd
On 9/8/2016 10:36 AM, Hugo Beauzée-Luyssen wrote:
> This only happens when building with -lwindowsapp (see another patch of
> mine). When building with the default -lkernel32, all is good, since
> kernel32.lib contains GetStartupInfo.
> windowsapp.lib, on the other hand, doesn't; which makes sense since the
> symbol is forbidden.
> Since the issue only happens when building test program within
> configure, it seemed ok to add a stub for it.

I'm not opposed to the idea of a stub for GetStartupInfo.  I assume your 
plan is to add it to libwindowsapp.a?  I'm guessing the idea is we want 
to avoid having to customize the startup code and that sounds like a 
good idea.

I'm also thinking some comments to explain what is going on for future 
maintainers might be a good idea.  Cuz this is gonna look a bit odd (ie 
why are we calling a function that doesn't do anything?).

If the expectation is that the code never gets called, it may even make 
sense to have the stub call abort() (or its winstore-appropriate 
equivalent) instead of the memset.  Configure doesn't actually run any 
of the programs it builds, does it?

dw

--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] winstorecompat: Add a GetStartupInfo stub

2016-09-08 Thread Hugo Beauzée-Luyssen
On 09/08/2016 07:21 PM, David Wohlferd wrote:
> On 9/7/2016 2:19 PM, Hugo Beauzée-Luyssen wrote:
>>> Is this to deal with the fact that __tmainCRTStartup uses it?
>> Exactly. In the end, the function won't be used since __tmainCRTStartup
>> won't be used for a windows store app, but we still need the configure
>> scripts to be able to compile executables.
>
> I haven't experimented with winstore.  What configure parameters are you
> using?
>
> dw
>
> --
> ___
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>
This only happens when building with -lwindowsapp (see another patch of 
mine). When building with the default -lkernel32, all is good, since 
kernel32.lib contains GetStartupInfo.
windowsapp.lib, on the other hand, doesn't; which makes sense since the 
symbol is forbidden.
Since the issue only happens when building test program within 
configure, it seemed ok to add a stub for it.

Regards,

--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] winstorecompat: Add a GetStartupInfo stub

2016-09-08 Thread David Wohlferd
On 9/7/2016 2:19 PM, Hugo Beauzée-Luyssen wrote:
>> Is this to deal with the fact that __tmainCRTStartup uses it?
> Exactly. In the end, the function won't be used since __tmainCRTStartup
> won't be used for a windows store app, but we still need the configure
> scripts to be able to compile executables.

I haven't experimented with winstore.  What configure parameters are you 
using?

dw

--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] Added standard-conforming fmaf(), fma() and fmal() functions.

2016-09-08 Thread lhmouse
Oops. Are there any volunteers to implement `fma()` functions for ARM ?

--   
Best regards,
lh_mouse
2016-09-08


--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] [PATCH] Added standard-conforming fmaf(), fma() and fmal() functions.

2016-09-08 Thread lhmouse
---
 mingw-w64-crt/Makefile.am |  4 ++--
 mingw-w64-crt/math/fma.S  | 42 
 mingw-w64-crt/math/fma.c  | 12 ++
 mingw-w64-crt/math/fmaf.S | 43 -
 mingw-w64-crt/math/fmaf.c | 10 
 mingw-w64-crt/math/fmal.c | 61 ++-
 6 files changed, 84 insertions(+), 88 deletions(-)
 delete mode 100644 mingw-w64-crt/math/fma.S
 create mode 100644 mingw-w64-crt/math/fma.c
 delete mode 100644 mingw-w64-crt/math/fmaf.S
 create mode 100644 mingw-w64-crt/math/fmaf.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 886fcf0..1c6e534 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -244,7 +244,6 @@ src_libmingwex=\
   \
   math/_chgsignl.S  math/ceil.Smath/ceilf.S  math/ceill.S  
   math/copysignl.S \
   math/floor.S  math/floorf.S  math/floorl.S \
-  math/fma.Smath/fmaf.S\
   math/nearbyint.S  math/nearbyintf.S  math/nearbyintl.S \
   math/trunc.S  math/truncf.S  \
   math/cbrt.c   \
@@ -252,7 +251,8 @@ src_libmingwex=\
   math/coshf.c  math/coshl.c   math/erfl.c   \
   math/expf.c   \
   math/fabs.c   math/fabsf.c   math/fabsl.c  math/fdim.c   
   math/fdimf.c math/fdiml.c \
-  math/fmal.c   math/fmax.cmath/fmaxf.c  math/fmaxl.c  
   math/fmin.c  math/fminf.c \
+  math/fma.cmath/fmaf.cmath/fmal.c   \
+  math/fmax.c   math/fmaxf.c   math/fmaxl.c  math/fmin.c   
   math/fminf.c \
   math/fminl.c  math/fp_consts.c   math/fp_constsf.c \
   math/fp_constsl.c math/fpclassify.c  math/fpclassifyf.c
math/fpclassifyl.c   math/frexpf.c\
   math/hypotf.c math/hypot.c  math/hypotl.c  math/isnan.c  
math/isnanf.cmath/isnanl.c\
diff --git a/mingw-w64-crt/math/fma.S b/mingw-w64-crt/math/fma.S
deleted file mode 100644
index 74becde..000
--- a/mingw-w64-crt/math/fma.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
-   .file   "fma.S"
-   .text
-#ifdef __x86_64__
-   .align 8
-#else
-   .align 4
-#endif
-   .p2align 4,,15
-   .globl __MINGW_USYMBOL(fma)
-   .def__MINGW_USYMBOL(fma);   .scl2;  .type   32; .endef
-__MINGW_USYMBOL(fma):
-#if defined(_AMD64_) || defined(__x86_64__)
-   subq$56, %rsp
-   movsd   %xmm0,(%rsp)
-   movsd   %xmm1,16(%rsp)
-   movsd   %xmm2,32(%rsp)
-   fldl(%rsp)
-   fmull   16(%rsp)
-   fldl32(%rsp)
-   faddp
-   fstpl   (%rsp)
-   movsd   (%rsp),%xmm0
-   addq$56, %rsp
-   ret
-#elif defined(_ARM_) || defined(__arm__)
-   fmacd d2, d0, d1
-   fcpyd d0, d2
-   bx  lr
-#elif defined(_X86_) || defined(__i386__)
-   fldl4(%esp)
-   fmull   12(%esp)
-   fldl20(%esp)
-   faddp
-   ret
-#endif
diff --git a/mingw-w64-crt/math/fma.c b/mingw-w64-crt/math/fma.c
new file mode 100644
index 000..3703e00
--- /dev/null
+++ b/mingw-w64-crt/math/fma.c
@@ -0,0 +1,12 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+long double fmal ( long double _x,  long double _y,  long double _z);
+
+double
+fma ( double _x,  double _y,  double _z)
+{
+  return (double)fmal(_x, _y, _z);
+}
diff --git a/mingw-w64-crt/math/fmaf.S b/mingw-w64-crt/math/fmaf.S
deleted file mode 100644
index 6bc7ef0..000
--- a/mingw-w64-crt/math/fmaf.S
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
-   .file   "fmaf.S"
-   .text
-#ifdef __x86_64__
-   .align 8
-#else
-   .align 2
-#endif
-   .p2align 4,,15
-   .globl __MINGW_USYMBOL(fmaf)
-   .def__MINGW_USYMBOL(fmaf);  .scl2;  .type   32; .endef
-__MINGW_USYMBOL(fmaf):
-#if defined(_AMD64_) || defined(__x86_64__)
-   subq$56, %rsp
-   movss   %xmm0,(%rsp)
-   movss   %xmm1,16(%rsp)
-   movss   %xmm2,32(%rsp)
-   flds(%rsp)
-   fmuls   16(%rsp)
-   flds32(%rsp)
-   faddp
-   fstps   (%rsp)
-   movss   (%rsp),%xmm0
-   addq$56, %rsp
-   ret
-#elif defined(_ARM_) || defined(__arm__)
-   fmacs s2, s0, s1
-   fcpys s0, s2
-   bx   

Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem

2016-09-08 Thread lhmouse
Thanks for such nice work!
I hope someone would accept it. Kai has been away for days.

--   
Best regards,
lh_mouse
2016-09-08

-
发件人:Thomas Bickel 
发送日期:2016-09-08 21:01
收件人:mingw-w64-public
抄送:
主题:Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem



On 07.09.2016 17:21, lhmouse wrote:
> (I don't write AT assembly so I am unable to make a patch.
> Nevertheless I hope someone who writes AT assembly could fix it.)

I don't have time to write a patch but I can donate some code that AFAIK does 
what you need for the 
sin functions.

 >gcc -m32 sinl32.s sin.c
 >a
sinl = -5.421010862427522170037264e-020
 my_sinl = -0.e+000
sin = 1.224606353822377258211418e-016
 my_sin = 1.225148454908620010428422e-016
sinf = -8.7422776573475858e-008
 my_sinf = -8.7422780003674585e-008

 >gcc -m64 sinl64.s sin.c
 >a
sinl = -5.421010862427522170037264e-020
 my_sinl = -0.e+000
sin = 1.224606353822377258211418e-016
 my_sin = 1.225148454908620010428422e-016
sinf = -8.7422776573475858e-008
 my_sinf = -8.7422776573475858e-008



Regards
Thomas

--

___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public




--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem

2016-09-08 Thread Thomas Bickel



On 07.09.2016 17:21, lhmouse wrote:

(I don't write AT assembly so I am unable to make a patch.
Nevertheless I hope someone who writes AT assembly could fix it.)


I don't have time to write a patch but I can donate some code that AFAIK does what you need for the 
sin functions.


>gcc -m32 sinl32.s sin.c
>a
   sinl = -5.421010862427522170037264e-020
my_sinl = -0.e+000
   sin = 1.224606353822377258211418e-016
my_sin = 1.225148454908620010428422e-016
   sinf = -8.7422776573475858e-008
my_sinf = -8.7422780003674585e-008

>gcc -m64 sinl64.s sin.c
>a
   sinl = -5.421010862427522170037264e-020
my_sinl = -0.e+000
   sin = 1.224606353822377258211418e-016
my_sin = 1.225148454908620010428422e-016
   sinf = -8.7422776573475858e-008
my_sinf = -8.7422776573475858e-008



Regards
Thomas

#define __USE_MINGW_ANSI_STDIO 1
#include 
#include 

#if defined(__x86_64__)  
 extern long double my_sinl64(long double x);
 extern double my_sin64(double x);
 extern float my_sinf64(float x);
#else
 extern long double __cdecl my_sinl32(long double x);
 extern double __cdecl my_sin32(double x);
 extern float __cdecl my_sinf32(float x);
#endif

void
main()
{
const long double thetal = atanl(1.0l) * 4.0l;
printf("   sinl = %.24Le\n", sinl(thetal));
#if defined(__x86_64__) 
printf("my_sinl = %.24Le\n", my_sinl64(thetal));
#else
printf("my_sinl = %.24Le\n", my_sinl32(thetal));
#endif  

printf("   sin = %.24le\n", sin((double)thetal));
#if defined(__x86_64__) 
printf("my_sin = %.24le\n", my_sin64((double)thetal));
#else
printf("my_sin = %.24le\n", my_sin32((double)thetal));
#endif  

printf("   sinf = %.16e\n", sinf((float)thetal));
#if defined(__x86_64__) 
printf("my_sinf = %.16e\n", my_sinf64((float)thetal));
#else
printf("my_sinf = %.16e\n", my_sinf32((float)thetal));
#endif  

}
.macro M_FSIN
2:  fprem1
fnstsw  %ax
sahf
jp 2b
fstp%st(1)
fsin
testw   $0x200, %ax
jz 1f
fchs
1:
.endm

.text
.align 4
.globl _my_sinl32
_my_sinl32:
fldpi
fldt4(%esp) 
M_FSIN
ret

.align 4
.globl _my_sin32
_my_sin32:
fldpi
fldl4(%esp) 
M_FSIN
ret 

.align 4
.globl _my_sinf32
_my_sinf32:
fldpi
flds4(%esp) 
M_FSIN
ret 

.macro M_FSIN
2:  fprem1
fnstsw  %ax
sahf
jp 2b
fstp%st(1)
fsin
testw   $0x200, %ax
jz 1f
fchs
1:
.endm   

.text
.globl my_sinl64
my_sinl64:
fldpi
fldt(%rdx)  
M_FSIN
movq%rcx, %rax
fstpt   (%rcx)
ret

.globl my_sin64
my_sin64:
fldpi
movsd   %xmm0, 8(%rsp)
fldl8(%rsp) 
M_FSIN
fstpl   8(%rsp) 
movsd   8(%rsp), %xmm0
ret

.globl my_sinf64
my_sinf64:
fldpi
movss   %xmm0, 8(%rsp)
flds8(%rsp) 
M_FSIN
fstps   8(%rsp) 
movss   8(%rsp), %xmm0
ret

--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] `fma()` functions are completely wrong in mingw-w64

2016-09-08 Thread lhmouse
Reading `mingw-w64/mingw-w64-crt/math/fmal.c`:

long double
fmal ( long double _x,  long double _y,  long double _z)
{
  return ((_x * _y) + _z);
}

This implementation is completely wrong.

https://en.wikipedia.org/wiki/Multiply–accumulate_operation#Fused_multiply.E2.80.93add
The multiplication in a single FMA operation must behave as if
the result had infinite precision. That is, multiplying
two x87-extended-precision floating point numbers
(1 sign + 15 exp + 64 frac = 80 bits) yields a result of 144 bits
(1 sign + 15 exp + 64 frac * 2 = 144 bits).

For example, with a conforming `fmal()`, the expression
`fmal(1.2l, 3.4l, -3.00010l)` shall yield
approximately `8e-18`, because `1.2l * 3.4l` yields
`3.000108l`. But in mingw-w64, this indeterminate result
is truncated when converted to `long double`, yielding `3.0001l`,
and adding `-3.00010l` to it yields zero.

Since x87 does not have 128-bit registers, FMA must be done in software:
1. Split both multiplier into higher and lower parts. Since a `long double`
has 64 significant bits (it does not have a hidden bit), either of the two 
parts
has to have 32 bits so we don't get precision losses when multiplying them.
2. Keeping in mind that `(a+b)(c+d)=ac+ad+bc+bd`, calculate the sum
IN THE FOLLOWING ORDER:

long double ret = z;
ret += xhi * yhi;
ret += xhi * ylo + xlo * yhi;
ret += xlo * ylo;


A conforming implementation can be found here:
https://github.com/lhmouse/MCF/blob/master/MCFCRT/src/stdc/math/fma.c

--
Best regards,
lh_mouse
2016-09-08


--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem

2016-09-08 Thread lhmouse
It is merely a function guaranteed to be declared implicitly
(thus requires no ) and has the same semantics with
the standard function `sinl()`. The GCC optimizer can perform
certain types of optimization such as constant folding and inlining
only if `fsinl()` is supposed to do the same thing as specified
by the C standard, which could be explicitly disabled using
`-fno-builtin` or `-ffreestanding`. AFAICS there is otherwise 
no difference. `__builtin_fsinl()` may result in a call to `sinl()`.

--   
Best regards,
lh_mouse
2016-09-08

-
发件人:NightStrike 
发送日期:2016-09-08 15:06
收件人:mingw-w64-public@lists.sourceforge.net
抄送:
主题:Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem

What does gcc's __builtin_sinl() do?


--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem

2016-09-08 Thread NightStrike
What does gcc's __builtin_sinl() do?

On Wed, Sep 7, 2016 at 11:37 PM, lhmouse  wrote:
> If performance is the problem there are a number of solutions such as
> inline assembly, static lookup tables, etc. `fsinl()` is apparently not one
> of them.
> But yes, I am all ears
>
> --
> Best regards,
> lh_mouse
> 2016-09-08
>
> -
> 发件人:Riot 
> 发送日期:2016-09-08 04:00
> 收件人:mingw-w64-public
> 抄送:
> 主题:Re: [Mingw-w64-public] sinl/cosl/tanl accuracy problem
>
> Some of us (game developers especially) greatly prefer a minor inaccuracy
> to a potentially major slowdown; I would personally opposed this change, as
> you're noticeably increasing the cost of something that's used heavily in
> tightly looped code.  Perhaps an appropriately named #ifdef switch would be
> a way to please everyone here?
>
> Regards,
> Riot
>
>
> --
> ___
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

--
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public