xref: /openbmc/linux/arch/powerpc/lib/ldstfp.S (revision 0898782247ae533d1f4e47a06bc5d4870931b284)
1*2874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
20016a4cfSPaul Mackerras/*
30016a4cfSPaul Mackerras * Floating-point, VMX/Altivec and VSX loads and stores
40016a4cfSPaul Mackerras * for use in instruction emulation.
50016a4cfSPaul Mackerras *
60016a4cfSPaul Mackerras * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
70016a4cfSPaul Mackerras */
80016a4cfSPaul Mackerras
90016a4cfSPaul Mackerras#include <asm/processor.h>
100016a4cfSPaul Mackerras#include <asm/ppc_asm.h>
110016a4cfSPaul Mackerras#include <asm/ppc-opcode.h>
120016a4cfSPaul Mackerras#include <asm/reg.h>
130016a4cfSPaul Mackerras#include <asm/asm-offsets.h>
14ec0c464cSChristophe Leroy#include <asm/asm-compat.h>
150016a4cfSPaul Mackerras#include <linux/errno.h>
160016a4cfSPaul Mackerras
170016a4cfSPaul Mackerras#define STKFRM	(PPC_MIN_STKFRM + 16)
180016a4cfSPaul Mackerras
19c22435a5SPaul Mackerras/* Get the contents of frN into *p; N is in r3 and p is in r4. */
200016a4cfSPaul Mackerras_GLOBAL(get_fpr)
210016a4cfSPaul Mackerras	mflr	r0
22c22435a5SPaul Mackerras	mfmsr	r6
23c22435a5SPaul Mackerras	ori	r7, r6, MSR_FP
24c22435a5SPaul Mackerras	MTMSRD(r7)
25c22435a5SPaul Mackerras	isync
260016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0xf8
270016a4cfSPaul Mackerras	bcl	20,31,1f
28c22435a5SPaul Mackerrasreg = 0
29c22435a5SPaul Mackerras	.rept	32
30c22435a5SPaul Mackerras	stfd	reg, 0(r4)
31c22435a5SPaul Mackerras	b	2f
320016a4cfSPaul Mackerrasreg = reg + 1
330016a4cfSPaul Mackerras	.endr
340016a4cfSPaul Mackerras1:	mflr	r5
350016a4cfSPaul Mackerras	add	r5,r3,r5
360016a4cfSPaul Mackerras	mtctr	r5
370016a4cfSPaul Mackerras	mtlr	r0
380016a4cfSPaul Mackerras	bctr
39c22435a5SPaul Mackerras2:	MTMSRD(r6)
40c22435a5SPaul Mackerras	isync
41c22435a5SPaul Mackerras	blr
420016a4cfSPaul Mackerras
43c22435a5SPaul Mackerras/* Put the contents of *p into frN; N is in r3 and p is in r4. */
440016a4cfSPaul Mackerras_GLOBAL(put_fpr)
450016a4cfSPaul Mackerras	mflr	r0
46c22435a5SPaul Mackerras	mfmsr	r6
47c22435a5SPaul Mackerras	ori	r7, r6, MSR_FP
48c22435a5SPaul Mackerras	MTMSRD(r7)
49c22435a5SPaul Mackerras	isync
500016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0xf8
510016a4cfSPaul Mackerras	bcl	20,31,1f
52c22435a5SPaul Mackerrasreg = 0
53c22435a5SPaul Mackerras	.rept	32
54c22435a5SPaul Mackerras	lfd	reg, 0(r4)
55c22435a5SPaul Mackerras	b	2f
560016a4cfSPaul Mackerrasreg = reg + 1
570016a4cfSPaul Mackerras	.endr
580016a4cfSPaul Mackerras1:	mflr	r5
590016a4cfSPaul Mackerras	add	r5,r3,r5
600016a4cfSPaul Mackerras	mtctr	r5
610016a4cfSPaul Mackerras	mtlr	r0
620016a4cfSPaul Mackerras	bctr
63c22435a5SPaul Mackerras2:	MTMSRD(r6)
640016a4cfSPaul Mackerras	isync
650016a4cfSPaul Mackerras	blr
660016a4cfSPaul Mackerras
670016a4cfSPaul Mackerras#ifdef CONFIG_ALTIVEC
68c22435a5SPaul Mackerras/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
690016a4cfSPaul Mackerras_GLOBAL(get_vr)
700016a4cfSPaul Mackerras	mflr	r0
71c22435a5SPaul Mackerras	mfmsr	r6
72c22435a5SPaul Mackerras	oris	r7, r6, MSR_VEC@h
73c22435a5SPaul Mackerras	MTMSRD(r7)
74c22435a5SPaul Mackerras	isync
754716e488SPaul Mackerras	rlwinm	r3,r3,3,0xf8
760016a4cfSPaul Mackerras	bcl	20,31,1f
77c22435a5SPaul Mackerrasreg = 0
78c22435a5SPaul Mackerras	.rept	32
79c22435a5SPaul Mackerras	stvx	reg, 0, r4
80c22435a5SPaul Mackerras	b	2f
810016a4cfSPaul Mackerrasreg = reg + 1
820016a4cfSPaul Mackerras	.endr
830016a4cfSPaul Mackerras1:	mflr	r5
844716e488SPaul Mackerras	add	r5,r3,r5
850016a4cfSPaul Mackerras	mtctr	r5
860016a4cfSPaul Mackerras	mtlr	r0
870016a4cfSPaul Mackerras	bctr
88c22435a5SPaul Mackerras2:	MTMSRD(r6)
89c22435a5SPaul Mackerras	isync
90c22435a5SPaul Mackerras	blr
910016a4cfSPaul Mackerras
92c22435a5SPaul Mackerras/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
930016a4cfSPaul Mackerras_GLOBAL(put_vr)
940016a4cfSPaul Mackerras	mflr	r0
95c22435a5SPaul Mackerras	mfmsr	r6
96c22435a5SPaul Mackerras	oris	r7, r6, MSR_VEC@h
97c22435a5SPaul Mackerras	MTMSRD(r7)
98c22435a5SPaul Mackerras	isync
994716e488SPaul Mackerras	rlwinm	r3,r3,3,0xf8
1000016a4cfSPaul Mackerras	bcl	20,31,1f
101c22435a5SPaul Mackerrasreg = 0
102c22435a5SPaul Mackerras	.rept	32
103c22435a5SPaul Mackerras	lvx	reg, 0, r4
104c22435a5SPaul Mackerras	b	2f
1050016a4cfSPaul Mackerrasreg = reg + 1
1060016a4cfSPaul Mackerras	.endr
1070016a4cfSPaul Mackerras1:	mflr	r5
1084716e488SPaul Mackerras	add	r5,r3,r5
1090016a4cfSPaul Mackerras	mtctr	r5
1100016a4cfSPaul Mackerras	mtlr	r0
1110016a4cfSPaul Mackerras	bctr
112c22435a5SPaul Mackerras2:	MTMSRD(r6)
1130016a4cfSPaul Mackerras	isync
1140016a4cfSPaul Mackerras	blr
1150016a4cfSPaul Mackerras#endif /* CONFIG_ALTIVEC */
1160016a4cfSPaul Mackerras
1170016a4cfSPaul Mackerras#ifdef CONFIG_VSX
118df99e6ebSAnton Blanchard/* Get the contents of vsN into vs0; N is in r3. */
1190016a4cfSPaul Mackerras_GLOBAL(get_vsr)
1200016a4cfSPaul Mackerras	mflr	r0
1210016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0x1f8
1220016a4cfSPaul Mackerras	bcl	20,31,1f
123df99e6ebSAnton Blanchard	blr			/* vs0 is already in vs0 */
1240016a4cfSPaul Mackerras	nop
1250016a4cfSPaul Mackerrasreg = 1
1260016a4cfSPaul Mackerras	.rept	63
1270016a4cfSPaul Mackerras	XXLOR(0,reg,reg)
1280016a4cfSPaul Mackerras	blr
1290016a4cfSPaul Mackerrasreg = reg + 1
1300016a4cfSPaul Mackerras	.endr
1310016a4cfSPaul Mackerras1:	mflr	r5
1320016a4cfSPaul Mackerras	add	r5,r3,r5
1330016a4cfSPaul Mackerras	mtctr	r5
1340016a4cfSPaul Mackerras	mtlr	r0
1350016a4cfSPaul Mackerras	bctr
1360016a4cfSPaul Mackerras
137df99e6ebSAnton Blanchard/* Put the contents of vs0 into vsN; N is in r3. */
1380016a4cfSPaul Mackerras_GLOBAL(put_vsr)
1390016a4cfSPaul Mackerras	mflr	r0
1400016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0x1f8
1410016a4cfSPaul Mackerras	bcl	20,31,1f
142c2ce6f9fSAnton Blanchard	blr			/* v0 is already in v0 */
1430016a4cfSPaul Mackerras	nop
1440016a4cfSPaul Mackerrasreg = 1
1450016a4cfSPaul Mackerras	.rept	63
1460016a4cfSPaul Mackerras	XXLOR(reg,0,0)
1470016a4cfSPaul Mackerras	blr
1480016a4cfSPaul Mackerrasreg = reg + 1
1490016a4cfSPaul Mackerras	.endr
1500016a4cfSPaul Mackerras1:	mflr	r5
1510016a4cfSPaul Mackerras	add	r5,r3,r5
1520016a4cfSPaul Mackerras	mtctr	r5
1530016a4cfSPaul Mackerras	mtlr	r0
1540016a4cfSPaul Mackerras	bctr
1550016a4cfSPaul Mackerras
1560016a4cfSPaul Mackerras/* Load VSX reg N from vector doubleword *p.  N is in r3, p in r4. */
157350779a2SPaul Mackerras_GLOBAL(load_vsrn)
1580016a4cfSPaul Mackerras	PPC_STLU r1,-STKFRM(r1)
1590016a4cfSPaul Mackerras	mflr	r0
1600016a4cfSPaul Mackerras	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
1610016a4cfSPaul Mackerras	mfmsr	r6
1620016a4cfSPaul Mackerras	oris	r7,r6,MSR_VSX@h
1630016a4cfSPaul Mackerras	cmpwi	cr7,r3,0
1640016a4cfSPaul Mackerras	li	r8,STKFRM-16
165cd64d169SSean MacLennan	MTMSRD(r7)
1660016a4cfSPaul Mackerras	isync
1670016a4cfSPaul Mackerras	beq	cr7,1f
168c75df6f9SMichael Neuling	STXVD2X(0,R1,R8)
169350779a2SPaul Mackerras1:	LXVD2X(0,R0,R4)
170350779a2SPaul Mackerras#ifdef __LITTLE_ENDIAN__
171350779a2SPaul Mackerras	XXSWAPD(0,0)
172350779a2SPaul Mackerras#endif
173350779a2SPaul Mackerras	beq	cr7,4f
1740016a4cfSPaul Mackerras	bl	put_vsr
175c75df6f9SMichael Neuling	LXVD2X(0,R1,R8)
1760016a4cfSPaul Mackerras4:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
1770016a4cfSPaul Mackerras	mtlr	r0
178cd64d169SSean MacLennan	MTMSRD(r6)
1790016a4cfSPaul Mackerras	isync
1800016a4cfSPaul Mackerras	addi	r1,r1,STKFRM
1810016a4cfSPaul Mackerras	blr
1820016a4cfSPaul Mackerras
1830016a4cfSPaul Mackerras/* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
184350779a2SPaul Mackerras_GLOBAL(store_vsrn)
1850016a4cfSPaul Mackerras	PPC_STLU r1,-STKFRM(r1)
1860016a4cfSPaul Mackerras	mflr	r0
1870016a4cfSPaul Mackerras	PPC_STL	r0,STKFRM+PPC_LR_STKOFF(r1)
1880016a4cfSPaul Mackerras	mfmsr	r6
1890016a4cfSPaul Mackerras	oris	r7,r6,MSR_VSX@h
1900016a4cfSPaul Mackerras	li	r8,STKFRM-16
191cd64d169SSean MacLennan	MTMSRD(r7)
1920016a4cfSPaul Mackerras	isync
193c75df6f9SMichael Neuling	STXVD2X(0,R1,R8)
1940016a4cfSPaul Mackerras	bl	get_vsr
195350779a2SPaul Mackerras#ifdef __LITTLE_ENDIAN__
196350779a2SPaul Mackerras	XXSWAPD(0,0)
197350779a2SPaul Mackerras#endif
198350779a2SPaul Mackerras	STXVD2X(0,R0,R4)
199c75df6f9SMichael Neuling	LXVD2X(0,R1,R8)
200350779a2SPaul Mackerras	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
2010016a4cfSPaul Mackerras	mtlr	r0
202cd64d169SSean MacLennan	MTMSRD(r6)
2030016a4cfSPaul Mackerras	isync
2040016a4cfSPaul Mackerras	mr	r3,r9
2050016a4cfSPaul Mackerras	addi	r1,r1,STKFRM
2060016a4cfSPaul Mackerras	blr
2070016a4cfSPaul Mackerras#endif /* CONFIG_VSX */
208cd64d169SSean MacLennan
209350779a2SPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */
210350779a2SPaul Mackerras/* conv_sp_to_dp(float *sp, double *dp) */
211350779a2SPaul Mackerras_GLOBAL(conv_sp_to_dp)
212350779a2SPaul Mackerras	mfmsr	r6
213350779a2SPaul Mackerras	ori	r7, r6, MSR_FP
214350779a2SPaul Mackerras	MTMSRD(r7)
215350779a2SPaul Mackerras	isync
216350779a2SPaul Mackerras	stfd	fr0, -16(r1)
217350779a2SPaul Mackerras	lfs	fr0, 0(r3)
218350779a2SPaul Mackerras	stfd	fr0, 0(r4)
219350779a2SPaul Mackerras	lfd	fr0, -16(r1)
220350779a2SPaul Mackerras	MTMSRD(r6)
221350779a2SPaul Mackerras	isync
222350779a2SPaul Mackerras	blr
223350779a2SPaul Mackerras
224350779a2SPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */
225350779a2SPaul Mackerras/* conv_sp_to_dp(double *dp, float *sp) */
226350779a2SPaul Mackerras_GLOBAL(conv_dp_to_sp)
227350779a2SPaul Mackerras	mfmsr	r6
228350779a2SPaul Mackerras	ori	r7, r6, MSR_FP
229350779a2SPaul Mackerras	MTMSRD(r7)
230350779a2SPaul Mackerras	isync
231350779a2SPaul Mackerras	stfd	fr0, -16(r1)
232350779a2SPaul Mackerras	lfd	fr0, 0(r3)
233350779a2SPaul Mackerras	stfs	fr0, 0(r4)
234350779a2SPaul Mackerras	lfd	fr0, -16(r1)
235350779a2SPaul Mackerras	MTMSRD(r6)
236350779a2SPaul Mackerras	isync
237350779a2SPaul Mackerras	blr
238