File Index
Files and directories
Sign in
FILE

fpu.S

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/kvm/fpu.S 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
 88FPS_ONE_IN(fres)
 89FPS_ONE_IN(frsqrte)
 90FPS_ONE_IN(fsqrts)
 91FPS_TWO_IN(fadds)
 92FPS_TWO_IN(fdivs)
 93FPS_TWO_IN(fmuls)
 94FPS_TWO_IN(fsubs)
 95FPS_THREE_IN(fmadds)
 96FPS_THREE_IN(fmsubs)
 97FPS_THREE_IN(fnmadds)
 98FPS_THREE_IN(fnmsubs)
 99FPS_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 */
115SYM_FUNC_START_LOCAL(fpd_load_three)
116	lfd	2,0(r8)			/* load param3 */
117SYM_FUNC_START_LOCAL(fpd_load_two)
118	lfd	1,0(r7)			/* load param2 */
119SYM_FUNC_START_LOCAL(fpd_load_one)
120	lfd	0,0(r6)			/* load param1 */
121SYM_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
127SYM_FUNC_END(fpd_load_none)
128SYM_FUNC_END(fpd_load_one)
129SYM_FUNC_END(fpd_load_two)
130SYM_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 */
140SYM_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
147SYM_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
245FPD_ONE_IN(fsqrts)
246FPD_ONE_IN(frsqrtes)
247FPD_ONE_IN(fres)
248FPD_ONE_IN(frsp)
249FPD_ONE_IN(fctiw)
250FPD_ONE_IN(fctiwz)
251FPD_ONE_IN(fsqrt)
252FPD_ONE_IN(fre)
253FPD_ONE_IN(frsqrte)
254FPD_ONE_IN(fneg)
255FPD_ONE_IN(fabs)
256FPD_TWO_IN(fadds)
257FPD_TWO_IN(fsubs)
258FPD_TWO_IN(fdivs)
259FPD_TWO_IN(fmuls)
260FPD_TWO_IN_CR(fcmpu)
261FPD_TWO_IN(fcpsgn)
262FPD_TWO_IN(fdiv)
263FPD_TWO_IN(fadd)
264FPD_TWO_IN(fmul)
265FPD_TWO_IN_CR(fcmpo)
266FPD_TWO_IN(fsub)
267FPD_THREE_IN(fmsubs)
268FPD_THREE_IN(fmadds)
269FPD_THREE_IN(fnmsubs)
270FPD_THREE_IN(fnmadds)
271FPD_THREE_IN(fsel)
272FPD_THREE_IN(fmsub)
273FPD_THREE_IN(fmadd)
274FPD_THREE_IN(fnmsub)
275FPD_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
~/ Read-only file preview.