1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 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> 7 */ 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> 14 #include <asm/asm-compat.h> 15 #include <linux/errno.h> 16 17 #define STKFRM (PPC_MIN_STKFRM + 16) 18 19 /* Get the contents of frN into *p; N is in r3 and p is in r4. */ 20 _GLOBAL(get_fpr) 21 mflr r0 22 mfmsr r6 23 ori r7, r6, MSR_FP 24 MTMSRD(r7) 25 isync 26 rlwinm r3,r3,3,0xf8 27 bcl 20,31,1f 28 reg = 0 29 .rept 32 30 stfd reg, 0(r4) 31 b 2f 32 reg = reg + 1 33 .endr 34 1: mflr r5 35 add r5,r3,r5 36 mtctr r5 37 mtlr r0 38 bctr 39 2: MTMSRD(r6) 40 isync 41 blr 42 43 /* Put the contents of *p into frN; N is in r3 and p is in r4. */ 44 _GLOBAL(put_fpr) 45 mflr r0 46 mfmsr r6 47 ori r7, r6, MSR_FP 48 MTMSRD(r7) 49 isync 50 rlwinm r3,r3,3,0xf8 51 bcl 20,31,1f 52 reg = 0 53 .rept 32 54 lfd reg, 0(r4) 55 b 2f 56 reg = reg + 1 57 .endr 58 1: mflr r5 59 add r5,r3,r5 60 mtctr r5 61 mtlr r0 62 bctr 63 2: MTMSRD(r6) 64 isync 65 blr 66 67 #ifdef CONFIG_ALTIVEC 68 /* Get the contents of vrN into *p; N is in r3 and p is in r4. */ 69 _GLOBAL(get_vr) 70 mflr r0 71 mfmsr r6 72 oris r7, r6, MSR_VEC@h 73 MTMSRD(r7) 74 isync 75 rlwinm r3,r3,3,0xf8 76 bcl 20,31,1f 77 reg = 0 78 .rept 32 79 stvx reg, 0, r4 80 b 2f 81 reg = reg + 1 82 .endr 83 1: mflr r5 84 add r5,r3,r5 85 mtctr r5 86 mtlr r0 87 bctr 88 2: MTMSRD(r6) 89 isync 90 blr 91 92 /* Put the contents of *p into vrN; N is in r3 and p is in r4. */ 93 _GLOBAL(put_vr) 94 mflr r0 95 mfmsr r6 96 oris r7, r6, MSR_VEC@h 97 MTMSRD(r7) 98 isync 99 rlwinm r3,r3,3,0xf8 100 bcl 20,31,1f 101 reg = 0 102 .rept 32 103 lvx reg, 0, r4 104 b 2f 105 reg = reg + 1 106 .endr 107 1: mflr r5 108 add r5,r3,r5 109 mtctr r5 110 mtlr r0 111 bctr 112 2: MTMSRD(r6) 113 isync 114 blr 115 #endif /* CONFIG_ALTIVEC */ 116 117 #ifdef CONFIG_VSX 118 /* Get the contents of vsN into vs0; N is in r3. */ 119 _GLOBAL(get_vsr) 120 mflr r0 121 rlwinm r3,r3,3,0x1f8 122 bcl 20,31,1f 123 blr /* vs0 is already in vs0 */ 124 nop 125 reg = 1 126 .rept 63 127 XXLOR(0,reg,reg) 128 blr 129 reg = reg + 1 130 .endr 131 1: mflr r5 132 add r5,r3,r5 133 mtctr r5 134 mtlr r0 135 bctr 136 137 /* Put the contents of vs0 into vsN; N is in r3. */ 138 _GLOBAL(put_vsr) 139 mflr r0 140 rlwinm r3,r3,3,0x1f8 141 bcl 20,31,1f 142 blr /* v0 is already in v0 */ 143 nop 144 reg = 1 145 .rept 63 146 XXLOR(reg,0,0) 147 blr 148 reg = reg + 1 149 .endr 150 1: 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. */ 157 _GLOBAL(load_vsrn) 158 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 165 MTMSRD(r7) 166 isync 167 beq cr7,1f 168 STXVD2X(0,R1,R8) 169 1: LXVD2X(0,R0,R4) 170 #ifdef __LITTLE_ENDIAN__ 171 XXSWAPD(0,0) 172 #endif 173 beq cr7,4f 174 bl put_vsr 175 LXVD2X(0,R1,R8) 176 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 177 mtlr r0 178 MTMSRD(r6) 179 isync 180 addi r1,r1,STKFRM 181 blr 182 183 /* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ 184 _GLOBAL(store_vsrn) 185 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 190 li r8,STKFRM-16 191 MTMSRD(r7) 192 isync 193 STXVD2X(0,R1,R8) 194 bl get_vsr 195 #ifdef __LITTLE_ENDIAN__ 196 XXSWAPD(0,0) 197 #endif 198 STXVD2X(0,R0,R4) 199 LXVD2X(0,R1,R8) 200 PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 201 mtlr r0 202 MTMSRD(r6) 203 isync 204 mr r3,r9 205 addi r1,r1,STKFRM 206 blr 207 #endif /* CONFIG_VSX */ 208 209 /* 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.