Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Help needed with FPE handling



18.06.2010 18:57, Matthias Drochner wrote:

I don't have an amd64 to test. How does it fail?

sys_float.c:(.text+0x242): undefined reference to `skip_sse2_insn'
make[3]: *** [/home/pkgsrc/wip/erlang/work.x86_64/otp_src_R14A/bin/x86_64-unknown-netbsd5.99.30/beam.smp] Error 1

so the x86_64 code should really have same functionality like the other #ifdef fragments have now. And no, patch-as is not my patch originally.

Why are you doing it differently than all the other OSes?

The good thing is that NetBSD/i386 seems to work but the NetBSD/amd64 code needs to look like the other 64-bit BSDs. I tried the OpenBSD/amd64 code but it didn't work and I don't have more time to investigate this now.

In the old Erlang R12B-0 code, that function had


#elif defined(__FreeBSD__) && defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
    struct envxmm *envxmm = &savefpu->sv_env;
    if (envxmm->en_mxcsr & 0x000D) {
        envxmm->en_mxcsr &= ~(0x003F|0x0680);
        skip_sse2_insn(mc);
    }
    envxmm->en_sw &= ~0xFF;
#elif defined(__FreeBSD__) && defined(__i386__)
    mcontext_t *mc = &uc->uc_mcontext;
    union savefpu *savefpu = (union savefpu*)&mc->mc_fpstate;
    if (mc->mc_fpformat == _MC_FPFMT_XMM) {
        struct envxmm *envxmm = &savefpu->sv_xmm.sv_env;
        if (envxmm->en_mxcsr & 0x000D) {
            envxmm->en_mxcsr &= ~(0x003F|0x0680);
            skip_sse2_insn(mc);
        }
        envxmm->en_sw &= ~0xFF;
    } else {
        struct env87 *env87 = &savefpu->sv_87.sv_env;
        env87->en_sw &= ~0xFF;
    }
#elif defined(__OpenBSD__) && defined(__x86_64__)
    struct fxsave64 *fxsave = uc->sc_fpstate;
    if (fxsave->fx_mxcsr & 0x000D) {
        fxsave->fx_mxcsr &= ~(0x003F|0x0680);
        skip_sse2_insn(uc);
    }
    fxsave->fx_fsw &= ~0xFF;
#elif defined(__sun__) && defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    struct fpchip_state *fpstate = &mc->fpregs.fp_reg_set.fpchip_state;
    if (fpstate->mxcsr & 0x000D) {
        fpstate->mxcsr &= ~(0x003F|0x0680);
        skip_sse2_insn(mc);
    }
    fpstate->sw &= ~0xFF;
#endif
    set_current_fp_exception();
}


but in the latest version the code has been rewritten not to use skip_sse2_insn and it looks like this


#elif defined(__FreeBSD__) && defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
    struct envxmm *envxmm = &savefpu->sv_env;
    pc = mc_pc(mc);
    envxmm->en_mxcsr = 0x1F80;
    envxmm->en_sw &= ~0xFF;
#elif defined(__FreeBSD__) && defined(__i386__)
    mcontext_t *mc = &uc->uc_mcontext;
    union savefpu *savefpu = (union savefpu*)&mc->mc_fpstate;
    pc = mc_pc(mc);
    if (mc->mc_fpformat == _MC_FPFMT_XMM) {
        struct envxmm *envxmm = &savefpu->sv_xmm.sv_env;
        envxmm->en_mxcsr = 0x1F80;
        envxmm->en_sw &= ~0xFF;
    } else {
        struct env87 *env87 = &savefpu->sv_87.sv_env;
        env87->en_sw &= ~0xFF;
    }
#elif defined(__OpenBSD__) && defined(__x86_64__)
    struct fxsave64 *fxsave = uc->sc_fpstate;
    pc = mc_pc(uc);
    fxsave->fx_mxcsr = 0x1F80;
    fxsave->fx_fsw &= ~0xFF;
#elif defined(__sun__) && defined(__x86_64__)
    mcontext_t *mc = &uc->uc_mcontext;
    struct fpchip_state *fpstate = &mc->fpregs.fp_reg_set.fpchip_state;
    pc = mc_pc(mc);
    fpstate->mxcsr = 0x1F80;
    fpstate->sw &= ~0xFF;
#endif


I don't know (yet) how to write the NetBSD/amd64 code as this "gregs[REG_RIP]" looks so different that in other BSDs (and I haven't look that the other BSD source codes).

So feel free to update your pkgsrc/wip and take a look at the updated patch-as and figure out how it should be implemented for NetBSD/amd64 :-)

Martti


Home | Main Index | Thread Index | Old Index