Subject: FPU handling
To: None <port-amd64@netbsd.org>
From: Ignatios Souvatzis <is@netbsd.org>
List: port-amd64
Date: 12/21/2007 17:56:58
Hello,

I'm trying to make erlang work on NetBSD/amd64.

The code that needs to be ported is about this:

static void fpe_sig_action(int sig, siginfo_t *si, void *puc)
{
    ucontext_t *uc = puc;
#if defined(__linux__)
#if defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    fpregset_t fpstate = mc->fpregs;
    /* A failed SSE2 instruction will restart. To avoid
       looping, we must update RIP to skip the instruction
       (leaving garbage in the destination).
       The alternative is to mask SSE2 exceptions now and
       unmask them again later in erts_check_fpe(), but that
       relies too much on other code being cooperative. */
    if (fpstate->mxcsr & 0x000D) { /* OE|ZE|IE; see unmask_sse2() */
        fpstate->mxcsr &= ~(0x003F|0x0680);
        skip_sse2_insn(mc);
    }
    fpstate->swd &= ~0xFF;

(with similar stuff for FreeBSD/amd64, Darwin/Amd64 and OpenBSD/amd64).

I tried:

#elif defined(__NetBSD__) && defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    struct fxsave64 *fxsave = (struct fxsave64 *)&mc->__fpregs;
    if (fxsave->fx_mxcsr & 0x000D) {
        fxsave->fx_mxcsr &= ~(0x003F|0x0680);
        skip_sse2_insn(mc);
    } /* XXX ??? */
    fxsave->fx_fsw &= ~0xFF; /* XXX ??? */
#else

but the test programs hang; it looks like the handler gets called
over and over again with mxcsr=0x1900 and IP always being the same 
value.

I'm not familiar with the architecture at all; is there any obvious
error in what I've done?

	-is