0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/sched.h>
0009 #include <asm/fpu.h>
0010
0011 #ifdef CONFIG_ISA_ARCOMPACT
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
0033 {
0034 unsigned int *saveto = &prev->thread.fpu.aux_dpfp[0].l;
0035 unsigned int *readfrom = &next->thread.fpu.aux_dpfp[0].l;
0036
0037 const unsigned int zero = 0;
0038
0039 __asm__ __volatile__(
0040 "daddh11 %0, %2, %2\n"
0041 "dexcl1 %1, %3, %4\n"
0042 : "=&r" (*(saveto + 1)),
0043 "=&r" (*(saveto))
0044 : "r" (zero), "r" (*(readfrom + 1)), "r" (*(readfrom))
0045 );
0046
0047 __asm__ __volatile__(
0048 "daddh22 %0, %2, %2\n"
0049 "dexcl2 %1, %3, %4\n"
0050 : "=&r"(*(saveto + 3)),
0051 "=&r"(*(saveto + 2))
0052 : "r" (zero), "r" (*(readfrom + 3)), "r" (*(readfrom + 2))
0053 );
0054 }
0055
0056 #else
0057
0058 void fpu_init_task(struct pt_regs *regs)
0059 {
0060 const unsigned int fwe = 0x80000000;
0061
0062
0063 write_aux_reg(ARC_REG_FPU_CTRL, 0x100);
0064
0065
0066 write_aux_reg(ARC_REG_FPU_STATUS, fwe);
0067 }
0068
0069 void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
0070 {
0071 struct arc_fpu *save = &prev->thread.fpu;
0072 struct arc_fpu *restore = &next->thread.fpu;
0073 const unsigned int fwe = 0x80000000;
0074
0075 save->ctrl = read_aux_reg(ARC_REG_FPU_CTRL);
0076 save->status = read_aux_reg(ARC_REG_FPU_STATUS);
0077
0078 write_aux_reg(ARC_REG_FPU_CTRL, restore->ctrl);
0079 write_aux_reg(ARC_REG_FPU_STATUS, (fwe | restore->status));
0080 }
0081
0082 #endif