blob: e00abeabc54db8614318f5583610ef3f47c61c67 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Paul Mackerras0016a4c2010-06-15 14:48:58 +10002/*
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>
Paul Mackerras0016a4c2010-06-15 14:48:58 +10007 */
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>
Christophe Leroyec0c4642018-07-05 16:24:57 +000014#include <asm/asm-compat.h>
Paul Mackerras0016a4c2010-06-15 14:48:58 +100015#include <linux/errno.h>
16
17#define STKFRM (PPC_MIN_STKFRM + 16)
18
Paul Mackerrasc22435a52017-08-30 14:12:33 +100019/* Get the contents of frN into *p; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100020_GLOBAL(get_fpr)
21 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100022 mfmsr r6
23 ori r7, r6, MSR_FP
24 MTMSRD(r7)
25 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100026 rlwinm r3,r3,3,0xf8
27 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100028reg = 0
29 .rept 32
30 stfd reg, 0(r4)
31 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100032reg = reg + 1
33 .endr
341: mflr r5
35 add r5,r3,r5
36 mtctr r5
37 mtlr r0
38 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000392: MTMSRD(r6)
40 isync
41 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100042
Paul Mackerrasc22435a52017-08-30 14:12:33 +100043/* Put the contents of *p into frN; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100044_GLOBAL(put_fpr)
45 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100046 mfmsr r6
47 ori r7, r6, MSR_FP
48 MTMSRD(r7)
49 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100050 rlwinm r3,r3,3,0xf8
51 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100052reg = 0
53 .rept 32
54 lfd reg, 0(r4)
55 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100056reg = reg + 1
57 .endr
581: mflr r5
59 add r5,r3,r5
60 mtctr r5
61 mtlr r0
62 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000632: MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +100064 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100065 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100066
67#ifdef CONFIG_ALTIVEC
Paul Mackerrasc22435a52017-08-30 14:12:33 +100068/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100069_GLOBAL(get_vr)
70 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100071 mfmsr r6
72 oris r7, r6, MSR_VEC@h
73 MTMSRD(r7)
74 isync
Paul Mackerras4716e482017-09-04 13:59:00 +100075 rlwinm r3,r3,3,0xf8
Paul Mackerras0016a4c2010-06-15 14:48:58 +100076 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100077reg = 0
78 .rept 32
79 stvx reg, 0, r4
80 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100081reg = reg + 1
82 .endr
831: mflr r5
Paul Mackerras4716e482017-09-04 13:59:00 +100084 add r5,r3,r5
Paul Mackerras0016a4c2010-06-15 14:48:58 +100085 mtctr r5
86 mtlr r0
87 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000882: MTMSRD(r6)
89 isync
90 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100091
Paul Mackerrasc22435a52017-08-30 14:12:33 +100092/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100093_GLOBAL(put_vr)
94 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100095 mfmsr r6
96 oris r7, r6, MSR_VEC@h
97 MTMSRD(r7)
98 isync
Paul Mackerras4716e482017-09-04 13:59:00 +100099 rlwinm r3,r3,3,0xf8
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000100 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000101reg = 0
102 .rept 32
103 lvx reg, 0, r4
104 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000105reg = reg + 1
106 .endr
1071: mflr r5
Paul Mackerras4716e482017-09-04 13:59:00 +1000108 add r5,r3,r5
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000109 mtctr r5
110 mtlr r0
111 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +10001122: MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000113 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000114 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000115#endif /* CONFIG_ALTIVEC */
116
117#ifdef CONFIG_VSX
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100118/* Get the contents of vsN into vs0; N is in r3. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000119_GLOBAL(get_vsr)
120 mflr r0
121 rlwinm r3,r3,3,0x1f8
122 bcl 20,31,1f
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100123 blr /* vs0 is already in vs0 */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000124 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
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100137/* Put the contents of vs0 into vsN; N is in r3. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000138_GLOBAL(put_vsr)
139 mflr r0
140 rlwinm r3,r3,3,0x1f8
141 bcl 20,31,1f
Anton Blanchardc2ce6f92015-02-10 09:51:22 +1100142 blr /* v0 is already in v0 */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000143 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. */
Paul Mackerras350779a2017-08-30 14:12:27 +1000157_GLOBAL(load_vsrn)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000158 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
Sean MacLennancd64d162010-09-01 07:21:21 +0000165 MTMSRD(r7)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000166 isync
167 beq cr7,1f
Michael Neulingc75df6f2012-06-25 13:33:10 +0000168 STXVD2X(0,R1,R8)
Paul Mackerras350779a2017-08-30 14:12:27 +10001691: LXVD2X(0,R0,R4)
170#ifdef __LITTLE_ENDIAN__
171 XXSWAPD(0,0)
172#endif
173 beq cr7,4f
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000174 bl put_vsr
Michael Neulingc75df6f2012-06-25 13:33:10 +0000175 LXVD2X(0,R1,R8)
Paul Mackerras0016a4c2010-06-15 14:48:58 +10001764: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
177 mtlr r0
Sean MacLennancd64d162010-09-01 07:21:21 +0000178 MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000179 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000180 addi r1,r1,STKFRM
181 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000182
183/* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */
Paul Mackerras350779a2017-08-30 14:12:27 +1000184_GLOBAL(store_vsrn)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000185 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
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000190 li r8,STKFRM-16
Sean MacLennancd64d162010-09-01 07:21:21 +0000191 MTMSRD(r7)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000192 isync
Michael Neulingc75df6f2012-06-25 13:33:10 +0000193 STXVD2X(0,R1,R8)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000194 bl get_vsr
Paul Mackerras350779a2017-08-30 14:12:27 +1000195#ifdef __LITTLE_ENDIAN__
196 XXSWAPD(0,0)
197#endif
198 STXVD2X(0,R0,R4)
Michael Neulingc75df6f2012-06-25 13:33:10 +0000199 LXVD2X(0,R1,R8)
Paul Mackerras350779a2017-08-30 14:12:27 +1000200 PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000201 mtlr r0
Sean MacLennancd64d162010-09-01 07:21:21 +0000202 MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000203 isync
204 mr r3,r9
205 addi r1,r1,STKFRM
206 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000207#endif /* CONFIG_VSX */
Sean MacLennancd64d162010-09-01 07:21:21 +0000208
Paul Mackerras350779a2017-08-30 14:12:27 +1000209/* 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