Home
Patch for incorrect heap function declarations in winnt.h
Fix a few return types in winnt.h
VOTE: x64dbg
Here is my final code, the function fxclassify is a candidate to replace ___fxclassifyl on x64 (it is correct in the sense that the currently unimplementation FP_UNSUPPORTED flag is returned as FP_NAN). The function hwclassify is inline assembly and this works, I added support for FP_UNSUPPORTED (and if you define unsupported as nan it works). The macro btclassify calls __builtin_fpclassify and should not be used because it is incorrect (admittedly only in certain edge cases where you have a denormal...
Okay that code is broken I will try again...
I did some more testing where I take all possible sign_exponent and high values that influence the classification according to wikipedia and compare my implementation (with #define FP_UNSUPPORTED FP_NAN) with __builtin_fpclassify and it appears that my implementation is correct (or at least matches the builtin classification): https://ideone.com/RB1sZm I will do some more testing also on the 32 bit version of GCC and mingw-w64 later to see if the 32 bit builtin/software implementation is the same....
This code: #include <math.h> int main() { long double ld = 0; unsigned char data[10] = { 0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59 }; __builtin_memcpy(&ld, data, 10); __builtin_printf("sizeof(long double) = %d\n", sizeof(long double)); __builtin_printf("FP_NAN: 0x%X\nFP_NORMAL: 0x%X\n", FP_NAN, FP_NORMAL); __builtin_printf("fpclassify: 0x%X\n", fpclassify(ld), FP_NAN, FP_NORMAL); } Shows (on GCC 6.3): sizeof(long double) = 16 FP_NAN: 0x0 FP_NORMAL: 0x4 fpclassify: 0x0 And on Apple...
Sorry about the swearing I forgot to clean that up lol. Also I agree, just missed that one. Does this look correct? I'm not particularly sure about the bit manipulation stuff... int myclassify(long double ld) { __mingw_ldbl_type_t lds = *(__mingw_ldbl_type_t*)&ld; //https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format auto bit63 = (lds.lh.high & 0x80000000) != 0; switch (lds.lh.sign_exponent & 0x7fff) //Exponent { case 0: //Exponent: All Zeros { if (!bit63) //Bit 63: Zero...
Hm so then there is a bug in GCC... Or because it's implementation defined they chose to classify this as NAN :-D http://x86.renejeschke.de/html/file_module_x86_id_125.html I'm currently rather unclear about how this table relates to the values of FP_NAN, etc. but I can add FP_UNSUPPORTED. Could you check if my current implementation of that wikipedia table is correct? int myclassify(long double ld) { __mingw_ldbl_type_t fuck = *(__mingw_ldbl_type_t*)&ld; //https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format...
The builtin classifier for gcc is very clear: that value is nan. The 32 bit inline assembly is also very clear: nan. These macros are based on the hardware implementation so following the hardware is definitely correct I think. Another argument for using what the hardware tells you is that if you don't you get the kind of garbage output I got because the value is invalid but you try to do something with it anyway.
To clarify: the hardware implementation I'm talking about is also in that function for 32 bit.
To clarify: the hardware implementation I'm talking about is also in that function for 32 bit. On Tue, 25 Apr 2017 at 08:31, TPoDT|Mr. eXoDia mr.exodia.tpodt@gmail.com wrote: The builtin classifier for gcc is very clear: that value is nan. The 32 bit inline assembly is also very clear: nan. These macros are based on the hardware implementation so following the hardware is definitely correct I think. Another argument for using what the hardware tells you is that if you don't you get the kind of garbage...
The builtin classifier for gcc is very clear: that value is nan. The 32 bit inline assembly is also very clear: nan. These macros are based on the hardware implementation so following the hardware is definitely correct I think. Another argument for using what the hardware tells you is that if you don't you get the kind of garbage output I got because the value is invalid but you try to do something with it anyway. On Tue, 25 Apr 2017 at 05:27, LH_Mouse lhmouse@users.sf.net wrote: If we weren't emulating...
Okay I found and the bug in the software implementation (it also appears to exist in glibc by the way). I still believe __builtin_fpclassify should be called in the fpclassify macro and the __fpclassifyX family of functions should never be used directly. This is the code for math.h (I'm pretty sure the other software implementations are also broken, for long double but also the other floating point types): #ifndef __CRT__NO_INLINE __CRT_INLINE int __cdecl __fpclassifyl (long double x) { #if defined(__x86_64__)...
Hm okay, so is nan an incorrect classification or is that what should be looked at for the software implementation?
I have confirmed this fix, by replacing the implementations of __fpclassifyl with __builtin_fpclassify everything works correctly, but I don't know how to properly fix this (there are various direct uses of __fpclassifyl in mingw_pformat.c so my solution would be to replace those with fpclassify and then replace the macro for fpclassify with a call to __builtin_fpclassify).
Okay, the solution is to either fix __fpclassifyl (x64 uses a bad software implementation) or just use __builtin_fpclassify: #include <math.h> #include <stdio.h> #include <string.h> # define fufu(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \ FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x) const char* show_classification(long double x) { switch(fufu(x)) { case FP_INFINITE: return "Inf"; case FP_NAN: return "NaN"; case FP_NORMAL: return "normal"; case FP_SUBNORMAL: return "subnormal"; case FP_ZERO: return "zero";...
__mingw_printf invalid output for nan value
change the stroke size with the mouse wheel