arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / kvm / fpu.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *  FPU helper code to use FPU operations from inside the kernel
4  *
5  *    Copyright (C) 2010 Alexander Graf (agraf@suse.de)
6  */
7
8 #include <linux/pgtable.h>
9 #include <linux/linkage.h>
10
11 #include <asm/reg.h>
12 #include <asm/page.h>
13 #include <asm/mmu.h>
14 #include <asm/cputable.h>
15 #include <asm/cache.h>
16 #include <asm/thread_info.h>
17 #include <asm/ppc_asm.h>
18 #include <asm/asm-offsets.h>
19
20 /* Instructions operating on single parameters */
21
22 /*
23  * Single operation with one input operand
24  *
25  * R3 = (double*)&fpscr
26  * R4 = (short*)&result
27  * R5 = (short*)&param1
28  */
29 #define FPS_ONE_IN(name)                                        \
30 _GLOBAL(fps_ ## name);                                                  \
31         lfd     0,0(r3);                /* load up fpscr value */       \
32         MTFSF_L(0);                                                     \
33         lfs     0,0(r5);                                                \
34                                                                         \
35         name    0,0;                                                    \
36                                                                         \
37         stfs    0,0(r4);                                                \
38         mffs    0;                                                      \
39         stfd    0,0(r3);        /* save new fpscr value */      \
40         blr
41
42 /*
43  * Single operation with two input operands
44  *
45  * R3 = (double*)&fpscr
46  * R4 = (short*)&result
47  * R5 = (short*)&param1
48  * R6 = (short*)&param2
49  */
50 #define FPS_TWO_IN(name)                                        \
51 _GLOBAL(fps_ ## name);                                                  \
52         lfd     0,0(r3);                /* load up fpscr value */       \
53         MTFSF_L(0);                                                     \
54         lfs     0,0(r5);                                                \
55         lfs     1,0(r6);                                                \
56                                                                         \
57         name    0,0,1;                                                  \
58                                                                         \
59         stfs    0,0(r4);                                                \
60         mffs    0;                                                      \
61         stfd    0,0(r3);                /* save new fpscr value */      \
62         blr
63
64 /*
65  * Single operation with three input operands
66  *
67  * R3 = (double*)&fpscr
68  * R4 = (short*)&result
69  * R5 = (short*)&param1
70  * R6 = (short*)&param2
71  * R7 = (short*)&param3
72  */
73 #define FPS_THREE_IN(name)                                      \
74 _GLOBAL(fps_ ## name);                                                  \
75         lfd     0,0(r3);                /* load up fpscr value */       \
76         MTFSF_L(0);                                                     \
77         lfs     0,0(r5);                                                \
78         lfs     1,0(r6);                                                \
79         lfs     2,0(r7);                                                \
80                                                                         \
81         name    0,0,1,2;                                                \
82                                                                         \
83         stfs    0,0(r4);                                                \
84         mffs    0;                                                      \
85         stfd    0,0(r3);                /* save new fpscr value */      \
86         blr
87
88 FPS_ONE_IN(fres)
89 FPS_ONE_IN(frsqrte)
90 FPS_ONE_IN(fsqrts)
91 FPS_TWO_IN(fadds)
92 FPS_TWO_IN(fdivs)
93 FPS_TWO_IN(fmuls)
94 FPS_TWO_IN(fsubs)
95 FPS_THREE_IN(fmadds)
96 FPS_THREE_IN(fmsubs)
97 FPS_THREE_IN(fnmadds)
98 FPS_THREE_IN(fnmsubs)
99 FPS_THREE_IN(fsel)
100
101
102 /* Instructions operating on double parameters */
103
104 /*
105  * Beginning of double instruction processing
106  *
107  * R3 = (double*)&fpscr
108  * R4 = (u32*)&cr
109  * R5 = (double*)&result
110  * R6 = (double*)&param1
111  * R7 = (double*)&param2 [load_two]
112  * R8 = (double*)&param3 [load_three]
113  * LR = instruction call function
114  */
115 SYM_FUNC_START_LOCAL(fpd_load_three)
116         lfd     2,0(r8)                 /* load param3 */
117 SYM_FUNC_START_LOCAL(fpd_load_two)
118         lfd     1,0(r7)                 /* load param2 */
119 SYM_FUNC_START_LOCAL(fpd_load_one)
120         lfd     0,0(r6)                 /* load param1 */
121 SYM_FUNC_START_LOCAL(fpd_load_none)
122         lfd     3,0(r3)                 /* load up fpscr value */
123         MTFSF_L(3)
124         lwz     r6, 0(r4)               /* load cr */
125         mtcr    r6
126         blr
127 SYM_FUNC_END(fpd_load_none)
128 SYM_FUNC_END(fpd_load_one)
129 SYM_FUNC_END(fpd_load_two)
130 SYM_FUNC_END(fpd_load_three)
131
132 /*
133  * End of double instruction processing
134  *
135  * R3 = (double*)&fpscr
136  * R4 = (u32*)&cr
137  * R5 = (double*)&result
138  * LR = caller of instruction call function
139  */
140 SYM_FUNC_START_LOCAL(fpd_return)
141         mfcr    r6
142         stfd    0,0(r5)                 /* save result */
143         mffs    0
144         stfd    0,0(r3)                 /* save new fpscr value */
145         stw     r6,0(r4)                /* save new cr value */
146         blr
147 SYM_FUNC_END(fpd_return)
148
149 /*
150  * Double operation with no input operand
151  *
152  * R3 = (double*)&fpscr
153  * R4 = (u32*)&cr
154  * R5 = (double*)&result
155  */
156 #define FPD_NONE_IN(name)                                               \
157 _GLOBAL(fpd_ ## name);                                                  \
158         mflr    r12;                                                    \
159         bl      fpd_load_none;                                          \
160         mtlr    r12;                                                    \
161                                                                         \
162         name.   0;                      /* call instruction */          \
163         b       fpd_return
164
165 /*
166  * Double operation with one input operand
167  *
168  * R3 = (double*)&fpscr
169  * R4 = (u32*)&cr
170  * R5 = (double*)&result
171  * R6 = (double*)&param1
172  */
173 #define FPD_ONE_IN(name)                                                \
174 _GLOBAL(fpd_ ## name);                                                  \
175         mflr    r12;                                                    \
176         bl      fpd_load_one;                                           \
177         mtlr    r12;                                                    \
178                                                                         \
179         name.   0,0;                    /* call instruction */          \
180         b       fpd_return
181
182 /*
183  * Double operation with two input operands
184  *
185  * R3 = (double*)&fpscr
186  * R4 = (u32*)&cr
187  * R5 = (double*)&result
188  * R6 = (double*)&param1
189  * R7 = (double*)&param2
190  * R8 = (double*)&param3
191  */
192 #define FPD_TWO_IN(name)                                                \
193 _GLOBAL(fpd_ ## name);                                                  \
194         mflr    r12;                                                    \
195         bl      fpd_load_two;                                           \
196         mtlr    r12;                                                    \
197                                                                         \
198         name.   0,0,1;                  /* call instruction */          \
199         b       fpd_return
200
201 /*
202  * CR Double operation with two input operands
203  *
204  * R3 = (double*)&fpscr
205  * R4 = (u32*)&cr
206  * R5 = (double*)&param1
207  * R6 = (double*)&param2
208  * R7 = (double*)&param3
209  */
210 #define FPD_TWO_IN_CR(name)                                             \
211 _GLOBAL(fpd_ ## name);                                                  \
212         lfd     1,0(r6);                /* load param2 */               \
213         lfd     0,0(r5);                /* load param1 */               \
214         lfd     3,0(r3);                /* load up fpscr value */       \
215         MTFSF_L(3);                                                     \
216         lwz     r6, 0(r4);              /* load cr */                   \
217         mtcr    r6;                                                     \
218                                                                         \
219         name    0,0,1;                  /* call instruction */          \
220         mfcr    r6;                                                     \
221         mffs    0;                                                      \
222         stfd    0,0(r3);                /* save new fpscr value */      \
223         stw     r6,0(r4);               /* save new cr value */         \
224         blr
225
226 /*
227  * Double operation with three input operands
228  *
229  * R3 = (double*)&fpscr
230  * R4 = (u32*)&cr
231  * R5 = (double*)&result
232  * R6 = (double*)&param1
233  * R7 = (double*)&param2
234  * R8 = (double*)&param3
235  */
236 #define FPD_THREE_IN(name)                                              \
237 _GLOBAL(fpd_ ## name);                                                  \
238         mflr    r12;                                                    \
239         bl      fpd_load_three;                                         \
240         mtlr    r12;                                                    \
241                                                                         \
242         name.   0,0,1,2;                /* call instruction */          \
243         b       fpd_return
244
245 FPD_ONE_IN(fsqrts)
246 FPD_ONE_IN(frsqrtes)
247 FPD_ONE_IN(fres)
248 FPD_ONE_IN(frsp)
249 FPD_ONE_IN(fctiw)
250 FPD_ONE_IN(fctiwz)
251 FPD_ONE_IN(fsqrt)
252 FPD_ONE_IN(fre)
253 FPD_ONE_IN(frsqrte)
254 FPD_ONE_IN(fneg)
255 FPD_ONE_IN(fabs)
256 FPD_TWO_IN(fadds)
257 FPD_TWO_IN(fsubs)
258 FPD_TWO_IN(fdivs)
259 FPD_TWO_IN(fmuls)
260 FPD_TWO_IN_CR(fcmpu)
261 FPD_TWO_IN(fcpsgn)
262 FPD_TWO_IN(fdiv)
263 FPD_TWO_IN(fadd)
264 FPD_TWO_IN(fmul)
265 FPD_TWO_IN_CR(fcmpo)
266 FPD_TWO_IN(fsub)
267 FPD_THREE_IN(fmsubs)
268 FPD_THREE_IN(fmadds)
269 FPD_THREE_IN(fnmsubs)
270 FPD_THREE_IN(fnmadds)
271 FPD_THREE_IN(fsel)
272 FPD_THREE_IN(fmsub)
273 FPD_THREE_IN(fmadd)
274 FPD_THREE_IN(fnmsub)
275 FPD_THREE_IN(fnmadd)
276
277 _GLOBAL(kvm_cvt_fd)
278         lfs     0,0(r3)
279         stfd    0,0(r4)
280         blr
281
282 _GLOBAL(kvm_cvt_df)
283         lfd     0,0(r3)
284         stfs    0,0(r4)
285         blr