I think I found the source of the problem: the C code expects that all the
Intel's x86's floating point register tag bits are set to 1, but it seems
the Haskell code does not preserve that.
Since the x86 has all kinds of floating point
weirdness<http://www.informit.com/articles/article.aspx?p=770362> -
it is both a stack based and register based system - so it is crucially
important that generated code plays nice. For example, when using MMX one
must always emit an EMMS
instruction<http://msdn.microsoft.com/en-us/library/590b9ks9(VS.80).aspx>to
clear these tag bits.
If I manually clear these tags bits, my code works fine.
Is this something other people encountered as well? I'm trying to make a
very simple test case to reproduce the behavior...
I'm not sure if this is a visual C compiler bug, GHC bug, or something I'm
doing wrong...
Is it possible to annotate a foreign imported C function to tell the Haskell
code generator the functioin is using floating point registers somehow?
That test compares the result of the builtin floating point ops with
the same ops imported via FFI. The should not be different, but on
Intel they sometimes are.
Regards,
Malcolm
On 3 Apr 2009, at 18:58, Peter Verswyvelen wrote:
> For days I'm fighting against a weird bug.
>
> My Haskell code calls into a C function residing in a DLL (I'm on
> Windows, the DLL is generated using Visual Studio). This C function
> computes a floating point expression. However, the floating point
> result is incorrect.
>
> I think I found the source of the problem: the C code expects that
> all the Intel's x86's floating point register tag bits are set to 1,
> but it seems the Haskell code does not preserve that.
>
> Since the x86 has all kinds of floating point weirdness - it is both
> a stack based and register based system - so it is crucially
> important that generated code plays nice. For example, when using
> MMX one must always emit an EMMS instruction to clear these tag bits.
>
> If I manually clear these tags bits, my code works fine.
>
> Is this something other people encountered as well? I'm trying to
> make a very simple test case to reproduce the behavior...
>
> I'm not sure if this is a visual C compiler bug, GHC bug, or
> something I'm doing wrong...
>
> Is it possible to annotate a foreign imported C function to tell the
> Haskell code generator the functioin is using floating point
> registers somehow?
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
So I'll try to reduce this to a small reproducible test case, maybe
including the assembly generated by the VC++ compiler.
Does anybody know what the calling convention for floating points is for
cdecl on x86? The documentation says that the result is returned in st(0),
but it says nothing about the floating point tags. I assume that every
function expects the FP stack to be empty, potentially containing just
argument values. But GHC calls the C function with some FP registers
reserved on the stack...
You didn't say what version of GHC you are using, but it sounds like
this might already be fixed in 6.10.2 by:
Tue Nov 11 12:56:19 GMT 2008 Simon Marlow <marl...@gmail.com>
* Fix to i386_insert_ffrees (#2724, #1944)
The i386 native code generator has to arrange that the FPU stack is
clear on exit from any function that uses the FPU. Unfortunately it
was getting this wrong (and has been ever since this code was written,
I think): it was looking for basic blocks that used the FPU and adding
the code to clear the FPU stack on any non-local exit from the block.
In fact it should be doing this on a whole-function basis, rather than
individual basic blocks.
Thanks
Ian
Since this is such a severe bug, I would recommend listing it :)
Anyway, I have a very small repro test case now. Will certainly test this
with GHC 6.10.2.