blob: fb6bbb9b1cc8e704191f5a6fb73ce001d3c9644f [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 Mundt6ba65382009-11-25 12:07:31 +090028#define fpu_state_restore(regs) do { } while (0)
Paul Mundt138bed12008-03-26 19:09:21 +090029
Paul Mundt332fd572007-11-22 17:30:50 +090030#endif
31
Paul Mundte7ab3cd2008-09-21 19:04:55 +090032struct user_regset;
33
Paul Mundt74d99a52007-11-26 20:38:36 +090034extern int do_fpu_inst(unsigned short, struct pt_regs *);
35
Paul Mundte7ab3cd2008-09-21 19:04:55 +090036extern int fpregs_get(struct task_struct *target,
37 const struct user_regset *regset,
38 unsigned int pos, unsigned int count,
39 void *kbuf, void __user *ubuf);
40
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010041static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
42{
43 if (task_thread_info(tsk)->status & TS_USEDFPU) {
44 task_thread_info(tsk)->status &= ~TS_USEDFPU;
45 save_fpu(tsk);
46 release_fpu(regs);
47 } else
48 tsk->fpu_counter = 0;
49}
50
Paul Mundt9bbafce2008-03-26 19:02:47 +090051static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
52{
53 preempt_disable();
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010054 __unlazy_fpu(tsk, regs);
Paul Mundt9bbafce2008-03-26 19:02:47 +090055 preempt_enable();
56}
Paul Mundt332fd572007-11-22 17:30:50 +090057
Paul Mundt9bbafce2008-03-26 19:02:47 +090058static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
59{
60 preempt_disable();
Stuart Menefyd3ea9fa2009-09-25 18:25:10 +010061 if (task_thread_info(tsk)->status & TS_USEDFPU) {
62 task_thread_info(tsk)->status &= ~TS_USEDFPU;
Paul Mundt9bbafce2008-03-26 19:02:47 +090063 release_fpu(regs);
64 }
65 preempt_enable();
66}
Paul Mundt332fd572007-11-22 17:30:50 +090067
Paul Mundte7ab3cd2008-09-21 19:04:55 +090068static inline int init_fpu(struct task_struct *tsk)
69{
70 if (tsk_used_math(tsk)) {
71 if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
72 unlazy_fpu(tsk, task_pt_regs(tsk));
73 return 0;
74 }
75
76 set_stopped_child_used_math(tsk);
77 return 0;
78}
79
Paul Mundt332fd572007-11-22 17:30:50 +090080#endif /* __ASSEMBLY__ */
81
82#endif /* __ASM_SH_FPU_H */