FreeBSD/sys/arm/arm/vfp.c
/* start VFP unit, restore the vfp registers from the PCB  and retry
 * the instruction
 */
start VFP unit, restore the vfp registers from the PCB  and retry
the instruction
start VFP unit restore the vfp registers from the PCB and retry the instruction
static int
vfp_bounce(u_int addr, u_int insn, struct trapframe *frame, int code)
{
	u_int cpu, fpexc;
	struct pcb *curpcb;
	ksiginfo_t ksi;
	if ((code & FAULT_USER) == 0)
		panic("undefined floating point instruction in supervisor mode");
	critical_enter();
	fpexc = fmrx(fpexc);
	if (fpexc & VFPEXC_EN) {
		fmxr(fpexc, fpexc & ~(VFPEXC_EX | VFPEXC_FP2V));
		critical_exit();
		if (fpexc & VFPEXC_EX) {
			ksiginfo_init_trap(&ksi);
			ksi.ksi_signo = SIGFPE;
			if (fpexc & VFPEXC_UFC)
				ksi.ksi_code = FPE_FLTUND;
			else if (fpexc & VFPEXC_OFC)
				ksi.ksi_code = FPE_FLTOVF;
			else if (fpexc & VFPEXC_IOC)
				ksi.ksi_code = FPE_FLTINV;
			ksi.ksi_addr = (void *)addr;
			trapsignal(curthread, &ksi);
			return 0;
		}
		return 1;
	}
	fmxr(fpexc, fpexc | VFPEXC_EN);
	curpcb = curthread->td_pcb;
	cpu = PCPU_GET(cpuid);
	if (curpcb->pcb_vfpcpu != cpu || curthread != PCPU_GET(fpcurthread)) {
		vfp_restore(&curpcb->pcb_vfpstate);
		curpcb->pcb_vfpcpu = cpu;
		PCPU_SET(fpcurthread, curthread);
	}
	critical_exit();
	return (0);
}
static int vfp_bounce ( u_int addr , u_int insn , struct trapframe * frame , int code ) { u_int cpu , fpexc ; struct pcb * curpcb ; ksiginfo_t ksi ; if ( ( code & FAULT_USER ) == 0 ) panic ( " " ) ; critical_enter ( ) ; fpexc = fmrx ( fpexc ) ; if ( fpexc & VFPEXC_EN ) { fmxr ( fpexc , fpexc & ~ ( VFPEXC_EX | VFPEXC_FP2V ) ) ; critical_exit ( ) ; if ( fpexc & VFPEXC_EX ) { ksiginfo_init_trap ( & ksi ) ; ksi . ksi_signo = SIGFPE ; if ( fpexc & VFPEXC_UFC ) ksi . ksi_code = FPE_FLTUND ; else if ( fpexc & VFPEXC_OFC ) ksi . ksi_code = FPE_FLTOVF ; else if ( fpexc & VFPEXC_IOC ) ksi . ksi_code = FPE_FLTINV ; ksi . ksi_addr = ( void * ) addr ; trapsignal ( curthread , & ksi ) ; return 0 ; } return 1 ; } fmxr ( fpexc , fpexc | VFPEXC_EN ) ; curpcb = curthread -> td_pcb ; cpu = PCPU_GET ( cpuid ) ; if ( curpcb -> pcb_vfpcpu != cpu || curthread != PCPU_GET ( fpcurthread ) ) { vfp_restore ( & curpcb -> pcb_vfpstate ) ; curpcb -> pcb_vfpcpu = cpu ; PCPU_SET ( fpcurthread , curthread ) ; } critical_exit ( ) ; return ( 0 ) ; }
start VFP unit, restore the vfp registers from the PCB  and retry
 the instruction
start VFP unit restore the vfp registers from the PCB and retry the instruction
/*
	 * If the VFP is already on and we got an undefined instruction, then
	 * something tried to executate a truly invalid instruction that maps to
	 * the VFP.
	 */ /* Clear any exceptions */ /* kill the process - we do not handle emulation */ /* We have an exception, signal a SIGFPE */ /*
	 * If the last time this thread used the VFP it was on this core, and
	 * the last thread to use the VFP on this core was this thread, then the
	 * VFP state is valid, otherwise restore this thread's state to the VFP.
	 */