blob: d7709c06fac46c11b8d3fde9204aea6d1ea74517 [file] [log] [blame]
Paul Mundt332fd572007-11-22 17:30:50 +09001#ifndef __ASM_SH_FPU_H
2#define __ASM_SH_FPU_H
3
Paul Mundt332fd572007-11-22 17:30:50 +09004#ifndef __ASSEMBLY__
Paul Mundt9bbafce2008-03-26 19:02:47 +09005#include <linux/preempt.h>
Paul Mundt332fd572007-11-22 17:30:50 +09006#include <asm/ptrace.h>
7
8#ifdef CONFIG_SH_FPU
9static inline void release_fpu(struct pt_regs *regs)
10{
11 regs->sr |= SR_FD;
12}
13
14static inline void grab_fpu(struct pt_regs *regs)
15{
16 regs->sr &= ~SR_FD;
17}
18
19struct task_struct;
20
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010021extern void save_fpu(struct task_struct *__tsk);
Giuseppe CAVALLAROa0458b02009-07-07 16:25:10 +020022void fpu_state_restore(struct pt_regs *regs);
Paul Mundt332fd572007-11-22 17:30:50 +090023#else
Paul Mundt138bed12008-03-26 19:09:21 +090024
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010025#define save_fpu(tsk) do { } while (0)
Paul Mundt332fd572007-11-22 17:30:50 +090026#define release_fpu(regs) do { } while (0)
27#define grab_fpu(regs) do { } while (0)
Paul Mundt138bed12008-03-26 19:09:21 +090028
Paul Mundt332fd572007-11-22 17:30:50 +090029#endif
30
Paul Mundte7ab3cd2008-09-21 19:04:55 +090031struct user_regset;
32
Paul Mundt74d99a52007-11-26 20:38:36 +090033extern int do_fpu_inst(unsigned short, struct pt_regs *);
34
Paul Mundte7ab3cd2008-09-21 19:04:55 +090035extern int fpregs_get(struct task_struct *target,
36 const struct user_regset *regset,
37 unsigned int pos, unsigned int count,
38 void *kbuf, void __user *ubuf);
39
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010040static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
41{
42 if (task_thread_info(tsk)->status & TS_USEDFPU) {
43 task_thread_info(tsk)->status &= ~TS_USEDFPU;
44 save_fpu(tsk);
45 release_fpu(regs);
46 } else
47 tsk->fpu_counter = 0;
48}
49
Paul Mundt9bbafce2008-03-26 19:02:47 +090050static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
51{
52 preempt_disable();
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010053 __unlazy_fpu(tsk, regs);
Paul Mundt9bbafce2008-03-26 19:02:47 +090054 preempt_enable();
55}
Paul Mundt332fd572007-11-22 17:30:50 +090056
Paul Mundt9bbafce2008-03-26 19:02:47 +090057static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
58{
59 preempt_disable();
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010060 if (task_thread_info(tsk)->status & TS_USEDFPU) {
61 task_thread_info(tsk)->status &= ~TS_USEDFPU;
Paul Mundt9bbafce2008-03-26 19:02:47 +090062 release_fpu(regs);
63 }
64 preempt_enable();
65}
Paul Mundt332fd572007-11-22 17:30:50 +090066
Paul Mundte7ab3cd2008-09-21 19:04:55 +090067static inline int init_fpu(struct task_struct *tsk)
68{
69 if (tsk_used_math(tsk)) {
70 if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
71 unlazy_fpu(tsk, task_pt_regs(tsk));
72 return 0;
73 }
74
75 set_stopped_child_used_math(tsk);
76 return 0;
77}
78
Paul Mundt332fd572007-11-22 17:30:50 +090079#endif /* __ASSEMBLY__ */
80
81#endif /* __ASM_SH_FPU_H */