]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - arch/nds32/include/asm/fpu.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2005-2018 Andes Technology Corporation */
4 #ifndef __ASM_NDS32_FPU_H
5 #define __ASM_NDS32_FPU_H
7 #if IS_ENABLED(CONFIG_FPU)
9 #include <linux/sched/task_stack.h>
10 #include <linux/preempt.h>
11 #include <asm/ptrace.h>
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
);
20 #define test_tsk_fpu(regs) (regs->fucop_ctl & FUCOP_CTL_mskCP0EN)
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.
28 #define sNAN64 0xFFFFFFFFFFFFFFFFULL
29 #define sNAN32 0xFFFFFFFFUL
31 #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
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.
39 #define FPCSR_INIT (FPCSR_mskUDFE | FPCSR_mskIEXE)
41 #define FPCSR_INIT 0x0UL
44 extern const struct fpu_struct init_fpuregs
;
46 static inline void disable_ptreg_fpu(struct pt_regs
*regs
)
48 regs
->fucop_ctl
&= ~FUCOP_CTL_mskCP0EN
;
51 static inline void enable_ptreg_fpu(struct pt_regs
*regs
)
53 regs
->fucop_ctl
|= FUCOP_CTL_mskCP0EN
;
56 static inline void enable_fpu(void)
58 unsigned long fucop_ctl
;
60 fucop_ctl
= __nds32__mfsr(NDS32_SR_FUCOP_CTL
) | FUCOP_CTL_mskCP0EN
;
61 __nds32__mtsr(fucop_ctl
, NDS32_SR_FUCOP_CTL
);
65 static inline void disable_fpu(void)
67 unsigned long fucop_ctl
;
69 fucop_ctl
= __nds32__mfsr(NDS32_SR_FUCOP_CTL
) & ~FUCOP_CTL_mskCP0EN
;
70 __nds32__mtsr(fucop_ctl
, NDS32_SR_FUCOP_CTL
);
74 static inline void lose_fpu(void)
77 #if IS_ENABLED(CONFIG_LAZY_FPU)
78 if (last_task_used_math
== current
) {
79 last_task_used_math
= NULL
;
81 if (test_tsk_fpu(task_pt_regs(current
))) {
85 disable_ptreg_fpu(task_pt_regs(current
));
89 static inline void own_fpu(void)
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(¤t
->thread
.fpu
);
97 last_task_used_math
= current
;
100 if (!test_tsk_fpu(task_pt_regs(current
))) {
101 load_fpu(¤t
->thread
.fpu
);
104 enable_ptreg_fpu(task_pt_regs(current
));
108 #if !IS_ENABLED(CONFIG_LAZY_FPU)
109 static inline void unlazy_fpu(struct task_struct
*tsk
)
112 if (test_tsk_fpu(task_pt_regs(tsk
)))
116 #endif /* !CONFIG_LAZY_FPU */
117 static inline void clear_fpu(struct pt_regs
*regs
)
120 if (test_tsk_fpu(regs
))
121 disable_ptreg_fpu(regs
);
124 #endif /* CONFIG_FPU */
125 #endif /* __ASSEMBLY__ */
126 #endif /* __ASM_NDS32_FPU_H */