ldstfp.S (350779a29f11f80ac66a8b38a7718ad30f003f18) ldstfp.S (c22435a5f3d8f85ea162ae523a6ba60a58521ba5)
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

--- 7 unchanged lines hidden (view full) ---

16#include <asm/reg.h>
17#include <asm/asm-offsets.h>
18#include <linux/errno.h>
19
20#ifdef CONFIG_PPC_FPU
21
22#define STKFRM (PPC_MIN_STKFRM + 16)
23
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

--- 7 unchanged lines hidden (view full) ---

16#include <asm/reg.h>
17#include <asm/asm-offsets.h>
18#include <linux/errno.h>
19
20#ifdef CONFIG_PPC_FPU
21
22#define STKFRM (PPC_MIN_STKFRM + 16)
23
24 .macro inst32 op
25reg = 0
26 .rept 32
2720: \op reg,0,r4
28 b 3f
29 EX_TABLE(20b,99f)
30reg = reg + 1
31 .endr
32 .endm
33
34/* Get the contents of frN into fr0; N is in r3. */
24/* Get the contents of frN into *p; N is in r3 and p is in r4. */
35_GLOBAL(get_fpr)
36 mflr r0
25_GLOBAL(get_fpr)
26 mflr r0
27 mfmsr r6
28 ori r7, r6, MSR_FP
29 MTMSRD(r7)
30 isync
37 rlwinm r3,r3,3,0xf8
38 bcl 20,31,1f
31 rlwinm r3,r3,3,0xf8
32 bcl 20,31,1f
39 blr /* fr0 is already in fr0 */
40 nop
41reg = 1
42 .rept 31
43 fmr fr0,reg
44 blr
33reg = 0
34 .rept 32
35 stfd reg, 0(r4)
36 b 2f
45reg = reg + 1
46 .endr
471: mflr r5
48 add r5,r3,r5
49 mtctr r5
50 mtlr r0
51 bctr
37reg = reg + 1
38 .endr
391: mflr r5
40 add r5,r3,r5
41 mtctr r5
42 mtlr r0
43 bctr
442: MTMSRD(r6)
45 isync
46 blr
52
47
53/* Put the contents of fr0 into frN; N is in r3. */
48/* Put the contents of *p into frN; N is in r3 and p is in r4. */
54_GLOBAL(put_fpr)
55 mflr r0
49_GLOBAL(put_fpr)
50 mflr r0
51 mfmsr r6
52 ori r7, r6, MSR_FP
53 MTMSRD(r7)
54 isync
56 rlwinm r3,r3,3,0xf8
57 bcl 20,31,1f
55 rlwinm r3,r3,3,0xf8
56 bcl 20,31,1f
58 blr /* fr0 is already in fr0 */
59 nop
60reg = 1
61 .rept 31
62 fmr reg,fr0
63 blr
57reg = 0
58 .rept 32
59 lfd reg, 0(r4)
60 b 2f
64reg = reg + 1
65 .endr
661: mflr r5
67 add r5,r3,r5
68 mtctr r5
69 mtlr r0
70 bctr
61reg = reg + 1
62 .endr
631: mflr r5
64 add r5,r3,r5
65 mtctr r5
66 mtlr r0
67 bctr
71
72/* Load FP reg N from float at *p. N is in r3, p in r4. */
73_GLOBAL(do_lfs)
74 PPC_STLU r1,-STKFRM(r1)
75 mflr r0
76 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
77 mfmsr r6
78 ori r7,r6,MSR_FP
79 cmpwi cr7,r3,0
80 MTMSRD(r7)
682: MTMSRD(r6)
81 isync
69 isync
82 beq cr7,1f
83 stfd fr0,STKFRM-16(r1)
841: li r9,-EFAULT
852: lfs fr0,0(r4)
86 li r9,0
873: bl put_fpr
88 beq cr7,4f
89 lfd fr0,STKFRM-16(r1)
904: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
91 mtlr r0
92 MTMSRD(r6)
93 isync
94 mr r3,r9
95 addi r1,r1,STKFRM
96 blr
70 blr
97 EX_TABLE(2b,3b)
98
71
99/* Load FP reg N from double at *p. N is in r3, p in r4. */
100_GLOBAL(do_lfd)
101 PPC_STLU r1,-STKFRM(r1)
72#ifdef CONFIG_ALTIVEC
73/* Get the contents of vrN into *p; N is in r3 and p is in r4. */
74_GLOBAL(get_vr)
102 mflr r0
75 mflr r0
103 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
104 mfmsr r6
76 mfmsr r6
105 ori r7,r6,MSR_FP
106 cmpwi cr7,r3,0
77 oris r7, r6, MSR_VEC@h
107 MTMSRD(r7)
108 isync
78 MTMSRD(r7)
79 isync
109 beq cr7,1f
110 stfd fr0,STKFRM-16(r1)
1111: li r9,-EFAULT
1122: lfd fr0,0(r4)
113 li r9,0
1143: beq cr7,4f
115 bl put_fpr
116 lfd fr0,STKFRM-16(r1)
1174: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
118 mtlr r0
119 MTMSRD(r6)
120 isync
121 mr r3,r9
122 addi r1,r1,STKFRM
123 blr
124 EX_TABLE(2b,3b)
125
126/* Store FP reg N to float at *p. N is in r3, p in r4. */
127_GLOBAL(do_stfs)
128 PPC_STLU r1,-STKFRM(r1)
129 mflr r0
130 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
131 mfmsr r6
132 ori r7,r6,MSR_FP
133 cmpwi cr7,r3,0
134 MTMSRD(r7)
135 isync
136 beq cr7,1f
137 stfd fr0,STKFRM-16(r1)
138 bl get_fpr
1391: li r9,-EFAULT
1402: stfs fr0,0(r4)
141 li r9,0
1423: beq cr7,4f
143 lfd fr0,STKFRM-16(r1)
1444: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
145 mtlr r0
146 MTMSRD(r6)
147 isync
148 mr r3,r9
149 addi r1,r1,STKFRM
150 blr
151 EX_TABLE(2b,3b)
152
153/* Store FP reg N to double at *p. N is in r3, p in r4. */
154_GLOBAL(do_stfd)
155 PPC_STLU r1,-STKFRM(r1)
156 mflr r0
157 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
158 mfmsr r6
159 ori r7,r6,MSR_FP
160 cmpwi cr7,r3,0
161 MTMSRD(r7)
162 isync
163 beq cr7,1f
164 stfd fr0,STKFRM-16(r1)
165 bl get_fpr
1661: li r9,-EFAULT
1672: stfd fr0,0(r4)
168 li r9,0
1693: beq cr7,4f
170 lfd fr0,STKFRM-16(r1)
1714: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
172 mtlr r0
173 MTMSRD(r6)
174 isync
175 mr r3,r9
176 addi r1,r1,STKFRM
177 blr
178 EX_TABLE(2b,3b)
179
180#ifdef CONFIG_ALTIVEC
181/* Get the contents of vrN into v0; N is in r3. Doesn't touch r3 or r4. */
182_GLOBAL(get_vr)
183 mflr r0
184 rlwinm r6,r3,3,0xf8
185 bcl 20,31,1f
80 rlwinm r6,r3,3,0xf8
81 bcl 20,31,1f
186 blr /* v0 is already in v0 */
187 nop
188reg = 1
189 .rept 31
190 vor v0,reg,reg /* assembler doesn't know vmr? */
191 blr
82reg = 0
83 .rept 32
84 stvx reg, 0, r4
85 b 2f
192reg = reg + 1
193 .endr
1941: mflr r5
195 add r5,r6,r5
196 mtctr r5
197 mtlr r0
198 bctr
86reg = reg + 1
87 .endr
881: mflr r5
89 add r5,r6,r5
90 mtctr r5
91 mtlr r0
92 bctr
932: MTMSRD(r6)
94 isync
95 blr
199
96
200/* Put the contents of v0 into vrN; N is in r3. Doesn't touch r3 or r4. */
97/* Put the contents of *p into vrN; N is in r3 and p is in r4. */
201_GLOBAL(put_vr)
202 mflr r0
98_GLOBAL(put_vr)
99 mflr r0
100 mfmsr r6
101 oris r7, r6, MSR_VEC@h
102 MTMSRD(r7)
103 isync
203 rlwinm r6,r3,3,0xf8
204 bcl 20,31,1f
104 rlwinm r6,r3,3,0xf8
105 bcl 20,31,1f
205 blr /* v0 is already in v0 */
206 nop
207reg = 1
208 .rept 31
209 vor reg,v0,v0
210 blr
106reg = 0
107 .rept 32
108 lvx reg, 0, r4
109 b 2f
211reg = reg + 1
212 .endr
2131: mflr r5
214 add r5,r6,r5
215 mtctr r5
216 mtlr r0
217 bctr
110reg = reg + 1
111 .endr
1121: mflr r5
113 add r5,r6,r5
114 mtctr r5
115 mtlr r0
116 bctr
218
219/* Load vector reg N from *p. N is in r3, p in r4. */
220_GLOBAL(do_lvx)
221 PPC_STLU r1,-STKFRM(r1)
222 mflr r0
223 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
224 mfmsr r6
225 oris r7,r6,MSR_VEC@h
226 cmpwi cr7,r3,0
227 li r8,STKFRM-16
228 MTMSRD(r7)
1172: MTMSRD(r6)
229 isync
118 isync
230 beq cr7,1f
231 stvx v0,r1,r8
2321: li r9,-EFAULT
2332: lvx v0,0,r4
234 li r9,0
2353: beq cr7,4f
236 bl put_vr
237 lvx v0,r1,r8
2384: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
239 mtlr r0
240 MTMSRD(r6)
241 isync
242 mr r3,r9
243 addi r1,r1,STKFRM
244 blr
119 blr
245 EX_TABLE(2b,3b)
246
247/* Store vector reg N to *p. N is in r3, p in r4. */
248_GLOBAL(do_stvx)
249 PPC_STLU r1,-STKFRM(r1)
250 mflr r0
251 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
252 mfmsr r6
253 oris r7,r6,MSR_VEC@h
254 cmpwi cr7,r3,0
255 li r8,STKFRM-16
256 MTMSRD(r7)
257 isync
258 beq cr7,1f
259 stvx v0,r1,r8
260 bl get_vr
2611: li r9,-EFAULT
2622: stvx v0,0,r4
263 li r9,0
2643: beq cr7,4f
265 lvx v0,r1,r8
2664: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
267 mtlr r0
268 MTMSRD(r6)
269 isync
270 mr r3,r9
271 addi r1,r1,STKFRM
272 blr
273 EX_TABLE(2b,3b)
274#endif /* CONFIG_ALTIVEC */
275
276#ifdef CONFIG_VSX
277/* Get the contents of vsN into vs0; N is in r3. */
278_GLOBAL(get_vsr)
279 mflr r0
280 rlwinm r3,r3,3,0x1f8
281 bcl 20,31,1f

