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

2016-09-07 Thread lhmouse
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


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

2016-09-07 Thread Hugo Beauzée-Luyssen
On 09/07/2016 10:09 PM, David Wohlferd wrote:
> I'm confused.  Is GetStartupInfo even a winstore function?

Nope

> 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.

Regards,

>
> dw
>
> On 9/7/2016 1:31 AM, Hugo Beauzée-Luyssen wrote:
>> On 09/07/2016 10:25 AM, Jacek Caban wrote:
>>> Hi Hugo,
>>>
>>> On 06.09.2016 16:11, Hugo Beauzée-Luyssen wrote:
 +#define GetStartupInfo __GetStartupInfo
 +#include 
 +#undef GetStartupInfo
 +
 +VOID WINAPI GetStartupInfo( LPSTARTUPINFO lpStartupInfo )
 +{
 +(void)lpStartupInfo;
 +}
>>>
>>> Callers of this function expect passed STARTUPINFO to be filled with
>>> something sane. You can't just leave it untouched, it would most likely
>>> fail in runtime.
>>>
>>>
>>> Thanks,
>>>
>>> Jacek
>>>
>>>
>>> --
>>> ___
>>> Mingw-w64-public mailing list
>>> Mingw-w64-public@lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>>>
>> Hi,
>>
>> Fair point, would 0'ing it be ok in your opinion?
>>
>> Regards,
>>
>>
>> --
>> ___
>> 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
>


--
___
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-07 Thread David Wohlferd
I'm confused.  Is GetStartupInfo even a winstore function?  Is this to 
deal with the fact that __tmainCRTStartup uses it?

dw

On 9/7/2016 1:31 AM, Hugo Beauzée-Luyssen wrote:
> On 09/07/2016 10:25 AM, Jacek Caban wrote:
>> Hi Hugo,
>>
>> On 06.09.2016 16:11, Hugo Beauzée-Luyssen wrote:
>>> +#define GetStartupInfo __GetStartupInfo
>>> +#include 
>>> +#undef GetStartupInfo
>>> +
>>> +VOID WINAPI GetStartupInfo( LPSTARTUPINFO lpStartupInfo )
>>> +{
>>> +(void)lpStartupInfo;
>>> +}
>>
>> Callers of this function expect passed STARTUPINFO to be filled with
>> something sane. You can't just leave it untouched, it would most likely
>> fail in runtime.
>>
>>
>> Thanks,
>>
>> Jacek
>>
>>
>> --
>> ___
>> Mingw-w64-public mailing list
>> Mingw-w64-public@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>>
> Hi,
>
> Fair point, would 0'ing it be ok in your opinion?
>
> Regards,
>
>
> --
> ___
> 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-07 Thread Riot
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

On 7 September 2016 at 16: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.)
>
> The x87 `sinl` instruction has been suffering from an accuracy problem
> since decades ago, which is described in this article:
> https://software.intel.com/blogs/2014/10/09/fsin-
> documentation-improvements-in-the-intel-64-and-ia-32-
> architectures-software
>
> Long story short: Before we can calculate `sin(x)`, we have to reduce `x`
> such that it falls in (-π/2,π/2]. This can be easily done via dividing `x`
> with π and getting the remainder. The problem is that, instead of
> a reasonably accurate value of π, `FSIN` uses a 66-bit approximate value
> as the divisor, which makes the result very inaccurate if `x` is proximate
> to
> some multiple of π, because the remainder would end up with most of
> its upper bits being zero and very few significant bits left.
>
> To compromise with Intel people, as the article suggests, it is essential
> to reduce `x` before executing the `fsin` instruction. This is done as
> follows:
>
> 1. Use `FLDPI` instruction to get an accurate value of π.
> 2. Run `FPREM1` instruction repeatly until the _C2_ bit in FPU status word
> is cleared. The result remainder will be in (-π/2,π/2], and
> the _C0_,_C3_,_C1_ bits are the least three significant bits of
> the quotient, from left to right.
> 3. Calculate the sine value using `FSIN` instruction. This never fails.
> 4. Acknowledging that `sin(x) = -sin(x+kπ)` when `k` is odd and
> `sin(x) = sin(x+kπ)` when `k` is even, because the parity bit of the
> quotient
> is the _C1_ bit in the FPU status word, if it is set, negate the
> result with
> `FCHS` instruction. We get the sine value now.
>
> The above process is the same for cosine.
> In the case of tangent, step 4 should be removed.
>
>
> The following code fragment compares `sinl` from mingw-w64 and
> my own implementation:
>
> volatile auto one = 1.0l;
> auto theta = atanl(one) * 4; // This function is from mingw-w64.
> std::printf("sinl   (theta) = %.16Le\n", sinl   (theta));
> std::printf("my_sinl(theta) = %.16Le\n", my_sinl(theta));
>
> It produces the following result:
>
> sinl   (theta) = 1.6263032587282567e-019
> my_sinl(theta) = -0.e+000
>
> My implementation could be found here:
> https://github.com/lhmouse/MCF/blob/master/MCFCRT/src/stdc/math/sin.c#L12
>
> static inline long double fpu_sin(long double x){
> unsigned fsw;
> const long double reduced = __MCFCRT_fremainder(, x,
> __MCFCRT_fldpi());
> long double ret = __MCFCRT_fsin_unsafe(reduced);
> if(fsw & 0x0200){
> ret = __MCFCRT_fneg(ret);
> }
> return ret;
> }
>
> --
> Best regards,
> lh_mouse
> 2016-09-07
>
>
> 
> --
> ___
> 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


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

