• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/powerpc/lib/
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#define STKFRM	(PPC_MIN_STKFRM + 16)
21
22	.macro	extab	instr,handler
23	.section __ex_table,"a"
24	PPC_LONG \instr,\handler
25	.previous
26	.endm
27
28	.macro	inst32	op
29reg = 0
30	.rept	32
3120:	\op	reg,0,r4
32	b	3f
33	extab	20b,99f
34reg = reg + 1
35	.endr
36	.endm
37
38/* Get the contents of frN into fr0; N is in r3. */
39_GLOBAL(get_fpr)
40	mflr	r0
41	rlwinm	r3,r3,3,0xf8
42	bcl	20,31,1f
43	blr			/* fr0 is already in fr0 */
44	nop
45reg = 1
46	.rept	31
47	fmr	fr0,reg
48	blr
49reg = reg + 1
50	.endr
511:	mflr	r5
52	add	r5,r3,r5
53	mtctr	r5
54	mtlr	r0
55	bctr
56
57/* Put the contents of fr0 into frN; N is in r3. */
58_GLOBAL(put_fpr)
59	mflr	r0
60	rlwinm	r3,r3,3,0xf8
61	bcl	20,31,1f
62	blr			/* fr0 is already in fr0 */
63	nop
64reg = 1
65	.rept	31
66	fmr	reg,fr0
67	blr
68reg = reg + 1
69	.endr
701:	mflr	r5
71	add	r5,r3,r5
72	mtctr	r5
73	mtlr	r0
74	bctr
75
76/* Load FP reg N from float at *p.  N is in r3, p in r4. */
77_GLOBAL(do_lfs)
78	PPC_STLU r1,-STKFRM(r1)
79	mflr	r0
80	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
81	mfmsr	r6
82	ori	r7,r6,MSR_FP
83	cmpwi	cr7,r3,0
84	mtmsrd	r7
85	isync
86	beq	cr7,1f
87	stfd	fr0,STKFRM-16(r1)
881:	li	r9,-EFAULT
892:	lfs	fr0,0(r4)
90	li	r9,0
913:	bl	put_fpr
92	beq	cr7,4f
93	lfd	fr0,STKFRM-16(r1)
944:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
95	mtlr	r0
96	mtmsrd	r6
97	isync
98	mr	r3,r9
99	addi	r1,r1,STKFRM
100	blr
101	extab	2b,3b
102
103/* Load FP reg N from double at *p.  N is in r3, p in r4. */
104_GLOBAL(do_lfd)
105	PPC_STLU r1,-STKFRM(r1)
106	mflr	r0
107	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
108	mfmsr	r6
109	ori	r7,r6,MSR_FP
110	cmpwi	cr7,r3,0
111	mtmsrd	r7
112	isync
113	beq	cr7,1f
114	stfd	fr0,STKFRM-16(r1)
1151:	li	r9,-EFAULT
1162:	lfd	fr0,0(r4)
117	li	r9,0
1183:	beq	cr7,4f
119	bl	put_fpr
120	lfd	fr0,STKFRM-16(r1)
1214:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
122	mtlr	r0
123	mtmsrd	r6
124	isync
125	mr	r3,r9
126	addi	r1,r1,STKFRM
127	blr
128	extab	2b,3b
129
130/* Store FP reg N to float at *p.  N is in r3, p in r4. */
131_GLOBAL(do_stfs)
132	PPC_STLU r1,-STKFRM(r1)
133	mflr	r0
134	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
135	mfmsr	r6
136	ori	r7,r6,MSR_FP
137	cmpwi	cr7,r3,0
138	mtmsrd	r7
139	isync
140	beq	cr7,1f
141	stfd	fr0,STKFRM-16(r1)
142	bl	get_fpr
1431:	li	r9,-EFAULT
1442:	stfs	fr0,0(r4)
145	li	r9,0
1463:	beq	cr7,4f
147	lfd	fr0,STKFRM-16(r1)
1484:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
149	mtlr	r0
150	mtmsrd	r6
151	isync
152	mr	r3,r9
153	addi	r1,r1,STKFRM
154	blr
155	extab	2b,3b
156
157/* Store FP reg N to double at *p.  N is in r3, p in r4. */
158_GLOBAL(do_stfd)
159	PPC_STLU r1,-STKFRM(r1)
160	mflr	r0
161	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
162	mfmsr	r6
163	ori	r7,r6,MSR_FP
164	cmpwi	cr7,r3,0
165	mtmsrd	r7
166	isync
167	beq	cr7,1f
168	stfd	fr0,STKFRM-16(r1)
169	bl	get_fpr
1701:	li	r9,-EFAULT
1712:	stfd	fr0,0(r4)
172	li	r9,0
1733:	beq	cr7,4f
174	lfd	fr0,STKFRM-16(r1)
1754:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
176	mtlr	r0
177	mtmsrd	r6
178	isync
179	mr	r3,r9
180	addi	r1,r1,STKFRM
181	blr
182	extab	2b,3b
183
184#ifdef CONFIG_ALTIVEC
185/* Get the contents of vrN into vr0; N is in r3. */
186_GLOBAL(get_vr)
187	mflr	r0
188	rlwinm	r3,r3,3,0xf8
189	bcl	20,31,1f
190	blr			/* vr0 is already in vr0 */
191	nop
192reg = 1
193	.rept	31
194	vor	vr0,reg,reg	/* assembler doesn't know vmr? */
195	blr
196reg = reg + 1
197	.endr
1981:	mflr	r5
199	add	r5,r3,r5
200	mtctr	r5
201	mtlr	r0
202	bctr
203
204/* Put the contents of vr0 into vrN; N is in r3. */
205_GLOBAL(put_vr)
206	mflr	r0
207	rlwinm	r3,r3,3,0xf8
208	bcl	20,31,1f
209	blr			/* vr0 is already in vr0 */
210	nop
211reg = 1
212	.rept	31
213	vor	reg,vr0,vr0
214	blr
215reg = reg + 1
216	.endr
2171:	mflr	r5
218	add	r5,r3,r5
219	mtctr	r5
220	mtlr	r0
221	bctr
222
223/* Load vector reg N from *p.  N is in r3, p in r4. */
224_GLOBAL(do_lvx)
225	PPC_STLU r1,-STKFRM(r1)
226	mflr	r0
227	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
228	mfmsr	r6
229	oris	r7,r6,MSR_VEC@h
230	cmpwi	cr7,r3,0
231	li	r8,STKFRM-16
232	mtmsrd	r7
233	isync
234	beq	cr7,1f
235	stvx	vr0,r1,r8
2361:	li	r9,-EFAULT
2372:	lvx	vr0,0,r4
238	li	r9,0
2393:	beq	cr7,4f
240	bl	put_vr
241	lvx	vr0,r1,r8
2424:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
243	mtlr	r0
244	mtmsrd	r6
245	isync
246	mr	r3,r9
247	addi	r1,r1,STKFRM
248	blr
249	extab	2b,3b
250
251/* Store vector reg N to *p.  N is in r3, p in r4. */
252_GLOBAL(do_stvx)
253	PPC_STLU r1,-STKFRM(r1)
254	mflr	r0
255	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
256	mfmsr	r6
257	oris	r7,r6,MSR_VEC@h
258	cmpwi	cr7,r3,0
259	li	r8,STKFRM-16
260	mtmsrd	r7
261	isync
262	beq	cr7,1f
263	stvx	vr0,r1,r8
264	bl	get_vr
2651:	li	r9,-EFAULT
2662:	stvx	vr0,0,r4
267	li	r9,0
2683:	beq	cr7,4f
269	lvx	vr0,r1,r8
2704:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
271	mtlr	r0
272	mtmsrd	r6
273	isync
274	mr	r3,r9
275	addi	r1,r1,STKFRM
276	blr
277	extab	2b,3b
278#endif /* CONFIG_ALTIVEC */
279
280#ifdef CONFIG_VSX
281/* Get the contents of vsrN into vsr0; N is in r3. */
282_GLOBAL(get_vsr)
283	mflr	r0
284	rlwinm	r3,r3,3,0x1f8
285	bcl	20,31,1f
286	blr			/* vsr0 is already in vsr0 */
287	nop
288reg = 1
289	.rept	63
290	XXLOR(0,reg,reg)
291	blr
292reg = reg + 1
293	.endr
2941:	mflr	r5
295	add	r5,r3,r5
296	mtctr	r5
297	mtlr	r0
298	bctr
299
300/* Put the contents of vsr0 into vsrN; N is in r3. */
301_GLOBAL(put_vsr)
302	mflr	r0
303	rlwinm	r3,r3,3,0x1f8
304	bcl	20,31,1f
305	blr			/* vr0 is already in vr0 */
306	nop
307reg = 1
308	.rept	63
309	XXLOR(reg,0,0)
310	blr
311reg = reg + 1
312	.endr
3131:	mflr	r5
314	add	r5,r3,r5
315	mtctr	r5
316	mtlr	r0
317	bctr
318
319/* Load VSX reg N from vector doubleword *p.  N is in r3, p in r4. */
320_GLOBAL(do_lxvd2x)
321	PPC_STLU r1,-STKFRM(r1)
322	mflr	r0
323	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
324	mfmsr	r6
325	oris	r7,r6,MSR_VSX@h
326	cmpwi	cr7,r3,0
327	li	r8,STKFRM-16
328	mtmsrd	r7
329	isync
330	beq	cr7,1f
331	STXVD2X(0,r1,r8)
3321:	li	r9,-EFAULT
3332:	LXVD2X(0,0,r4)
334	li	r9,0
3353:	beq	cr7,4f
336	bl	put_vsr
337	LXVD2X(0,r1,r8)
3384:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
339	mtlr	r0
340	mtmsrd	r6
341	isync
342	mr	r3,r9
343	addi	r1,r1,STKFRM
344	blr
345	extab	2b,3b
346
347/* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
348_GLOBAL(do_stxvd2x)
349	PPC_STLU r1,-STKFRM(r1)
350	mflr	r0
351	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
352	mfmsr	r6
353	oris	r7,r6,MSR_VSX@h
354	cmpwi	cr7,r3,0
355	li	r8,STKFRM-16
356	mtmsrd	r7
357	isync
358	beq	cr7,1f
359	STXVD2X(0,r1,r8)
360	bl	get_vsr
3611:	li	r9,-EFAULT
3622:	STXVD2X(0,0,r4)
363	li	r9,0
3643:	beq	cr7,4f
365	LXVD2X(0,r1,r8)
3664:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
367	mtlr	r0
368	mtmsrd	r6
369	isync
370	mr	r3,r9
371	addi	r1,r1,STKFRM
372	blr
373	extab	2b,3b
374
375#endif /* CONFIG_VSX */
376