patch-2.3.99-pre8 linux/arch/s390/kernel/s390fpu.c
Next file: linux/arch/s390/kernel/s390io.c
Previous file: linux/arch/s390/kernel/s390dyn.c
Back to the patch index
Back to the overall index
- Lines: 148
- Date:
Fri May 12 11:41:45 2000
- Orig file:
v2.3.99-pre7/linux/arch/s390/kernel/s390fpu.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.3.99-pre7/linux/arch/s390/kernel/s390fpu.c linux/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 ([email protected],[email protected])
+ *
+ * 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
+}
+
+
+
+
+
+
+
+
+
+
+
+
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])