--- zzzz-none-000/linux-3.10.107/arch/mips/math-emu/kernel_linkage.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/mips/math-emu/kernel_linkage.c 2021-11-10 11:53:54.000000000 +0000 @@ -27,7 +27,21 @@ #include #include -#define SIGNALLING_NAN 0x7ff800007ff80000LL +#define SIGNALLING_NAN 0x7ff800007ff80000LL +#define SIGNALLING_NAN2008 0x7ff000007fa00000LL + +extern unsigned int fpu_fcr31 __read_mostly; +extern unsigned int system_has_fpu __read_mostly; +static int nan2008 __read_mostly = -1; + +static int __init setup_nan2008(char *str) +{ + get_option (&str, &nan2008); + + return 1; +} + +__setup("nan2008=", setup_nan2008); void fpu_emulator_init_fpu(void) { @@ -39,10 +53,28 @@ printk("Algorithmics/MIPS FPU Emulator v1.5\n"); } - current->thread.fpu.fcr31 = 0; - for (i = 0; i < 32; i++) { - current->thread.fpu.fpr[i] = SIGNALLING_NAN; + if (system_has_fpu) + current->thread.fpu.fcr31 = fpu_fcr31; + else if (nan2008 < 0) { + if (!test_thread_flag(TIF_32BIT_REGS)) + current->thread.fpu.fcr31 = FPU_CSR_DEFAULT|FPU_CSR_MAC2008|FPU_CSR_ABS2008|FPU_CSR_NAN2008; + else + current->thread.fpu.fcr31 = FPU_CSR_DEFAULT; + } else { + if (nan2008) + current->thread.fpu.fcr31 = FPU_CSR_DEFAULT|FPU_CSR_MAC2008|FPU_CSR_ABS2008|FPU_CSR_NAN2008; + else + current->thread.fpu.fcr31 = FPU_CSR_DEFAULT; } + + if (current->thread.fpu.fcr31 & FPU_CSR_NAN2008) + for (i = 0; i < 32; i++) { + current->thread.fpu.fpr[i] = SIGNALLING_NAN2008; + } + else + for (i = 0; i < 32; i++) { + current->thread.fpu.fpr[i] = SIGNALLING_NAN; + } } @@ -90,6 +122,17 @@ int i; int err = 0; + if (!test_thread_flag(TIF_32BIT_REGS)) { + for (i = 0; i < 32; i++) { + err |= + __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]); + } + err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr); + + return err; + + } + for (i = 0; i < 32; i+=2) { err |= __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]); @@ -104,6 +147,16 @@ int i; int err = 0; + if (!test_thread_flag(TIF_32BIT_REGS)) { + for (i = 0; i < 32; i++) { + err |= + __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]); + } + err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr); + + return err; + } + for (i = 0; i < 32; i+=2) { err |= __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);