blob: ae15eba49c1fcd89b61eba5c76ad91774555cbf6 [file] [log] [blame]
Paul Mackerras0016a4c2010-06-15 14:48:58 +10001/*
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
Sean MacLennancd64d162010-09-01 07:21:21 +000020#ifdef CONFIG_PPC_FPU
21
Paul Mackerras0016a4c2010-06-15 14:48:58 +100022#define STKFRM (PPC_MIN_STKFRM + 16)
23
Paul Mackerrasc22435a52017-08-30 14:12:33 +100024/* Get the contents of frN into *p; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100025_GLOBAL(get_fpr)
26 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100027 mfmsr r6
28 ori r7, r6, MSR_FP
29 MTMSRD(r7)
30 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100031 rlwinm r3,r3,3,0xf8
32 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100033reg = 0
34 .rept 32
35 stfd reg, 0(r4)
36 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100037reg = reg + 1
38 .endr
391: mflr r5
40 add r5,r3,r5
41 mtctr r5
42 mtlr r0
43 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000442: MTMSRD(r6)
45 isync
46 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100047
Paul Mackerrasc22435a52017-08-30 14:12:33 +100048/* Put the contents of *p into frN; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100049_GLOBAL(put_fpr)
50 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100051 mfmsr r6
52 ori r7, r6, MSR_FP
53 MTMSRD(r7)
54 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100055 rlwinm r3,r3,3,0xf8
56 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100057reg = 0
58 .rept 32
59 lfd reg, 0(r4)
60 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100061reg = reg + 1
62 .endr
631: mflr r5
64 add r5,r3,r5
65 mtctr r5
66 mtlr r0
67 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000682: MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +100069 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +100070 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100071
72#ifdef CONFIG_ALTIVEC
Paul Mackerrasc22435a52017-08-30 14:12:33 +100073/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100074_GLOBAL(get_vr)
75 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +100076 mfmsr r6
77 oris r7, r6, MSR_VEC@h
78 MTMSRD(r7)
79 isync
Paul Mackerras4716e482017-09-04 13:59:00 +100080 rlwinm r3,r3,3,0xf8
Paul Mackerras0016a4c2010-06-15 14:48:58 +100081 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +100082reg = 0
83 .rept 32
84 stvx reg, 0, r4
85 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +100086reg = reg + 1
87 .endr
881: mflr r5
Paul Mackerras4716e482017-09-04 13:59:00 +100089 add r5,r3,r5
Paul Mackerras0016a4c2010-06-15 14:48:58 +100090 mtctr r5
91 mtlr r0
92 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000932: MTMSRD(r6)
94 isync
95 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +100096
Paul Mackerrasc22435a52017-08-30 14:12:33 +100097/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +100098_GLOBAL(put_vr)
99 mflr r0
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000100 mfmsr r6
101 oris r7, r6, MSR_VEC@h
102 MTMSRD(r7)
103 isync
Paul Mackerras4716e482017-09-04 13:59:00 +1000104 rlwinm r3,r3,3,0xf8
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000105 bcl 20,31,1f
Paul Mackerrasc22435a52017-08-30 14:12:33 +1000106reg = 0
107 .rept 32
108 lvx reg, 0, r4
109 b 2f
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000110reg = reg + 1
111 .endr
1121: mflr r5
Paul Mackerras4716e482017-09-04 13:59:00 +1000113 add r5,r3,r5
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000114 mtctr r5
115 mtlr r0
116 bctr
Paul Mackerrasc22435a52017-08-30 14:12:33 +10001172: MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000118 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000119 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000120#endif /* CONFIG_ALTIVEC */
121
122#ifdef CONFIG_VSX
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100123/* Get the contents of vsN into vs0; N is in r3. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000124_GLOBAL(get_vsr)
125 mflr r0
126 rlwinm r3,r3,3,0x1f8
127 bcl 20,31,1f
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100128 blr /* vs0 is already in vs0 */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000129 nop
130reg = 1
131 .rept 63
132 XXLOR(0,reg,reg)
133 blr
134reg = reg + 1
135 .endr
1361: mflr r5
137 add r5,r3,r5
138 mtctr r5
139 mtlr r0
140 bctr
141
Anton Blancharddf99e6e2015-02-10 09:51:23 +1100142/* Put the contents of vs0 into vsN; N is in r3. */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000143_GLOBAL(put_vsr)
144 mflr r0
145 rlwinm r3,r3,3,0x1f8
146 bcl 20,31,1f
Anton Blanchardc2ce6f92015-02-10 09:51:22 +1100147 blr /* v0 is already in v0 */
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000148 nop
149reg = 1
150 .rept 63
151 XXLOR(reg,0,0)
152 blr
153reg = reg + 1
154 .endr
1551: mflr r5
156 add r5,r3,r5
157 mtctr r5
158 mtlr r0
159 bctr
160
161/* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */
Paul Mackerras350779a2017-08-30 14:12:27 +1000162_GLOBAL(load_vsrn)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000163 PPC_STLU r1,-STKFRM(r1)
164 mflr r0
165 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
166 mfmsr r6
167 oris r7,r6,MSR_VSX@h
168 cmpwi cr7,r3,0
169 li r8,STKFRM-16
Sean MacLennancd64d162010-09-01 07:21:21 +0000170 MTMSRD(r7)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000171 isync
172 beq cr7,1f
Michael Neulingc75df6f2012-06-25 13:33:10 +0000173 STXVD2X(0,R1,R8)
Paul Mackerras350779a2017-08-30 14:12:27 +10001741: LXVD2X(0,R0,R4)
175#ifdef __LITTLE_ENDIAN__
176 XXSWAPD(0,0)
177#endif
178 beq cr7,4f
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000179 bl put_vsr
Michael Neulingc75df6f2012-06-25 13:33:10 +0000180 LXVD2X(0,R1,R8)
Paul Mackerras0016a4c2010-06-15 14:48:58 +10001814: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
182 mtlr r0
Sean MacLennancd64d162010-09-01 07:21:21 +0000183 MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000184 isync
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000185 addi r1,r1,STKFRM
186 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000187
188/* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */
Paul Mackerras350779a2017-08-30 14:12:27 +1000189_GLOBAL(store_vsrn)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000190 PPC_STLU r1,-STKFRM(r1)
191 mflr r0
192 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
193 mfmsr r6
194 oris r7,r6,MSR_VSX@h
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000195 li r8,STKFRM-16
Sean MacLennancd64d162010-09-01 07:21:21 +0000196 MTMSRD(r7)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000197 isync
Michael Neulingc75df6f2012-06-25 13:33:10 +0000198 STXVD2X(0,R1,R8)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000199 bl get_vsr
Paul Mackerras350779a2017-08-30 14:12:27 +1000200#ifdef __LITTLE_ENDIAN__
201 XXSWAPD(0,0)
202#endif
203 STXVD2X(0,R0,R4)
Michael Neulingc75df6f2012-06-25 13:33:10 +0000204 LXVD2X(0,R1,R8)
Paul Mackerras350779a2017-08-30 14:12:27 +1000205 PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000206 mtlr r0
Sean MacLennancd64d162010-09-01 07:21:21 +0000207 MTMSRD(r6)
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000208 isync
209 mr r3,r9
210 addi r1,r1,STKFRM
211 blr
Paul Mackerras0016a4c2010-06-15 14:48:58 +1000212#endif /* CONFIG_VSX */
Sean MacLennancd64d162010-09-01 07:21:21 +0000213
Paul Mackerras350779a2017-08-30 14:12:27 +1000214/* Convert single-precision to double, without disturbing FPRs. */
215/* conv_sp_to_dp(float *sp, double *dp) */
216_GLOBAL(conv_sp_to_dp)
217 mfmsr r6
218 ori r7, r6, MSR_FP
219 MTMSRD(r7)
220 isync
221 stfd fr0, -16(r1)
222 lfs fr0, 0(r3)
223 stfd fr0, 0(r4)
224 lfd fr0, -16(r1)
225 MTMSRD(r6)
226 isync
227 blr
228
229/* Convert single-precision to double, without disturbing FPRs. */
230/* conv_sp_to_dp(double *dp, float *sp) */
231_GLOBAL(conv_dp_to_sp)
232 mfmsr r6
233 ori r7, r6, MSR_FP
234 MTMSRD(r7)
235 isync
236 stfd fr0, -16(r1)
237 lfd fr0, 0(r3)
238 stfs fr0, 0(r4)
239 lfd fr0, -16(r1)
240 MTMSRD(r6)
241 isync
242 blr
243
Sean MacLennancd64d162010-09-01 07:21:21 +0000244#endif /* CONFIG_PPC_FPU */