示例#1
0
void
_thread_machdep_save_float_state(struct _machdep_state *ms)
{
	union savefpu *addr = &ms->fpreg;

	if (_thread_machdep_osfxsr()) {
		fwait();
		fxsave(&addr->sv_xmm);
		fninit();
	} else
		fnsave(&addr->sv_87);
	fwait();
}
示例#2
0
void
fputrap(struct trapframe *frame)
{
	register struct lwp *l = curcpu()->ci_fpcurlwp;
	struct pcb *pcb = lwp_getpcb(l);
	struct savefpu *sfp = &pcb->pcb_savefpu;
	uint32_t mxcsr, statbits;
	uint16_t cw;
	ksiginfo_t ksi;

	KPREEMPT_DISABLE(l);
	x86_enable_intr();

	/*
	 * At this point, fpcurlwp should be curlwp.  If it wasn't, the TS bit
	 * should be set, and we should have gotten a DNA exception.
	 */
	KASSERT(l == curlwp);
	fxsave(sfp);
	pcb->pcb_savefpu_i387.fp_ex_tw = sfp->fp_fxsave.fx_ftw;
	pcb->pcb_savefpu_i387.fp_ex_sw = sfp->fp_fxsave.fx_fsw;

	if (frame->tf_trapno == T_XMM) {
		mxcsr = sfp->fp_fxsave.fx_mxcsr;
		statbits = mxcsr;
		mxcsr &= ~0x3f;
		x86_ldmxcsr(&mxcsr);
	} else {
		fninit();
		fwait();
		cw = sfp->fp_fxsave.fx_fcw;
		fldcw(&cw);
		fwait();
		statbits = sfp->fp_fxsave.fx_fsw;
	}
	KPREEMPT_ENABLE(l);

	KSI_INIT_TRAP(&ksi);
	ksi.ksi_signo = SIGFPE;
	ksi.ksi_addr = (void *)frame->tf_rip;
	ksi.ksi_code = x86fpflags_to_ksiginfo(statbits);
	ksi.ksi_trap = statbits;
	(*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
}
示例#3
0
/*
The feraiseexcept function raises the supported floating-point
exceptions represented by its argument. The order in which
these floating-point exceptions are raised is unspecified, except
as stated in F.7.6. Whether the feraiseexcept function additionally
raises the inexact floating-point exception whenever it raises the
overflow or underflow floating-point exception is implementation-defined.
*/
_WCRTLINK int feraiseexcept( int excepts )
/****************************************/
{
    fenv_t      env;

    fenv_store( &env );
    env.status_word |= excepts & FE_ALL_EXCEPT;
    fenv_load( &env );
    fwait();    /* Make sure exception gets triggered now */
    return( 0 );
}
示例#4
0
void
_thread_machdep_restore_float_state(struct _machdep_state *ms)
{
	union savefpu *addr = &ms->fpreg;

	if (_thread_machdep_osfxsr()) {
		fxrstor(&addr->sv_xmm);
		fwait();
	} else
		frstor(&addr->sv_87);

}