xref: /openbmc/linux/arch/powerpc/lib/ldstfp.S (revision 2874c5fd)
12874c5fdSThomas 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
17cd64d169SSean MacLennan#define STKFRM	(PPC_MIN_STKFRM + 16)
18cd64d169SSean MacLennan
190016a4cfSPaul Mackerras/* Get the contents of frN into *p; N is in r3 and p is in r4. */
200016a4cfSPaul Mackerras_GLOBAL(get_fpr)
21c22435a5SPaul Mackerras	mflr	r0
220016a4cfSPaul Mackerras	mfmsr	r6
230016a4cfSPaul Mackerras	ori	r7, r6, MSR_FP
24c22435a5SPaul Mackerras	MTMSRD(r7)
25c22435a5SPaul Mackerras	isync
26c22435a5SPaul Mackerras	rlwinm	r3,r3,3,0xf8
27c22435a5SPaul Mackerras	bcl	20,31,1f
280016a4cfSPaul Mackerrasreg = 0
290016a4cfSPaul Mackerras	.rept	32
30c22435a5SPaul Mackerras	stfd	reg, 0(r4)
31c22435a5SPaul Mackerras	b	2f
32c22435a5SPaul Mackerrasreg = reg + 1
33c22435a5SPaul Mackerras	.endr
340016a4cfSPaul Mackerras1:	mflr	r5
350016a4cfSPaul Mackerras	add	r5,r3,r5
360016a4cfSPaul Mackerras	mtctr	r5
370016a4cfSPaul Mackerras	mtlr	r0
380016a4cfSPaul Mackerras	bctr
390016a4cfSPaul Mackerras2:	MTMSRD(r6)
400016a4cfSPaul Mackerras	isync
41c22435a5SPaul Mackerras	blr
42c22435a5SPaul Mackerras
43c22435a5SPaul Mackerras/* Put the contents of *p into frN; N is in r3 and p is in r4. */
440016a4cfSPaul Mackerras_GLOBAL(put_fpr)
45c22435a5SPaul Mackerras	mflr	r0
460016a4cfSPaul Mackerras	mfmsr	r6
470016a4cfSPaul Mackerras	ori	r7, r6, MSR_FP
48c22435a5SPaul Mackerras	MTMSRD(r7)
49c22435a5SPaul Mackerras	isync
50c22435a5SPaul Mackerras	rlwinm	r3,r3,3,0xf8
51c22435a5SPaul Mackerras	bcl	20,31,1f
520016a4cfSPaul Mackerrasreg = 0
530016a4cfSPaul Mackerras	.rept	32
54c22435a5SPaul Mackerras	lfd	reg, 0(r4)
55c22435a5SPaul Mackerras	b	2f
56c22435a5SPaul Mackerrasreg = reg + 1
57c22435a5SPaul Mackerras	.endr
580016a4cfSPaul Mackerras1:	mflr	r5
590016a4cfSPaul Mackerras	add	r5,r3,r5
600016a4cfSPaul Mackerras	mtctr	r5
610016a4cfSPaul Mackerras	mtlr	r0
620016a4cfSPaul Mackerras	bctr
630016a4cfSPaul Mackerras2:	MTMSRD(r6)
640016a4cfSPaul Mackerras	isync
65c22435a5SPaul Mackerras	blr
660016a4cfSPaul Mackerras
670016a4cfSPaul Mackerras#ifdef CONFIG_ALTIVEC
680016a4cfSPaul Mackerras/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
690016a4cfSPaul Mackerras_GLOBAL(get_vr)
70c22435a5SPaul Mackerras	mflr	r0
710016a4cfSPaul Mackerras	mfmsr	r6
720016a4cfSPaul Mackerras	oris	r7, r6, MSR_VEC@h
73c22435a5SPaul Mackerras	MTMSRD(r7)
74c22435a5SPaul Mackerras	isync
75c22435a5SPaul Mackerras	rlwinm	r3,r3,3,0xf8
76c22435a5SPaul Mackerras	bcl	20,31,1f
774716e488SPaul Mackerrasreg = 0
780016a4cfSPaul Mackerras	.rept	32
79c22435a5SPaul Mackerras	stvx	reg, 0, r4
80c22435a5SPaul Mackerras	b	2f
81c22435a5SPaul Mackerrasreg = reg + 1
82c22435a5SPaul Mackerras	.endr
830016a4cfSPaul Mackerras1:	mflr	r5
840016a4cfSPaul Mackerras	add	r5,r3,r5
850016a4cfSPaul Mackerras	mtctr	r5
864716e488SPaul Mackerras	mtlr	r0
870016a4cfSPaul Mackerras	bctr
880016a4cfSPaul Mackerras2:	MTMSRD(r6)
890016a4cfSPaul Mackerras	isync
90c22435a5SPaul Mackerras	blr
91c22435a5SPaul Mackerras
92c22435a5SPaul Mackerras/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
930016a4cfSPaul Mackerras_GLOBAL(put_vr)
94c22435a5SPaul Mackerras	mflr	r0
950016a4cfSPaul Mackerras	mfmsr	r6
960016a4cfSPaul Mackerras	oris	r7, r6, MSR_VEC@h
97c22435a5SPaul Mackerras	MTMSRD(r7)
98c22435a5SPaul Mackerras	isync
99c22435a5SPaul Mackerras	rlwinm	r3,r3,3,0xf8
100c22435a5SPaul Mackerras	bcl	20,31,1f
1014716e488SPaul Mackerrasreg = 0
1020016a4cfSPaul Mackerras	.rept	32
103c22435a5SPaul Mackerras	lvx	reg, 0, r4
104c22435a5SPaul Mackerras	b	2f
105c22435a5SPaul Mackerrasreg = reg + 1
106c22435a5SPaul Mackerras	.endr
1070016a4cfSPaul Mackerras1:	mflr	r5
1080016a4cfSPaul Mackerras	add	r5,r3,r5
1090016a4cfSPaul Mackerras	mtctr	r5
1104716e488SPaul Mackerras	mtlr	r0
1110016a4cfSPaul Mackerras	bctr
1120016a4cfSPaul Mackerras2:	MTMSRD(r6)
1130016a4cfSPaul Mackerras	isync
114c22435a5SPaul Mackerras	blr
1150016a4cfSPaul Mackerras#endif /* CONFIG_ALTIVEC */
1160016a4cfSPaul Mackerras
1170016a4cfSPaul Mackerras#ifdef CONFIG_VSX
1180016a4cfSPaul Mackerras/* Get the contents of vsN into vs0; N is in r3. */
1190016a4cfSPaul Mackerras_GLOBAL(get_vsr)
120df99e6ebSAnton Blanchard	mflr	r0
1210016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0x1f8
1220016a4cfSPaul Mackerras	bcl	20,31,1f
1230016a4cfSPaul Mackerras	blr			/* vs0 is already in vs0 */
1240016a4cfSPaul Mackerras	nop
125df99e6ebSAnton Blanchardreg = 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
1370016a4cfSPaul Mackerras/* Put the contents of vs0 into vsN; N is in r3. */
1380016a4cfSPaul Mackerras_GLOBAL(put_vsr)
139df99e6ebSAnton Blanchard	mflr	r0
1400016a4cfSPaul Mackerras	rlwinm	r3,r3,3,0x1f8
1410016a4cfSPaul Mackerras	bcl	20,31,1f
1420016a4cfSPaul Mackerras	blr			/* v0 is already in v0 */
1430016a4cfSPaul Mackerras	nop
144c2ce6f9fSAnton Blanchardreg = 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. */
1570016a4cfSPaul Mackerras_GLOBAL(load_vsrn)
1580016a4cfSPaul Mackerras	PPC_STLU r1,-STKFRM(r1)
159350779a2SPaul 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
1650016a4cfSPaul Mackerras	MTMSRD(r7)
1660016a4cfSPaul Mackerras	isync
167cd64d169SSean MacLennan	beq	cr7,1f
1680016a4cfSPaul Mackerras	STXVD2X(0,R1,R8)
1690016a4cfSPaul Mackerras1:	LXVD2X(0,R0,R4)
170c75df6f9SMichael Neuling#ifdef __LITTLE_ENDIAN__
171350779a2SPaul Mackerras	XXSWAPD(0,0)
172350779a2SPaul Mackerras#endif
173350779a2SPaul Mackerras	beq	cr7,4f
174350779a2SPaul Mackerras	bl	put_vsr
175350779a2SPaul Mackerras	LXVD2X(0,R1,R8)
1760016a4cfSPaul Mackerras4:	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
177c75df6f9SMichael Neuling	mtlr	r0
1780016a4cfSPaul Mackerras	MTMSRD(r6)
1790016a4cfSPaul Mackerras	isync
180cd64d169SSean MacLennan	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. */
1840016a4cfSPaul Mackerras_GLOBAL(store_vsrn)
1850016a4cfSPaul Mackerras	PPC_STLU r1,-STKFRM(r1)
186350779a2SPaul 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
1910016a4cfSPaul Mackerras	MTMSRD(r7)
1920016a4cfSPaul Mackerras	isync
193cd64d169SSean MacLennan	STXVD2X(0,R1,R8)
1940016a4cfSPaul Mackerras	bl	get_vsr
195c75df6f9SMichael Neuling#ifdef __LITTLE_ENDIAN__
1960016a4cfSPaul Mackerras	XXSWAPD(0,0)
197350779a2SPaul Mackerras#endif
198350779a2SPaul Mackerras	STXVD2X(0,R0,R4)
199350779a2SPaul Mackerras	LXVD2X(0,R1,R8)
200350779a2SPaul Mackerras	PPC_LL	r0,STKFRM+PPC_LR_STKOFF(r1)
201c75df6f9SMichael Neuling	mtlr	r0
202350779a2SPaul Mackerras	MTMSRD(r6)
2030016a4cfSPaul Mackerras	isync
204cd64d169SSean MacLennan	mr	r3,r9
2050016a4cfSPaul Mackerras	addi	r1,r1,STKFRM
2060016a4cfSPaul Mackerras	blr
2070016a4cfSPaul Mackerras#endif /* CONFIG_VSX */
2080016a4cfSPaul Mackerras
2090016a4cfSPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */
210cd64d169SSean MacLennan/* 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
238350779a2SPaul Mackerras