static inline int restore_fpu_state()

in kernel/signal.c [255:329]


static inline int restore_fpu_state(struct sigcontext *sc)
{
	int err = 1;

	if (FPU_IS_EMU) {
	    /* restore registers */
	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
	    return 0;
	}

	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
	    /* Verify the frame format.  */
	    if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
		 (sc->sc_fpstate[0] != fpu_version))
		goto out;
	    if (CPU_IS_020_OR_030) {
		if (m68k_fputype & FPU_68881 &&
		    !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
		    goto out;
		if (m68k_fputype & FPU_68882 &&
		    !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
		    goto out;
	    } else if (CPU_IS_040) {
		if (!(sc->sc_fpstate[1] == 0x00 ||
                      sc->sc_fpstate[1] == 0x28 ||
                      sc->sc_fpstate[1] == 0x60))
		    goto out;
	    } else if (CPU_IS_060) {
		if (!(sc->sc_fpstate[3] == 0x00 ||
                      sc->sc_fpstate[3] == 0x60 ||
		      sc->sc_fpstate[3] == 0xe0))
		    goto out;
	    } else if (CPU_IS_COLDFIRE) {
		if (!(sc->sc_fpstate[0] == 0x00 ||
		      sc->sc_fpstate[0] == 0x05 ||
		      sc->sc_fpstate[0] == 0xe5))
		    goto out;
	    } else
		goto out;

	    if (CPU_IS_COLDFIRE) {
		__asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
				  "fmovel %1,%%fpcr\n\t"
				  "fmovel %2,%%fpsr\n\t"
				  "fmovel %3,%%fpiar"
				  : /* no outputs */
				  : "m" (sc->sc_fpregs[0]),
				    "m" (sc->sc_fpcntl[0]),
				    "m" (sc->sc_fpcntl[1]),
				    "m" (sc->sc_fpcntl[2]));
	    } else {
		__asm__ volatile (".chip 68k/68881\n\t"
				  "fmovemx %0,%%fp0-%%fp1\n\t"
				  "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
				  ".chip 68k"
				  : /* no outputs */
				  : "m" (*sc->sc_fpregs),
				    "m" (*sc->sc_fpcntl));
	    }
	}

	if (CPU_IS_COLDFIRE) {
		__asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
	} else {
		__asm__ volatile (".chip 68k/68881\n\t"
				  "frestore %0\n\t"
				  ".chip 68k"
				  : : "m" (*sc->sc_fpstate));
	}
	err = 0;

out:
	return err;
}