root/arch/nds32/include/asm/fpu.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. disable_ptreg_fpu
  2. enable_ptreg_fpu
  3. enable_fpu
  4. disable_fpu
  5. lose_fpu
  6. own_fpu
  7. unlazy_fpu
  8. clear_fpu

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /* Copyright (C) 2005-2018 Andes Technology Corporation */
   3 
   4 #ifndef __ASM_NDS32_FPU_H
   5 #define __ASM_NDS32_FPU_H
   6 
   7 #if IS_ENABLED(CONFIG_FPU)
   8 #ifndef __ASSEMBLY__
   9 #include <linux/sched/task_stack.h>
  10 #include <linux/preempt.h>
  11 #include <asm/ptrace.h>
  12 
  13 extern bool has_fpu;
  14 
  15 extern void save_fpu(struct task_struct *__tsk);
  16 extern void load_fpu(const struct fpu_struct *fpregs);
  17 extern bool do_fpu_exception(unsigned int subtype, struct pt_regs *regs);
  18 extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu);
  19 
  20 #define test_tsk_fpu(regs)      (regs->fucop_ctl & FUCOP_CTL_mskCP0EN)
  21 
  22 /*
  23  * Initially load the FPU with signalling NANS.  This bit pattern
  24  * has the property that no matter whether considered as single or as
  25  * double precision, it still represents a signalling NAN.
  26  */
  27 
  28 #define sNAN64    0xFFFFFFFFFFFFFFFFULL
  29 #define sNAN32    0xFFFFFFFFUL
  30 
  31 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
  32 /*
  33  * Denormalized number is unsupported by nds32 FPU. Hence the operation
  34  * is treated as underflow cases when the final result is a denormalized
  35  * number. To enhance precision, underflow exception trap should be
  36  * enabled by default and kerenl will re-execute it by fpu emulator
  37  * when getting underflow exception.
  38  */
  39 #define FPCSR_INIT  (FPCSR_mskUDFE | FPCSR_mskIEXE)
  40 #else
  41 #define FPCSR_INIT  0x0UL
  42 #endif
  43 
  44 extern const struct fpu_struct init_fpuregs;
  45 
  46 static inline void disable_ptreg_fpu(struct pt_regs *regs)
  47 {
  48         regs->fucop_ctl &= ~FUCOP_CTL_mskCP0EN;
  49 }
  50 
  51 static inline void enable_ptreg_fpu(struct pt_regs *regs)
  52 {
  53         regs->fucop_ctl |= FUCOP_CTL_mskCP0EN;
  54 }
  55 
  56 static inline void enable_fpu(void)
  57 {
  58         unsigned long fucop_ctl;
  59 
  60         fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) | FUCOP_CTL_mskCP0EN;
  61         __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL);
  62         __nds32__isb();
  63 }
  64 
  65 static inline void disable_fpu(void)
  66 {
  67         unsigned long fucop_ctl;
  68 
  69         fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) & ~FUCOP_CTL_mskCP0EN;
  70         __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL);
  71         __nds32__isb();
  72 }
  73 
  74 static inline void lose_fpu(void)
  75 {
  76         preempt_disable();
  77 #if IS_ENABLED(CONFIG_LAZY_FPU)
  78         if (last_task_used_math == current) {
  79                 last_task_used_math = NULL;
  80 #else
  81         if (test_tsk_fpu(task_pt_regs(current))) {
  82 #endif
  83                 save_fpu(current);
  84         }
  85         disable_ptreg_fpu(task_pt_regs(current));
  86         preempt_enable();
  87 }
  88 
  89 static inline void own_fpu(void)
  90 {
  91         preempt_disable();
  92 #if IS_ENABLED(CONFIG_LAZY_FPU)
  93         if (last_task_used_math != current) {
  94                 if (last_task_used_math != NULL)
  95                         save_fpu(last_task_used_math);
  96                 load_fpu(&current->thread.fpu);
  97                 last_task_used_math = current;
  98         }
  99 #else
 100         if (!test_tsk_fpu(task_pt_regs(current))) {
 101                 load_fpu(&current->thread.fpu);
 102         }
 103 #endif
 104         enable_ptreg_fpu(task_pt_regs(current));
 105         preempt_enable();
 106 }
 107 
 108 #if !IS_ENABLED(CONFIG_LAZY_FPU)
 109 static inline void unlazy_fpu(struct task_struct *tsk)
 110 {
 111         preempt_disable();
 112         if (test_tsk_fpu(task_pt_regs(tsk)))
 113                 save_fpu(tsk);
 114         preempt_enable();
 115 }
 116 #endif /* !CONFIG_LAZY_FPU */
 117 static inline void clear_fpu(struct pt_regs *regs)
 118 {
 119         preempt_disable();
 120         if (test_tsk_fpu(regs))
 121                 disable_ptreg_fpu(regs);
 122         preempt_enable();
 123 }
 124 #endif /* CONFIG_FPU */
 125 #endif /* __ASSEMBLY__ */
 126 #endif /* __ASM_NDS32_FPU_H */

/* [<][>][^][v][top][bottom][index][help] */