[racket-dev] Extflonum type for windows
Hello all,
The following pull request provides long double type (extflonum) on
win32: https://github.com/plt/racket/pull/265
Extflonum arithmetic is implemented in a set of functions
compiled into longdouble.dll (dll and lib attached, source
code included in the pull request). It has been compiled
with mingw-w64. In ordinary mingw there is no long double
input (neither non-msvc strtold nor scanf).
All those functions accept a special long_double union:
#define SIZEOF_LONGDOUBLE 16
typedef union long_double
{
char bytes[SIZEOF_LONGDOUBLE];
#ifdef __MINGW__
long double val;
#endif
} long_double;
Racket's libffi uses this union for ffi facilities instead
of ffi_type_longdouble, because ffi_type_longdouble is
defined to ffi_type_double on win platforms.
To compile the longdouble library yourself, use the following
commands:
(mingw-w64, msvc environments are required):
cd src/racket/src/longdouble
gcc.exe -shared -o longdouble.dll longdouble.c
-Wl,--output-def,longdouble.def,--out-implib,longdouble.a -I.
lib /machine:i386 /def:longdouble.def
copy /Y longdouble.dll ..\..\..\..\lib\.
It seems that RacketCGC is supposed to be built without any
third-party DLLs (longdouble.dll being one of them), so the
following building process seems natural:
1. RacketCGC builds with Visual Studio, without MZ_LONG_DOUBLE
and without longdouble.dll. (There is currently no MS_LONG_DOUBLE
macro
in worksp/mzconfig.h)
2. RacketCGC is called to download third-party libraries, including
longdouble.dll and longdouble.lib
3. gc2/make.rkt is called to compile Racket3m. It uses command
line options to define MS_LONG_DOUBLE macro for the compiled
code and to link it against longdouble.lib
Matthew, could you please adjust the build scripts so that
items 2 and 3 work? Or, of course, any other way that you find
convenient.
There are some issues which I do not know how to solve, because they
depend on racket maintainers work style.
Some miscellaneous notes:
1. There is currently a problem with the code generation in
foreign.rktc.
As a result of foreign.rktc's code generation, line 1974 is supposed
to be:
tmp = (mz_long_double)(SCHEME_MAYBE_LONG_DBL_VAL(val));
Unfortunately, that does not compile, saying
error C2440: 'type cast' : cannot convert from 'long_double' to
'mz_long_double'
So we must not cast the structure value type into itself.
Good news is that simple assignment without casting works fine.
Probably there is a need for an option in foreign.rktc declaratons
to turn off casting in this partuicular case. Matthew, it is possible
to add such an option?
2. xform.rkt contains a long list of all long double arithmetic
[non-]functions.
3. In numstr.c I could not avoid separating the parsing of
double and long double values.
I have tested the code on windows 7 x86 msvc 2008 (virtualbox).
x64 has not been tested yet.
Binary longdouble library can be found here:
https://github.com/filonenko-mikhail/racket/tree/extflonum-windows/src/racket/src/longdouble
--
With best regards, Michael Filonenko