1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/config.h>
17#include <linux/sched.h>
18
19int save_fp_regs1(s390_fp_regs *fpregs)
20{
21 int has_ieee=MACHINE_HAS_IEEE;
22
23
24
25
26 asm volatile ("STD 0,8(%0)\n\t"
27 "STD 2,24(%0)\n\t"
28 "STD 4,40(%0)\n\t"
29 "STD 6,56(%0)"
30 :
31 : "a" (fpregs)
32 : "memory"
33 );
34 if(has_ieee)
35 {
36 asm volatile ("STFPC 0(%0)\n\t"
37 "STD 1,16(%0)\n\t"
38 "STD 3,32(%0)\n\t"
39 "STD 5,48(%0)\n\t"
40 "STD 7,64(%0)\n\t"
41 "STD 8,72(%0)\n\t"
42 "STD 9,80(%0)\n\t"
43 "STD 10,88(%0)\n\t"
44 "STD 11,96(%0)\n\t"
45 "STD 12,104(%0)\n\t"
46 "STD 13,112(%0)\n\t"
47 "STD 14,120(%0)\n\t"
48 "STD 15,128(%0)\n\t"
49 :
50 : "a" (fpregs)
51 : "memory"
52 );
53 }
54 return(has_ieee);
55}
56
57
58void save_fp_regs(s390_fp_regs *fpregs)
59{
60#if CONFIG_MATHEMU
61 s390_fp_regs *currentfprs;
62
63 if(!save_fp_regs1(fpregs))
64 {
65 currentfprs=¤t->thread.fp_regs;
66 fpregs->fpc=currentfprs->fpc;
67 fpregs->fprs[1].d=currentfprs->fprs[1].d;
68 fpregs->fprs[3].d=currentfprs->fprs[3].d;
69 fpregs->fprs[5].d=currentfprs->fprs[5].d;
70 fpregs->fprs[7].d=currentfprs->fprs[7].d;
71 memcpy(&fpregs->fprs[8].d,¤tfprs->fprs[8].d,sizeof(freg_t)*8);
72 }
73#else
74 save_fp_regs1(fpregs);
75#endif
76}
77
78
79int restore_fp_regs1(s390_fp_regs *fpregs)
80{
81 int has_ieee=MACHINE_HAS_IEEE;
82
83
84
85
86
87 fpregs->fpc&=FPC_VALID_MASK;
88 asm volatile ("LD 0,8(%0)\n\t"
89 "LD 2,24(%0)\n\t"
90 "LD 4,40(%0)\n\t"
91 "LD 6,56(%0)"
92 :
93 : "a" (fpregs)
94 : "memory"
95 );
96 if(has_ieee)
97 {
98 asm volatile ("LFPC 0(%0)\n\t"
99 "LD 1,16(%0)\n\t"
100 "LD 3,32(%0)\n\t"
101 "LD 5,48(%0)\n\t"
102 "LD 7,64(%0)\n\t"
103 "LD 8,72(%0)\n\t"
104 "LD 9,80(%0)\n\t"
105 "LD 10,88(%0)\n\t"
106 "LD 11,96(%0)\n\t"
107 "LD 12,104(%0)\n\t"
108 "LD 13,112(%0)\n\t"
109 "LD 14,120(%0)\n\t"
110 "LD 15,128(%0)\n\t"
111 :
112 : "a" (fpregs)
113 : "memory"
114 );
115 }
116 return(has_ieee);
117}
118
119void restore_fp_regs(s390_fp_regs *fpregs)
120{
121#if CONFIG_MATHEMU
122 s390_fp_regs *currentfprs;
123
124 if(!restore_fp_regs1(fpregs))
125 {
126 currentfprs=¤t->thread.fp_regs;
127 currentfprs->fpc=fpregs->fpc;
128 currentfprs->fprs[1].d=fpregs->fprs[1].d;
129 currentfprs->fprs[3].d=fpregs->fprs[3].d;
130 currentfprs->fprs[5].d=fpregs->fprs[5].d;
131 currentfprs->fprs[7].d=fpregs->fprs[7].d;
132 memcpy(¤tfprs->fprs[8].d,&fpregs->fprs[8].d,sizeof(freg_t)*8);
133 }
134#else
135 restore_fp_regs1(fpregs);
136#endif
137}
138
139