Linux Audio

Check our new training course

Loading...
v6.8
  1/* SPDX-License-Identifier: GPL-2.0-or-later */
  2/*
  3 * Floating-point, VMX/Altivec and VSX loads and stores
  4 * for use in instruction emulation.
  5 *
  6 * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
 
 
 
 
 
  7 */
  8
  9#include <asm/processor.h>
 10#include <asm/ppc_asm.h>
 11#include <asm/ppc-opcode.h>
 12#include <asm/reg.h>
 13#include <asm/asm-offsets.h>
 14#include <asm/asm-compat.h>
 15#include <linux/errno.h>
 16
 
 
 17#define STKFRM	(PPC_MIN_STKFRM + 16)
 18
 19/* Get the contents of frN into *p; N is in r3 and p is in r4. */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 20_GLOBAL(get_fpr)
 21	mflr	r0
 22	mfmsr	r6
 23	ori	r7, r6, MSR_FP
 24	MTMSRD(r7)
 25	isync
 26	rlwinm	r3,r3,3,0xf8
 27	bcl	20,31,1f
 28reg = 0
 29	.rept	32
 30	stfd	reg, 0(r4)
 31	b	2f
 
 
 32reg = reg + 1
 33	.endr
 341:	mflr	r5
 35	add	r5,r3,r5
 36	mtctr	r5
 37	mtlr	r0
 38	bctr
 392:	MTMSRD(r6)
 40	isync
 41	blr
 42
 43/* Put the contents of *p into frN; N is in r3 and p is in r4. */
 44_GLOBAL(put_fpr)
 45	mflr	r0
 46	mfmsr	r6
 47	ori	r7, r6, MSR_FP
 48	MTMSRD(r7)
 49	isync
 50	rlwinm	r3,r3,3,0xf8
 51	bcl	20,31,1f
 52reg = 0
 53	.rept	32
 54	lfd	reg, 0(r4)
 55	b	2f
 
 
 56reg = reg + 1
 57	.endr
 581:	mflr	r5
 59	add	r5,r3,r5
 60	mtctr	r5
 61	mtlr	r0
 62	bctr
 632:	MTMSRD(r6)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 64	isync
 
 
 65	blr
 
 66
 67#ifdef CONFIG_ALTIVEC
 68/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
 69_GLOBAL(get_vr)
 70	mflr	r0
 
 71	mfmsr	r6
 72	oris	r7, r6, MSR_VEC@h
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 73	MTMSRD(r7)
 74	isync
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 75	rlwinm	r3,r3,3,0xf8
 76	bcl	20,31,1f
 77reg = 0
 78	.rept	32
 79	stvx	reg, 0, r4
 80	b	2f
 
 
 81reg = reg + 1
 82	.endr
 831:	mflr	r5
 84	add	r5,r3,r5
 85	mtctr	r5
 86	mtlr	r0
 87	bctr
 882:	MTMSRD(r6)
 89	isync
 90	blr
 91
 92/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
 93_GLOBAL(put_vr)
 94	mflr	r0
 95	mfmsr	r6
 96	oris	r7, r6, MSR_VEC@h
 97	MTMSRD(r7)
 98	isync
 99	rlwinm	r3,r3,3,0xf8
100	bcl	20,31,1f
101reg = 0
102	.rept	32
103	lvx	reg, 0, r4
104	b	2f
 
 
105reg = reg + 1
106	.endr
1071:	mflr	r5
108	add	r5,r3,r5
109	mtctr	r5
110	mtlr	r0
111	bctr
1122:	MTMSRD(r6)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113	isync
 
 
114	blr
 
