diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 23:48:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 23:48:34 +0000 |
commit | 7fd36ebeeec9244a7431bb010e6e3c5e4848a0d5 (patch) | |
tree | 5fb03a9aafdd1cec5f4f6ff7f1873174cb89b66c /arch/s390/kernel/s390fpu.c | |
parent | ba2dacab305c598cd4c34a604f8e276bf5bab5ff (diff) |
Merge with Linux 2.3.99-pre8. Linus must hate me, too man patches ;-)
Diffstat (limited to 'arch/s390/kernel/s390fpu.c')
-rw-r--r-- | arch/s390/kernel/s390fpu.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/arch/s390/kernel/s390fpu.c b/arch/s390/kernel/s390fpu.c new file mode 100644 index 000000000..42048abbc --- /dev/null +++ b/arch/s390/kernel/s390fpu.c @@ -0,0 +1,147 @@ +/* + * arch/s390/kernel/s390fpu.c + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + * + * s390fpu.h functions for saving & restoring the fpu state. + * + * I couldn't inline these as linux/sched.h included half the world + * & was required to at the task structure. + * & the functions were too complex to make macros from. + * ( & as usual I didn't feel like debugging inline code ). + */ + +#include <linux/config.h> +#include <linux/sched.h> + +int save_fp_regs1(s390_fp_regs *fpregs) +{ + int has_ieee=MACHINE_HAS_IEEE; +/* + I don't think we can use STE here as this would load + fp registers 0 & 2 into memory locations 0 & 1 etc. + */ + asm volatile ("STD 0,8(%0)\n\t" + "STD 2,24(%0)\n\t" + "STD 4,40(%0)\n\t" + "STD 6,56(%0)" + : + : "a" (fpregs) + : "memory" + ); + if(has_ieee) + { + asm volatile ("STFPC 0(%0)\n\t" + "STD 1,16(%0)\n\t" + "STD 3,32(%0)\n\t" + "STD 5,48(%0)\n\t" + "STD 7,64(%0)\n\t" + "STD 8,72(%0)\n\t" + "STD 9,80(%0)\n\t" + "STD 10,88(%0)\n\t" + "STD 11,96(%0)\n\t" + "STD 12,104(%0)\n\t" + "STD 13,112(%0)\n\t" + "STD 14,120(%0)\n\t" + "STD 15,128(%0)\n\t" + : + : "a" (fpregs) + : "memory" + ); + } + return(has_ieee); +} + + +void save_fp_regs(s390_fp_regs *fpregs) +{ +#if CONFIG_IEEEFPU_EMULATION + s390_fp_regs *currentfprs; +#endif +#if CONFIG_IEEEFPU_EMULATION + if(!save_fp_regs1(fpregs)) + { + currentfprs=¤t->thread.fp_regs; + fpregs->fpc=currentfprs->fpc; + fpregs->fprs[1].d=currentfprs->fprs[1].d; + fpregs->fprs[3].d=currentfprs->fprs[3].d; + fpregs->fprs[5].d=currentfprs->fprs[5].d; + fpregs->fprs[7].d=currentfprs->fprs[7].d; + memcpy(&fpregs->fprs[8].d,¤tfprs->fprs[8].d,sizeof(freg_t)*8); + } +#else + save_fp_regs1(fpregs); +#endif +} + + +int restore_fp_regs1(s390_fp_regs *fpregs) +{ + int has_ieee=MACHINE_HAS_IEEE; + + asm volatile ("LD 0,8(%0)\n\t" + "LD 2,24(%0)\n\t" + "LD 4,40(%0)\n\t" + "LD 6,56(%0)" + : + : "a" (fpregs) + : "memory" + ); + if(has_ieee) + { + asm volatile ("LFPC 0(%0)\n\t" + "LD 1,16(%0)\n\t" + "LD 3,32(%0)\n\t" + "LD 5,48(%0)\n\t" + "LD 7,64(%0)\n\t" + "LD 8,72(%0)\n\t" + "LD 9,80(%0)\n\t" + "LD 10,88(%0)\n\t" + "LD 11,96(%0)\n\t" + "LD 12,104(%0)\n\t" + "LD 13,112(%0)\n\t" + "LD 14,120(%0)\n\t" + "LD 15,128(%0)\n\t" + : + : "a" (fpregs) + : "memory" + ); + } + return(has_ieee); +} + +void restore_fp_regs(s390_fp_regs *fpregs) +{ +#if CONFIG_IEEEFPU_EMULATION + s390_fp_regs *currentfprs; +#endif + +#if CONFIG_IEEEFPU_EMULATION + if(!restore_fp_regs1(fpregs)) + { + currentfprs=¤t->thread.fp_regs; + currentfprs->fpc=fpregs->fpc; + currentfprs->fprs[1].d=fpregs->fprs[1].d; + currentfprs->fprs[3].d=fpregs->fprs[3].d; + currentfprs->fprs[5].d=fpregs->fprs[5].d; + currentfprs->fprs[7].d=fpregs->fprs[7].d; + memcpy(¤tfprs->fprs[8].d,&fpregs->fprs[8].d,sizeof(freg_t)*8); + } +#else + restore_fp_regs1(fpregs); +#endif +} + + + + + + + + + + + + |