2016-09-07 Thread lhmouse
(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.)

The x87 `sinl` instruction has been suffering from an accuracy problem
since decades ago, which is described in this article:
https://software.intel.com/blogs/2014/10/09/fsin-documentation-improvements-in-the-intel-64-and-ia-32-architectures-software

Long story short: Before we can calculate `sin(x)`, we have to reduce `x`
such that it falls in (-π/2,π/2]. This can be easily done via dividing `x`
with π and getting the remainder. The problem is that, instead of
a reasonably accurate value of π, `FSIN` uses a 66-bit approximate value
as the divisor, which makes the result very inaccurate if `x` is proximate to
some multiple of π, because the remainder would end up with most of
its upper bits being zero and very few significant bits left.

To compromise with Intel people, as the article suggests, it is essential
to reduce `x` before executing the `fsin` instruction. This is done as follows:

1. Use `FLDPI` instruction to get an accurate value of π.
2. Run `FPREM1` instruction repeatly until the _C2_ bit in FPU status word
is cleared. The result remainder will be in (-π/2,π/2], and 
the _C0_,_C3_,_C1_ bits are the least three significant bits of
the quotient, from left to right.
3. Calculate the sine value using `FSIN` instruction. This never fails.
4. Acknowledging that `sin(x) = -sin(x+kπ)` when `k` is odd and
`sin(x) = sin(x+kπ)` when `k` is even, because the parity bit of the 
quotient
is the _C1_ bit in the FPU status word, if it is set, negate the result with
`FCHS` instruction. We get the sine value now.

The above process is the same for cosine.
In the case of tangent, step 4 should be removed.


The following code fragment compares `sinl` from mingw-w64 and
my own implementation:

volatile auto one = 1.0l;
auto theta = atanl(one) * 4; // This function is from mingw-w64.
std::printf("sinl   (theta) = %.16Le\n", sinl   (theta));
std::printf("my_sinl(theta) = %.16Le\n", my_sinl(theta));

It produces the following result:

sinl   (theta) = 1.6263032587282567e-019
my_sinl(theta) = -0.e+000

My implementation could be found here:
https://github.com/lhmouse/MCF/blob/master/MCFCRT/src/stdc/math/sin.c#L12

static inline long double fpu_sin(long double x){
unsigned fsw;
const long double reduced = __MCFCRT_fremainder(, x, 
__MCFCRT_fldpi());
long double ret = __MCFCRT_fsin_unsafe(reduced);
if(fsw & 0x0200){
ret = __MCFCRT_fneg(ret);
}
return ret;
}

--
Best regards,
lh_mouse
2016-09-07


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


[Mingw-w64-public] CRT math implementations on ARM

2016-09-07 Thread Martin Storsjö
Hi,

In my testing with mingw-w64 on ARM, I've run into a number of issues with 
the implementation of the math routines. Some of these issues are:

