Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/lib/ldstfp.S
10817 views
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. <[email protected]>
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
20
#ifdef CONFIG_PPC_FPU
21
22
#define STKFRM (PPC_MIN_STKFRM + 16)
23
24
.macro extab instr,handler
25
.section __ex_table,"a"
26
PPC_LONG \instr,\handler
27
.previous
28
.endm
29
30
.macro inst32 op
31
reg = 0
32
.rept 32
33
20: \op reg,0,r4
34
b 3f
35
extab 20b,99f
36
reg = reg + 1
37
.endr
38
.endm
39
40
/* Get the contents of frN into fr0; N is in r3. */
41
_GLOBAL(get_fpr)
42
mflr r0
43
rlwinm r3,r3,3,0xf8
44
bcl 20,31,1f
45
blr /* fr0 is already in fr0 */
46
nop
47
reg = 1
48
.rept 31
49
fmr fr0,reg
50
blr
51
reg = reg + 1
52
.endr
53
1: mflr r5
54
add r5,r3,r5
55
mtctr r5
56
mtlr r0
57
bctr
58
59
/* Put the contents of fr0 into frN; N is in r3. */
60
_GLOBAL(put_fpr)
61
mflr r0
62
rlwinm r3,r3,3,0xf8
63
bcl 20,31,1f
64
blr /* fr0 is already in fr0 */
65
nop
66
reg = 1
67
.rept 31
68
fmr reg,fr0
69
blr
70
reg = reg + 1
71
.endr
72
1: mflr r5
73
add r5,r3,r5
74
mtctr r5
75
mtlr r0
76
bctr
77
78
/* Load FP reg N from float at *p. N is in r3, p in r4. */
79
_GLOBAL(do_lfs)
80
PPC_STLU r1,-STKFRM(r1)
81
mflr r0
82
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
83
mfmsr r6
84
ori r7,r6,MSR_FP
85
cmpwi cr7,r3,0
86
MTMSRD(r7)
87
isync
88
beq cr7,1f
89
stfd fr0,STKFRM-16(r1)
90
1: li r9,-EFAULT
91
2: lfs fr0,0(r4)
92
li r9,0
93
3: bl put_fpr
94
beq cr7,4f
95
lfd fr0,STKFRM-16(r1)
96
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
97
mtlr r0
98
MTMSRD(r6)
99
isync
100
mr r3,r9
101
addi r1,r1,STKFRM
102
blr
103
extab 2b,3b
104
105
/* Load FP reg N from double at *p. N is in r3, p in r4. */
106
_GLOBAL(do_lfd)
107
PPC_STLU r1,-STKFRM(r1)
108
mflr r0
109
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
110
mfmsr r6
111
ori r7,r6,MSR_FP
112
cmpwi cr7,r3,0
113
MTMSRD(r7)
114
isync
115
beq cr7,1f
116
stfd fr0,STKFRM-16(r1)
117
1: li r9,-EFAULT
118
2: lfd fr0,0(r4)
119
li r9,0
120
3: beq cr7,4f
121
bl put_fpr
122
lfd fr0,STKFRM-16(r1)
123
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
124
mtlr r0
125
MTMSRD(r6)
126
isync
127
mr r3,r9
128
addi r1,r1,STKFRM
129
blr
130
extab 2b,3b
131
132
/* Store FP reg N to float at *p. N is in r3, p in r4. */
133
_GLOBAL(do_stfs)
134
PPC_STLU r1,-STKFRM(r1)
135
mflr r0
136
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
137
mfmsr r6
138
ori r7,r6,MSR_FP
139
cmpwi cr7,r3,0
140
MTMSRD(r7)
141
isync
142
beq cr7,1f
143
stfd fr0,STKFRM-16(r1)
144
bl get_fpr
145
1: li r9,-EFAULT
146
2: stfs fr0,0(r4)
147
li r9,0
148
3: beq cr7,4f
149
lfd fr0,STKFRM-16(r1)
150
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
151
mtlr r0
152
MTMSRD(r6)
153
isync
154
mr r3,r9
155
addi r1,r1,STKFRM
156
blr
157
extab 2b,3b
158
159
/* Store FP reg N to double at *p. N is in r3, p in r4. */
160
_GLOBAL(do_stfd)
161
PPC_STLU r1,-STKFRM(r1)
162
mflr r0
163
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
164
mfmsr r6
165
ori r7,r6,MSR_FP
166
cmpwi cr7,r3,0
167
MTMSRD(r7)
168
isync
169
beq cr7,1f
170
stfd fr0,STKFRM-16(r1)
171
bl get_fpr
172
1: li r9,-EFAULT
173
2: stfd fr0,0(r4)
174
li r9,0
175
3: beq cr7,4f
176
lfd fr0,STKFRM-16(r1)
177
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
178
mtlr r0
179
MTMSRD(r6)
180
isync
181
mr r3,r9
182
addi r1,r1,STKFRM
183
blr
184
extab 2b,3b
185
186
#ifdef CONFIG_ALTIVEC
187
/* Get the contents of vrN into vr0; N is in r3. */
188
_GLOBAL(get_vr)
189
mflr r0
190
rlwinm r3,r3,3,0xf8
191
bcl 20,31,1f
192
blr /* vr0 is already in vr0 */
193
nop
194
reg = 1
195
.rept 31
196
vor vr0,reg,reg /* assembler doesn't know vmr? */
197
blr
198
reg = reg + 1
199
.endr
200
1: mflr r5
201
add r5,r3,r5
202
mtctr r5
203
mtlr r0
204
bctr
205
206
/* Put the contents of vr0 into vrN; N is in r3. */
207
_GLOBAL(put_vr)
208
mflr r0
209
rlwinm r3,r3,3,0xf8
210
bcl 20,31,1f
211
blr /* vr0 is already in vr0 */
212
nop
213
reg = 1
214
.rept 31
215
vor reg,vr0,vr0
216
blr
217
reg = reg + 1
218
.endr
219
1: mflr r5
220
add r5,r3,r5
221
mtctr r5
222
mtlr r0
223
bctr
224
225
/* Load vector reg N from *p. N is in r3, p in r4. */
226
_GLOBAL(do_lvx)
227
PPC_STLU r1,-STKFRM(r1)
228
mflr r0
229
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
230
mfmsr r6
231
oris r7,r6,MSR_VEC@h
232
cmpwi cr7,r3,0
233
li r8,STKFRM-16
234
MTMSRD(r7)
235
isync
236
beq cr7,1f
237
stvx vr0,r1,r8
238
1: li r9,-EFAULT
239
2: lvx vr0,0,r4
240
li r9,0
241
3: beq cr7,4f
242
bl put_vr
243
lvx vr0,r1,r8
244
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
245
mtlr r0
246
MTMSRD(r6)
247
isync
248
mr r3,r9
249
addi r1,r1,STKFRM
250
blr
251
extab 2b,3b
252
253
/* Store vector reg N to *p. N is in r3, p in r4. */
254
_GLOBAL(do_stvx)
255
PPC_STLU r1,-STKFRM(r1)
256
mflr r0
257
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
258
mfmsr r6
259
oris r7,r6,MSR_VEC@h
260
cmpwi cr7,r3,0
261
li r8,STKFRM-16
262
MTMSRD(r7)
263
isync
264
beq cr7,1f
265
stvx vr0,r1,r8
266
bl get_vr
267
1: li r9,-EFAULT
268
2: stvx vr0,0,r4
269
li r9,0
270
3: beq cr7,4f
271
lvx vr0,r1,r8
272
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
273
mtlr r0
274
MTMSRD(r6)
275
isync
276
mr r3,r9
277
addi r1,r1,STKFRM
278
blr
279
extab 2b,3b
280
#endif /* CONFIG_ALTIVEC */
281
282
#ifdef CONFIG_VSX
283
/* Get the contents of vsrN into vsr0; N is in r3. */
284
_GLOBAL(get_vsr)
285
mflr r0
286
rlwinm r3,r3,3,0x1f8
287
bcl 20,31,1f
288
blr /* vsr0 is already in vsr0 */
289
nop
290
reg = 1
291
.rept 63
292
XXLOR(0,reg,reg)
293
blr
294
reg = reg + 1
295
.endr
296
1: mflr r5
297
add r5,r3,r5
298
mtctr r5
299
mtlr r0
300
bctr
301
302
/* Put the contents of vsr0 into vsrN; N is in r3. */
303
_GLOBAL(put_vsr)
304
mflr r0
305
rlwinm r3,r3,3,0x1f8
306
bcl 20,31,1f
307
blr /* vr0 is already in vr0 */
308
nop
309
reg = 1
310
.rept 63
311
XXLOR(reg,0,0)
312
blr
313
reg = reg + 1
314
.endr
315
1: mflr r5
316
add r5,r3,r5
317
mtctr r5
318
mtlr r0
319
bctr
320
321
/* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */
322
_GLOBAL(do_lxvd2x)
323
PPC_STLU r1,-STKFRM(r1)
324
mflr r0
325
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
326
mfmsr r6
327
oris r7,r6,MSR_VSX@h
328
cmpwi cr7,r3,0
329
li r8,STKFRM-16
330
MTMSRD(r7)
331
isync
332
beq cr7,1f
333
STXVD2X(0,r1,r8)
334
1: li r9,-EFAULT
335
2: LXVD2X(0,0,r4)
336
li r9,0
337
3: beq cr7,4f
338
bl put_vsr
339
LXVD2X(0,r1,r8)
340
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
341
mtlr r0
342
MTMSRD(r6)
343
isync
344
mr r3,r9
345
addi r1,r1,STKFRM
346
blr
347
extab 2b,3b
348
349
/* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */
350
_GLOBAL(do_stxvd2x)
351
PPC_STLU r1,-STKFRM(r1)
352
mflr r0
353
PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
354
mfmsr r6
355
oris r7,r6,MSR_VSX@h
356
cmpwi cr7,r3,0
357
li r8,STKFRM-16
358
MTMSRD(r7)
359
isync
360
beq cr7,1f
361
STXVD2X(0,r1,r8)
362
bl get_vsr
363
1: li r9,-EFAULT
364
2: STXVD2X(0,0,r4)
365
li r9,0
366
3: beq cr7,4f
367
LXVD2X(0,r1,r8)
368
4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
369
mtlr r0
370
MTMSRD(r6)
371
isync
372
mr r3,r9
373
addi r1,r1,STKFRM
374
blr
375
extab 2b,3b
376
377
#endif /* CONFIG_VSX */
378
379
#endif /* CONFIG_PPC_FPU */
380
381