115#endif /* CONFIG_ALTIVEC */
116
117#ifdef CONFIG_VSX
118/* Get the contents of vsN into vs0; N is in r3. */
119_GLOBAL(get_vsr)
120	mflr	r0
121	rlwinm	r3,r3,3,0x1f8
122	bcl	20,31,1f
123	blr			/* vs0 is already in vs0 */
124	nop
125reg = 1
126	.rept	63
127	XXLOR(0,reg,reg)
128	blr
129reg = reg + 1
130	.endr
1311:	mflr	r5
132	add	r5,r3,r5
133	mtctr	r5
134	mtlr	r0
135	bctr
136
137/* Put the contents of vs0 into vsN; N is in r3. */
138_GLOBAL(put_vsr)
139	mflr	r0
140	rlwinm	r3,r3,3,0x1f8
141	bcl	20,31,1f
142	blr			/* v0 is already in v0 */
143	nop
144reg = 1
145	.rept	63
146	XXLOR(reg,0,0)
147	blr
148reg = reg + 1
149	.endr
1501:	mflr	r5
151	add	r5,r3,r5
152	mtctr	r5
153	mtlr	r0
154	bctr
155
156/* Load VSX reg N from vector doubleword *p.  N is in r3, p in r4. */
157_GLOBAL(load_vsrn)
158	PPC_STLU r1,-STKFRM(r1)
159	mflr	r0
160	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
161	mfmsr	r6
162	oris	r7,r6,MSR_VSX@h
163	cmpwi	cr7,r3,0
164	li	r8,STKFRM-16
165	MTMSRD(r7)
166	isync
167	beq	cr7,1f
168	STXVD2X(0,R1,R8)
1691:	LXVD2X(0,R0,R4)
170#ifdef __LITTLE_ENDIAN__
171	XXSWAPD(0,0)
172#endif
173	beq	cr7,4f
174	bl	put_vsr
175	LXVD2X(0,R1,R8)
1764:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
177	mtlr	r0
178	MTMSRD(r6)
179	isync
 
180	addi	r1,r1,STKFRM
181	blr
 