The whole family of log functions is problematic (even after my fix for 
the number of iterations in 41de4baaccba), e.g. log2() only returns values 
in the range -17.6 - 7.73, for values outside.

For some values, it even crashes. IIRC, the issue iss an infinite 
recursion; bsd__ieee754_powf calls scalbnf, which calls bsd__ieee754_powf. 
E.g. log2f(strtod("1.225000", NULL)) will show this behaviour (using 
strtod to avoid any risk of the compiler evaluating it at compile time).

Likewise sin/cos and pow also have implementation accuracy issues - I 
haven't dug quite as deep into these, but just removing them (and linking 
to the msvcrt.dll versions instead) make the remaining libav testsuite 
failures go away. (Tested on wine though, whose msvcrt implementation 
might be better in some aspects than the real msvcrt.dll.)

Functions like floor and ceil are implemented using vcvtr.s32.f64, which 
effectively limits the range of these functions to what is expressible 
with signed 32 bits. This isn't that I've run into in actual real world 
code though, but it was noted at some point that it could be an issue.


I understand that mingw-w64 wants to reimplement math functions instead of 
linking to msvcrt in order to get proper C99 compliance. For the mentioned 
families of functions (log, pow, sin, cos), what C99 compliance issues are 
there with the msvcrt.dll implementations?

For functions that don't exist in the plain msvcrt.dll, like log2 and 
exp2, we can easily call the normal log/exp and multiply with a constant.

For functions that do exist in the normal msvcrt.dll, if those individual 
functions don't need any extra C99 conformance, we can just leave them out 
from libmingwex.a and link to msvcrt.dll instead. If some extra C99 
functionality is needed (perhaps handling of edge cases?), it's a bit 
trickier - can one do something like this?

double log(double x) {
 if (isnan(x))
return x;
 return __imp_log(x);
}

Locally when testing this, I've left out all of 
mingw-w64-crt/math/softfloat/*, and changed the log2/exp2 functions to 
just call log/exp, and gotten it working. But what would be required in 
order to get this fixed up upstream?

// Martin

--
___
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-07 Thread Hugo Beauzée-Luyssen
On 09/07/2016 10:25 AM, Jacek Caban wrote:
> Hi Hugo,
>
> On 06.09.2016 16:11, Hugo Beauzée-Luyssen wrote:
>> +#define GetStartupInfo __GetStartupInfo
>> +#include 
>> +#undef GetStartupInfo
>> +
>> +VOID WINAPI GetStartupInfo( LPSTARTUPINFO lpStartupInfo )
>> +{
>> +(void)lpStartupInfo;
>> +}
>
>
> Callers of this function expect passed STARTUPINFO to be filled with
> something sane. You can't just leave it untouched, it would most likely
> fail in runtime.
>
>
> Thanks,
>
> Jacek
>
>
> --
> ___
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>

Hi,

Fair point, would 0'ing it be ok in your opinion?

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] Add a windowsapp.lib

2016-09-07 Thread Hugo Beauzée-Luyssen
On 09/07/2016 02:15 AM, Martell Malone wrote:
> Hey,
>
> Are you sure this is correct?
> It seems to be for libarm32 but the xbox1 is x64.
>
> Best,
> Martell
>
> On Tue, Sep 6, 2016 at 8:27 AM, Hugo Beauzée-Luyssen 
> wrote:
>
>> Hi,
>>
>> When building apps for Xbox1 (at least), this lib must be used instead
>> of kernel32.lib, since kernel32.dll isn't shipped on this system.
>>
>> Since the patch is big, and I've been asked to refrain from sending big
>> chunks here, the patch is located there:
>> http://people.videolan.org/~hugo/0001-libarm32-Add-a-windowsapp.lib.patch
>>
>> Best regards,
>>
>> 
>> --
>> ___
>> 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
>

Oops... I obviously meant this link O:-)
http://people.videolan.org/~hugo/0001-crt-Add-a-WindowsApp.lib-mri-associated-def-files.patch

Using WindowsApp.lib seems to be the proper way of doing store apps now, 
including on x86 & arm. I'll submit the arm patch once I'll have tested 
it, but it should definitely be ignored in the meantime.

Thanks for noticing!

Best regards,

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