--- 76 unchanged lines hidden (view full) ---

358 LXVD2X(0,R1,R8)
359 PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
360 mtlr r0
361 MTMSRD(r6)
362 isync
363 mr r3,r9
364 addi r1,r1,STKFRM
365 blr
120#endif /* CONFIG_ALTIVEC */
121
122#ifdef CONFIG_VSX
123/* Get the contents of vsN into vs0; N is in r3. */
124_GLOBAL(get_vsr)
125 mflr r0
126 rlwinm r3,r3,3,0x1f8
127 bcl 20,31,1f

--- 76 unchanged lines hidden (view full) ---

204 LXVD2X(0,R1,R8)
205 PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
206 mtlr r0
207 MTMSRD(r6)
208 isync
209 mr r3,r9
210 addi r1,r1,STKFRM
211 blr
366 EX_TABLE(2b,3b)
367#endif /* CONFIG_VSX */
368
369/* Convert single-precision to double, without disturbing FPRs. */
370/* conv_sp_to_dp(float *sp, double *dp) */
371_GLOBAL(conv_sp_to_dp)
372 mfmsr r6
373 ori r7, r6, MSR_FP
374 MTMSRD(r7)

--- 25 unchanged lines hidden ---
212#endif /* CONFIG_VSX */
213
214/* 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)

--- 25 unchanged lines hidden ---