sh: Bring the SH-5 FPU in line with the SH-4 FPU API.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
b6d7b66609
commit
332fd57b92
|
@ -30,12 +30,12 @@
|
||||||
|
|
||||||
static union sh_fpu_union init_fpuregs = {
|
static union sh_fpu_union init_fpuregs = {
|
||||||
.hard = {
|
.hard = {
|
||||||
.fp_regs = { [0 ... 63] = sNAN32 },
|
.fp_regs = { [0 ... 63] = sNAN32 },
|
||||||
.fpscr = FPSCR_INIT
|
.fpscr = FPSCR_INIT
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void fpsave(struct sh_fpu_hard_struct *fpregs)
|
void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
asm volatile("fst.p %0, (0*8), fp0\n\t"
|
asm volatile("fst.p %0, (0*8), fp0\n\t"
|
||||||
"fst.p %0, (1*8), fp2\n\t"
|
"fst.p %0, (1*8), fp2\n\t"
|
||||||
|
@ -73,11 +73,10 @@ inline void fpsave(struct sh_fpu_hard_struct *fpregs)
|
||||||
"fgetscr fr63\n\t"
|
"fgetscr fr63\n\t"
|
||||||
"fst.s %0, (32*8), fr63\n\t"
|
"fst.s %0, (32*8), fr63\n\t"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: "r" (fpregs)
|
: "r" (&tsk->thread.fpu.hard)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fpload(struct sh_fpu_hard_struct *fpregs)
|
fpload(struct sh_fpu_hard_struct *fpregs)
|
||||||
{
|
{
|
||||||
|
@ -153,10 +152,10 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
if (last_task_used_math != NULL) {
|
if (last_task_used_math != NULL)
|
||||||
/* Other processes fpu state, save away */
|
/* Other processes fpu state, save away */
|
||||||
fpsave(&last_task_used_math->thread.fpu.hard);
|
save_fpu(last_task_used_math, regs);
|
||||||
}
|
|
||||||
last_task_used_math = current;
|
last_task_used_math = current;
|
||||||
if (used_math()) {
|
if (used_math()) {
|
||||||
fpload(¤t->thread.fpu.hard);
|
fpload(¤t->thread.fpu.hard);
|
||||||
|
@ -167,4 +166,3 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
|
||||||
if (fpvalid) {
|
if (fpvalid) {
|
||||||
if (current == last_task_used_math) {
|
if (current == last_task_used_math) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(&tsk->thread.fpu.hard);
|
save_fpu(tsk, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = 0;
|
last_task_used_math = 0;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
@ -507,7 +507,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
|
||||||
#ifdef CONFIG_SH_FPU
|
#ifdef CONFIG_SH_FPU
|
||||||
if(last_task_used_math == current) {
|
if(last_task_used_math == current) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(¤t->thread.fpu.hard);
|
save_fpu(current, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = NULL;
|
last_task_used_math = NULL;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
|
|
@ -75,7 +75,7 @@ get_fpu_long(struct task_struct *task, unsigned long addr)
|
||||||
|
|
||||||
if (last_task_used_math == task) {
|
if (last_task_used_math == task) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(&task->thread.fpu.hard);
|
save_fpu(task, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = 0;
|
last_task_used_math = 0;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
@ -111,7 +111,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
|
||||||
set_stopped_child_used_math(task);
|
set_stopped_child_used_math(task);
|
||||||
} else if (last_task_used_math == task) {
|
} else if (last_task_used_math == task) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(&task->thread.fpu.hard);
|
save_fpu(task, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = 0;
|
last_task_used_math = 0;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
|
|
@ -212,7 +212,7 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
|
|
||||||
if (current == last_task_used_math) {
|
if (current == last_task_used_math) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(¤t->thread.fpu.hard);
|
save_fpu(current, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = NULL;
|
last_task_used_math = NULL;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
|
|
@ -618,7 +618,7 @@ static int misaligned_fpu_load(struct pt_regs *regs,
|
||||||
indexed by register number. */
|
indexed by register number. */
|
||||||
if (last_task_used_math == current) {
|
if (last_task_used_math == current) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(¤t->thread.fpu.hard);
|
save_fpu(current, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = NULL;
|
last_task_used_math = NULL;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
@ -691,7 +691,7 @@ static int misaligned_fpu_store(struct pt_regs *regs,
|
||||||
indexed by register number. */
|
indexed by register number. */
|
||||||
if (last_task_used_math == current) {
|
if (last_task_used_math == current) {
|
||||||
enable_fpu();
|
enable_fpu();
|
||||||
fpsave(¤t->thread.fpu.hard);
|
save_fpu(current, regs);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = NULL;
|
last_task_used_math = NULL;
|
||||||
regs->sr |= SR_FD;
|
regs->sr |= SR_FD;
|
||||||
|
|
44
include/asm-sh/fpu.h
Normal file
44
include/asm-sh/fpu.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef __ASM_SH_FPU_H
|
||||||
|
#define __ASM_SH_FPU_H
|
||||||
|
|
||||||
|
#define SR_FD 0x00008000
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SH_FPU
|
||||||
|
static inline void release_fpu(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
regs->sr |= SR_FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void grab_fpu(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
regs->sr &= ~SR_FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct task_struct;
|
||||||
|
|
||||||
|
extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
|
||||||
|
#else
|
||||||
|
#define release_fpu(regs) do { } while (0)
|
||||||
|
#define grab_fpu(regs) do { } while (0)
|
||||||
|
#define save_fpu(tsk, regs) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define unlazy_fpu(tsk, regs) do { \
|
||||||
|
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \
|
||||||
|
save_fpu(tsk, regs); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define clear_fpu(tsk, regs) do { \
|
||||||
|
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \
|
||||||
|
clear_tsk_thread_flag(tsk, TIF_USEDFPU); \
|
||||||
|
release_fpu(regs); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* __ASM_SH_FPU_H */
|
|
@ -2,9 +2,9 @@
|
||||||
#define __ASM_SH_PROCESSOR_H
|
#define __ASM_SH_PROCESSOR_H
|
||||||
|
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
|
#include <asm/fpu.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU type and hardware bug flags. Kept separately for each CPU.
|
* CPU type and hardware bug flags. Kept separately for each CPU.
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,7 +65,6 @@ extern struct sh_cpuinfo cpu_data[];
|
||||||
* IMASK-bit:
|
* IMASK-bit:
|
||||||
* Interrupt level mask
|
* Interrupt level mask
|
||||||
*/
|
*/
|
||||||
#define SR_FD 0x00008000
|
|
||||||
#define SR_DSP 0x00001000
|
#define SR_DSP 0x00001000
|
||||||
#define SR_IMASK 0x000000f0
|
#define SR_IMASK 0x000000f0
|
||||||
|
|
||||||
|
@ -178,31 +177,6 @@ static __inline__ void enable_fpu(void)
|
||||||
: "r" (~SR_FD));
|
: "r" (~SR_FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void release_fpu(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ void grab_fpu(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
regs->sr &= ~SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
|
|
||||||
|
|
||||||
#define unlazy_fpu(tsk, regs) do { \
|
|
||||||
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \
|
|
||||||
save_fpu(tsk, regs); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define clear_fpu(tsk, regs) do { \
|
|
||||||
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \
|
|
||||||
clear_tsk_thread_flag(tsk, TIF_USEDFPU); \
|
|
||||||
release_fpu(regs); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Double presision, NANS as NANS, rounding to nearest, no exceptions */
|
/* Double presision, NANS as NANS, rounding to nearest, no exceptions */
|
||||||
#define FPSCR_INIT 0x00080000
|
#define FPSCR_INIT 0x00080000
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,6 @@ extern struct sh_cpuinfo cpu_data[];
|
||||||
* Single step bit
|
* Single step bit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define SR_FD 0x00008000
|
|
||||||
|
|
||||||
#if defined(CONFIG_SH64_SR_WATCH)
|
#if defined(CONFIG_SH64_SR_WATCH)
|
||||||
#define SR_MMU 0x84000000
|
#define SR_MMU 0x84000000
|
||||||
#else
|
#else
|
||||||
|
@ -243,16 +241,6 @@ static inline void enable_fpu(void)
|
||||||
: "r" (~SR_FD));
|
: "r" (~SR_FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void release_fpu(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void grab_fpu(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
regs->sr &= ~SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round to nearest, no exceptions on inexact, overflow, underflow,
|
/* Round to nearest, no exceptions on inexact, overflow, underflow,
|
||||||
zero-divide, invalid. Configure option for whether to flush denorms to
|
zero-divide, invalid. Configure option for whether to flush denorms to
|
||||||
zero, or except if a denorm is encountered. */
|
zero, or except if a denorm is encountered. */
|
||||||
|
@ -263,13 +251,9 @@ static inline void grab_fpu(struct pt_regs *regs)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
#ifdef CONFIG_SH_FPU
|
||||||
/* Save the current FP regs */
|
|
||||||
void fpsave(struct sh_fpu_hard_struct *fpregs);
|
|
||||||
|
|
||||||
/* Initialise the FP state of a task */
|
/* Initialise the FP state of a task */
|
||||||
void fpinit(struct sh_fpu_hard_struct *fpregs);
|
void fpinit(struct sh_fpu_hard_struct *fpregs);
|
||||||
#else
|
#else
|
||||||
#define fpsave(fpregs) do { } while (0)
|
|
||||||
#define fpinit(fpregs) do { } while (0)
|
#define fpinit(fpregs) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue