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 --- |