182
183/* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
184_GLOBAL(store_vsrn)
185	PPC_STLU r1,-STKFRM(r1)
186	mflr	r0
187	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
188	mfmsr	r6
189	oris	r7,r6,MSR_VSX@h
 
190	li	r8,STKFRM-16
191	MTMSRD(r7)
192	isync
193	STXVD2X(0,R1,R8)
 
194	bl	get_vsr
195#ifdef __LITTLE_ENDIAN__
196	XXSWAPD(0,0)
197#endif
198	STXVD2X(0,R0,R4)
199	LXVD2X(0,R1,R8)
200	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
201	mtlr	r0
202	MTMSRD(r6)
203	isync
204	mr	r3,r9
205	addi	r1,r1,STKFRM
206	blr
207#endif /* CONFIG_VSX */
208
209/* Convert single-precision to double, without disturbing FPRs. */
210/* conv_sp_to_dp(float *sp, double *dp) */
211_GLOBAL(conv_sp_to_dp)
212	mfmsr	r6
213	ori	r7, r6, MSR_FP
214	MTMSRD(r7)
215	isync
216	stfd	fr0, -16(r1)
217	lfs	fr0, 0(r3)
218	stfd	fr0, 0(r4)
219	lfd	fr0, -16(r1)
220	MTMSRD(r6)
221	isync
222	blr
223
224/* Convert single-precision to double, without disturbing FPRs. */
225/* conv_sp_to_dp(double *dp, float *sp) */
226_GLOBAL(conv_dp_to_sp)
227	mfmsr	r6
228	ori	r7, r6, MSR_FP
229	MTMSRD(r7)
230	isync
231	stfd	fr0, -16(r1)
232	lfd	fr0, 0(r3)
233	stfs	fr0, 0(r4)
234	lfd	fr0, -16(r1)
235	MTMSRD(r6)
236	isync
237	blr
v3.1
 
  1/*
  2 * Floating-point, VMX/Altivec and VSX loads and stores
  3 * for use in instruction emulation.
  4 *
  5 * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  6 *
  7 *  This program is free software; you can redistribute it and/or
  8 *  modify it under the terms of the GNU General Public License
  9 *  as published by the Free Software Foundation; either version
 10 *  2 of the License, or (at your option) any later version.
 11 */
 12
 13#include <asm/processor.h>
 14#include <asm/ppc_asm.h>
 15#include <asm/ppc-opcode.h>
 16#include <asm/reg.h>
 17#include <asm/asm-offsets.h>
 
 18#include <linux/errno.h>
 19
 20#ifdef CONFIG_PPC_FPU
 21
 22#define STKFRM	(PPC_MIN_STKFRM + 16)
 23
 24	.macro	extab	instr,handler
 25	.section __ex_table,"a"
 26	PPC_LONG \instr,\handler
 27	.previous
 28	.endm
 29
 30	.macro	inst32	op
 31reg = 0
 32	.rept	32
 3320:	\op	reg,0,r4
 34	b	3f
 35	extab	20b,99f
 36reg = reg + 1
 37	.endr
 38	.endm
 39
 40/* Get the contents of frN into fr0; N is in r3. */
 41_GLOBAL(get_fpr)
 42	mflr	r0
 
 
 
 
 43	rlwinm	r3,r3,3,0xf8
 44	bcl	20,31,1f
 45	blr			/* fr0 is already in fr0 */
 46	nop
 47reg = 1
 48	.rept	31
 49	fmr	fr0,reg
 50	blr
 51reg = reg + 1
 52	.endr
 531:	mflr	r5
 54	add	r5,r3,r5
 55	mtctr	r5
 56	mtlr	r0
 57	bctr
 
 
 
 58
 59/* Put the contents of fr0 into frN; N is in r3. */
 60_GLOBAL(put_fpr)
 61	mflr	r0
 
 
 
 
 62	rlwinm	r3,r3,3,0xf8
 63	bcl	20,31,1f
 64	blr			/* fr0 is already in fr0 */
 65	nop
 66reg = 1
 67	.rept	31
 68	fmr	reg,fr0
 69	blr
 70reg = reg + 1
 71	.endr
 721:	mflr	r5
 73	add	r5,r3,r5
 74	mtctr	r5
 75	mtlr	r0
 76	bctr
 77
 78/* Load FP reg N from float at *p.  N is in r3, p in r4. */
 79_GLOBAL(do_lfs)
 80	PPC_STLU r1,-STKFRM(r1)
 81	mflr	r0
 82	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
 83	mfmsr	r6
 84	ori	r7,r6,MSR_FP
 85	cmpwi	cr7,r3,0
 86	MTMSRD(r7)
 87	isync
 88	beq	cr7,1f
 89	stfd	fr0,STKFRM-16(r1)
 901:	li	r9,-EFAULT
 912:	lfs	fr0,0(r4)
 92	li	r9,0
 933:	bl	put_fpr
 94	beq	cr7,4f
 95	lfd	fr0,STKFRM-16(r1)
 964:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
 97	mtlr	r0
 98	MTMSRD(r6)
 99	isync
100	mr	r3,r9
101	addi	r1,r1,STKFRM
102	blr
103	extab	2b,3b
104
105/* Load FP reg N from double at *p.  N is in r3, p in r4. */
106_GLOBAL(do_lfd)
107	PPC_STLU r1,-STKFRM(r1)
108	mflr	r0
109	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
110	mfmsr	r6
111	ori	r7,r6,MSR_FP
112	cmpwi	cr7,r3,0
113	MTMSRD(r7)
114	isync
115	beq	cr7,1f
116	stfd	fr0,STKFRM-16(r1)
1171:	li	r9,-EFAULT
1182:	lfd	fr0,0(r4)
119	li	r9,0
1203:	beq	cr7,4f
121	bl	put_fpr
122	lfd	fr0,STKFRM-16(r1)
1234:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
124	mtlr	r0
125	MTMSRD(r6)
126	isync
127	mr	r3,r9
128	addi	r1,r1,STKFRM
129	blr
130	extab	2b,3b
131
132/* Store FP reg N to float at *p.  N is in r3, p in r4. */
133_GLOBAL(do_stfs)
134	PPC_STLU r1,-STKFRM(r1)
135	mflr	r0
136	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
137	mfmsr	r6
138	ori	r7,r6,MSR_FP
139	cmpwi	cr7,r3,0
140	MTMSRD(r7)
141	isync
142	beq	cr7,1f
143	stfd	fr0,STKFRM-16(r1)
144	bl	get_fpr
1451:	li	r9,-EFAULT
1462:	stfs	fr0,0(r4)
147	li	r9,0
1483:	beq	cr7,4f
149	lfd	fr0,STKFRM-16(r1)
1504:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
151	mtlr	r0
152	MTMSRD(r6)
153	isync
154	mr	r3,r9
155	addi	r1,r1,STKFRM
156	blr
157	extab	2b,3b
158
159/* Store FP reg N to double at *p.  N is in r3, p in r4. */
160_GLOBAL(do_stfd)
161	PPC_STLU r1,-STKFRM(r1)
162	mflr	r0
163	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
164	mfmsr	r6
165	ori	r7,r6,MSR_FP
166	cmpwi	cr7,r3,0
167	MTMSRD(r7)
168	isync
169	beq	cr7,1f
170	stfd	fr0,STKFRM-16(r1)
171	bl	get_fpr
1721:	li	r9,-EFAULT
1732:	stfd	fr0,0(r4)
174	li	r9,0
1753:	beq	cr7,4f
176	lfd	fr0,STKFRM-16(r1)
1774:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
178	mtlr	r0
179	MTMSRD(r6)
180	isync
181	mr	r3,r9
182	addi	r1,r1,STKFRM
183	blr
184	extab	2b,3b
185
186#ifdef CONFIG_ALTIVEC
187/* Get the contents of vrN into vr0; N is in r3. */
188_GLOBAL(get_vr)
189	mflr	r0
190	rlwinm	r3,r3,3,0xf8
191	bcl	20,31,1f
192	blr			/* vr0 is already in vr0 */
193	nop
194reg = 1
195	.rept	31
196	vor	vr0,reg,reg	/* assembler doesn't know vmr? */
197	blr
198reg = reg + 1
199	.endr
2001:	mflr	r5
201	add	r5,r3,r5
202	mtctr	r5
203	mtlr	r0
204	bctr
 
 
 
205
206/* Put the contents of vr0 into vrN; N is in r3. */
207_GLOBAL(put_vr)
208	mflr	r0
 
 
 
 
209	rlwinm	r3,r3,3,0xf8
210	bcl	20,31,1f
211	blr			/* vr0 is already in vr0 */
212	nop
213reg = 1
214	.rept	31
215	vor	reg,vr0,vr0
216	blr
217reg = reg + 1
218	.endr
2191:	mflr	r5
220	add	r5,r3,r5
221	mtctr	r5
222	mtlr	r0
223	bctr
224
225/* Load vector reg N from *p.  N is in r3, p in r4. */
226_GLOBAL(do_lvx)
227	PPC_STLU r1,-STKFRM(r1)
228	mflr	r0
229	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
230	mfmsr	r6
231	oris	r7,r6,MSR_VEC@h
232	cmpwi	cr7,r3,0
233	li	r8,STKFRM-16
234	MTMSRD(r7)
235	isync
236	beq	cr7,1f
237	stvx	vr0,r1,r8
2381:	li	r9,-EFAULT
2392:	lvx	vr0,0,r4
240	li	r9,0
2413:	beq	cr7,4f
242	bl	put_vr
243	lvx	vr0,r1,r8
2444:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
245	mtlr	r0
246	MTMSRD(r6)
247	isync
248	mr	r3,r9
249	addi	r1,r1,STKFRM
250	blr
251	extab	2b,3b
252
253/* Store vector reg N to *p.  N is in r3, p in r4. */
254_GLOBAL(do_stvx)
255	PPC_STLU r1,-STKFRM(r1)
256	mflr	r0
257	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
258	mfmsr	r6
259	oris	r7,r6,MSR_VEC@h
260	cmpwi	cr7,r3,0
261	li	r8,STKFRM-16
262	MTMSRD(r7)
263	isync
264	beq	cr7,1f
265	stvx	vr0,r1,r8
266	bl	get_vr
2671:	li	r9,-EFAULT
2682:	stvx	vr0,0,r4
269	li	r9,0
2703:	beq	cr7,4f
271	lvx	vr0,r1,r8
2724:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
273	mtlr	r0
274	MTMSRD(r6)
275	isync
276	mr	r3,r9
277	addi	r1,r1,STKFRM
278	blr
279	extab	2b,3b
280#endif /* CONFIG_ALTIVEC */
281
282#ifdef CONFIG_VSX
283/* Get the contents of vsrN into vsr0; N is in r3. */
284_GLOBAL(get_vsr)
285	mflr	r0
286	rlwinm	r3,r3,3,0x1f8
287	bcl	20,31,1f
288	blr			/* vsr0 is already in vsr0 */
289	nop
290reg = 1
291	.rept	63
292	XXLOR(0,reg,reg)
293	blr
294reg = reg + 1
295	.endr
2961:	mflr	r5
297	add	r5,r3,r5
298	mtctr	r5
299	mtlr	r0
300	bctr
301
302/* Put the contents of vsr0 into vsrN; N is in r3. */
303_GLOBAL(put_vsr)
304	mflr	r0
305	rlwinm	r3,r3,3,0x1f8
306	bcl	20,31,1f
307	blr			/* vr0 is already in vr0 */
308	nop
309reg = 1
310	.rept	63
311	XXLOR(reg,0,0)
312	blr
313reg = reg + 1
314	.endr
3151:	mflr	r5
316	add	r5,r3,r5
317	mtctr	r5
318	mtlr	r0
319	bctr
320
321/* Load VSX reg N from vector doubleword *p.  N is in r3, p in r4. */
322_GLOBAL(do_lxvd2x)
323	PPC_STLU r1,-STKFRM(r1)
324	mflr	r0
325	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
326	mfmsr	r6
327	oris	r7,r6,MSR_VSX@h
328	cmpwi	cr7,r3,0
329	li	r8,STKFRM-16
330	MTMSRD(r7)
331	isync
332	beq	cr7,1f
333	STXVD2X(0,r1,r8)
3341:	li	r9,-EFAULT
3352:	LXVD2X(0,0,r4)
336	li	r9,0
3373:	beq	cr7,4f
 
338	bl	put_vsr
339	LXVD2X(0,r1,r8)
3404:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
341	mtlr	r0
342	MTMSRD(r6)
343	isync
344	mr	r3,r9
345	addi	r1,r1,STKFRM
346	blr
347	extab	2b,3b
348
349/* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
350_GLOBAL(do_stxvd2x)
351	PPC_STLU r1,-STKFRM(r1)
352	mflr	r0
353	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
354	mfmsr	r6
355	oris	r7,r6,MSR_VSX@h
356	cmpwi	cr7,r3,0
357	li	r8,STKFRM-16
358	MTMSRD(r7)
359	isync
360	beq	cr7,1f
361	STXVD2X(0,r1,r8)
362	bl	get_vsr
3631:	li	r9,-EFAULT
3642:	STXVD2X(0,0,r4)
365	li	r9,0
3663:	beq	cr7,4f
367	LXVD2X(0,r1,r8)
3684:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
369	mtlr	r0
370	MTMSRD(r6)
371	isync
372	mr	r3,r9
373	addi	r1,r1,STKFRM
374	blr
375	extab	2b,3b
376
377#endif /* CONFIG_VSX */
 
 
 
 
 
 
 
 
 
 
 
 
 
378
379#endif	/* CONFIG_PPC_FPU */