1*2874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 20016a4cfSPaul Mackerras/* 30016a4cfSPaul Mackerras * Floating-point, VMX/Altivec and VSX loads and stores 40016a4cfSPaul Mackerras * for use in instruction emulation. 50016a4cfSPaul Mackerras * 60016a4cfSPaul Mackerras * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> 70016a4cfSPaul Mackerras */ 80016a4cfSPaul Mackerras 90016a4cfSPaul Mackerras#include <asm/processor.h> 100016a4cfSPaul Mackerras#include <asm/ppc_asm.h> 110016a4cfSPaul Mackerras#include <asm/ppc-opcode.h> 120016a4cfSPaul Mackerras#include <asm/reg.h> 130016a4cfSPaul Mackerras#include <asm/asm-offsets.h> 14ec0c464cSChristophe Leroy#include <asm/asm-compat.h> 150016a4cfSPaul Mackerras#include <linux/errno.h> 160016a4cfSPaul Mackerras 170016a4cfSPaul Mackerras#define STKFRM (PPC_MIN_STKFRM + 16) 180016a4cfSPaul Mackerras 19c22435a5SPaul Mackerras/* Get the contents of frN into *p; N is in r3 and p is in r4. */ 200016a4cfSPaul Mackerras_GLOBAL(get_fpr) 210016a4cfSPaul Mackerras mflr r0 22c22435a5SPaul Mackerras mfmsr r6 23c22435a5SPaul Mackerras ori r7, r6, MSR_FP 24c22435a5SPaul Mackerras MTMSRD(r7) 25c22435a5SPaul Mackerras isync 260016a4cfSPaul Mackerras rlwinm r3,r3,3,0xf8 270016a4cfSPaul Mackerras bcl 20,31,1f 28c22435a5SPaul Mackerrasreg = 0 29c22435a5SPaul Mackerras .rept 32 30c22435a5SPaul Mackerras stfd reg, 0(r4) 31c22435a5SPaul Mackerras b 2f 320016a4cfSPaul Mackerrasreg = reg + 1 330016a4cfSPaul Mackerras .endr 340016a4cfSPaul Mackerras1: mflr r5 350016a4cfSPaul Mackerras add r5,r3,r5 360016a4cfSPaul Mackerras mtctr r5 370016a4cfSPaul Mackerras mtlr r0 380016a4cfSPaul Mackerras bctr 39c22435a5SPaul Mackerras2: MTMSRD(r6) 40c22435a5SPaul Mackerras isync 41c22435a5SPaul Mackerras blr 420016a4cfSPaul Mackerras 43c22435a5SPaul Mackerras/* Put the contents of *p into frN; N is in r3 and p is in r4. */ 440016a4cfSPaul Mackerras_GLOBAL(put_fpr) 450016a4cfSPaul Mackerras mflr r0 46c22435a5SPaul Mackerras mfmsr r6 47c22435a5SPaul Mackerras ori r7, r6, MSR_FP 48c22435a5SPaul Mackerras MTMSRD(r7) 49c22435a5SPaul Mackerras isync 500016a4cfSPaul Mackerras rlwinm r3,r3,3,0xf8 510016a4cfSPaul Mackerras bcl 20,31,1f 52c22435a5SPaul Mackerrasreg = 0 53c22435a5SPaul Mackerras .rept 32 54c22435a5SPaul Mackerras lfd reg, 0(r4) 55c22435a5SPaul Mackerras b 2f 560016a4cfSPaul Mackerrasreg = reg + 1 570016a4cfSPaul Mackerras .endr 580016a4cfSPaul Mackerras1: mflr r5 590016a4cfSPaul Mackerras add r5,r3,r5 600016a4cfSPaul Mackerras mtctr r5 610016a4cfSPaul Mackerras mtlr r0 620016a4cfSPaul Mackerras bctr 63c22435a5SPaul Mackerras2: MTMSRD(r6) 640016a4cfSPaul Mackerras isync 650016a4cfSPaul Mackerras blr 660016a4cfSPaul Mackerras 670016a4cfSPaul Mackerras#ifdef CONFIG_ALTIVEC 68c22435a5SPaul Mackerras/* Get the contents of vrN into *p; N is in r3 and p is in r4. */ 690016a4cfSPaul Mackerras_GLOBAL(get_vr) 700016a4cfSPaul Mackerras mflr r0 71c22435a5SPaul Mackerras mfmsr r6 72c22435a5SPaul Mackerras oris r7, r6, MSR_VEC@h 73c22435a5SPaul Mackerras MTMSRD(r7) 74c22435a5SPaul Mackerras isync 754716e488SPaul Mackerras rlwinm r3,r3,3,0xf8 760016a4cfSPaul Mackerras bcl 20,31,1f 77c22435a5SPaul Mackerrasreg = 0 78c22435a5SPaul Mackerras .rept 32 79c22435a5SPaul Mackerras stvx reg, 0, r4 80c22435a5SPaul Mackerras b 2f 810016a4cfSPaul Mackerrasreg = reg + 1 820016a4cfSPaul Mackerras .endr 830016a4cfSPaul Mackerras1: mflr r5 844716e488SPaul Mackerras add r5,r3,r5 850016a4cfSPaul Mackerras mtctr r5 860016a4cfSPaul Mackerras mtlr r0 870016a4cfSPaul Mackerras bctr 88c22435a5SPaul Mackerras2: MTMSRD(r6) 89c22435a5SPaul Mackerras isync 90c22435a5SPaul Mackerras blr 910016a4cfSPaul Mackerras 92c22435a5SPaul Mackerras/* Put the contents of *p into vrN; N is in r3 and p is in r4. */ 930016a4cfSPaul Mackerras_GLOBAL(put_vr) 940016a4cfSPaul Mackerras mflr r0 95c22435a5SPaul Mackerras mfmsr r6 96c22435a5SPaul Mackerras oris r7, r6, MSR_VEC@h 97c22435a5SPaul Mackerras MTMSRD(r7) 98c22435a5SPaul Mackerras isync 994716e488SPaul Mackerras rlwinm r3,r3,3,0xf8 1000016a4cfSPaul Mackerras bcl 20,31,1f 101c22435a5SPaul Mackerrasreg = 0 102c22435a5SPaul Mackerras .rept 32 103c22435a5SPaul Mackerras lvx reg, 0, r4 104c22435a5SPaul Mackerras b 2f 1050016a4cfSPaul Mackerrasreg = reg + 1 1060016a4cfSPaul Mackerras .endr 1070016a4cfSPaul Mackerras1: mflr r5 1084716e488SPaul Mackerras add r5,r3,r5 1090016a4cfSPaul Mackerras mtctr r5 1100016a4cfSPaul Mackerras mtlr r0 1110016a4cfSPaul Mackerras bctr 112c22435a5SPaul Mackerras2: MTMSRD(r6) 1130016a4cfSPaul Mackerras isync 1140016a4cfSPaul Mackerras blr 1150016a4cfSPaul Mackerras#endif /* CONFIG_ALTIVEC */ 1160016a4cfSPaul Mackerras 1170016a4cfSPaul Mackerras#ifdef CONFIG_VSX 118df99e6ebSAnton Blanchard/* Get the contents of vsN into vs0; N is in r3. */ 1190016a4cfSPaul Mackerras_GLOBAL(get_vsr) 1200016a4cfSPaul Mackerras mflr r0 1210016a4cfSPaul Mackerras rlwinm r3,r3,3,0x1f8 1220016a4cfSPaul Mackerras bcl 20,31,1f 123df99e6ebSAnton Blanchard blr /* vs0 is already in vs0 */ 1240016a4cfSPaul Mackerras nop 1250016a4cfSPaul Mackerrasreg = 1 1260016a4cfSPaul Mackerras .rept 63 1270016a4cfSPaul Mackerras XXLOR(0,reg,reg) 1280016a4cfSPaul Mackerras blr 1290016a4cfSPaul Mackerrasreg = reg + 1 1300016a4cfSPaul Mackerras .endr 1310016a4cfSPaul Mackerras1: mflr r5 1320016a4cfSPaul Mackerras add r5,r3,r5 1330016a4cfSPaul Mackerras mtctr r5 1340016a4cfSPaul Mackerras mtlr r0 1350016a4cfSPaul Mackerras bctr 1360016a4cfSPaul Mackerras 137df99e6ebSAnton Blanchard/* Put the contents of vs0 into vsN; N is in r3. */ 1380016a4cfSPaul Mackerras_GLOBAL(put_vsr) 1390016a4cfSPaul Mackerras mflr r0 1400016a4cfSPaul Mackerras rlwinm r3,r3,3,0x1f8 1410016a4cfSPaul Mackerras bcl 20,31,1f 142c2ce6f9fSAnton Blanchard blr /* v0 is already in v0 */ 1430016a4cfSPaul Mackerras nop 1440016a4cfSPaul Mackerrasreg = 1 1450016a4cfSPaul Mackerras .rept 63 1460016a4cfSPaul Mackerras XXLOR(reg,0,0) 1470016a4cfSPaul Mackerras blr 1480016a4cfSPaul Mackerrasreg = reg + 1 1490016a4cfSPaul Mackerras .endr 1500016a4cfSPaul Mackerras1: mflr r5 1510016a4cfSPaul Mackerras add r5,r3,r5 1520016a4cfSPaul Mackerras mtctr r5 1530016a4cfSPaul Mackerras mtlr r0 1540016a4cfSPaul Mackerras bctr 1550016a4cfSPaul Mackerras 1560016a4cfSPaul Mackerras/* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */ 157350779a2SPaul Mackerras_GLOBAL(load_vsrn) 1580016a4cfSPaul Mackerras PPC_STLU r1,-STKFRM(r1) 1590016a4cfSPaul Mackerras mflr r0 1600016a4cfSPaul Mackerras PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) 1610016a4cfSPaul Mackerras mfmsr r6 1620016a4cfSPaul Mackerras oris r7,r6,MSR_VSX@h 1630016a4cfSPaul Mackerras cmpwi cr7,r3,0 1640016a4cfSPaul Mackerras li r8,STKFRM-16 165cd64d169SSean MacLennan MTMSRD(r7) 1660016a4cfSPaul Mackerras isync 1670016a4cfSPaul Mackerras beq cr7,1f 168c75df6f9SMichael Neuling STXVD2X(0,R1,R8) 169350779a2SPaul Mackerras1: LXVD2X(0,R0,R4) 170350779a2SPaul Mackerras#ifdef __LITTLE_ENDIAN__ 171350779a2SPaul Mackerras XXSWAPD(0,0) 172350779a2SPaul Mackerras#endif 173350779a2SPaul Mackerras beq cr7,4f 1740016a4cfSPaul Mackerras bl put_vsr 175c75df6f9SMichael Neuling LXVD2X(0,R1,R8) 1760016a4cfSPaul Mackerras4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 1770016a4cfSPaul Mackerras mtlr r0 178cd64d169SSean MacLennan MTMSRD(r6) 1790016a4cfSPaul Mackerras isync 1800016a4cfSPaul Mackerras addi r1,r1,STKFRM 1810016a4cfSPaul Mackerras blr 1820016a4cfSPaul Mackerras 1830016a4cfSPaul Mackerras/* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ 184350779a2SPaul Mackerras_GLOBAL(store_vsrn) 1850016a4cfSPaul Mackerras PPC_STLU r1,-STKFRM(r1) 1860016a4cfSPaul Mackerras mflr r0 1870016a4cfSPaul Mackerras PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) 1880016a4cfSPaul Mackerras mfmsr r6 1890016a4cfSPaul Mackerras oris r7,r6,MSR_VSX@h 1900016a4cfSPaul Mackerras li r8,STKFRM-16 191cd64d169SSean MacLennan MTMSRD(r7) 1920016a4cfSPaul Mackerras isync 193c75df6f9SMichael Neuling STXVD2X(0,R1,R8) 1940016a4cfSPaul Mackerras bl get_vsr 195350779a2SPaul Mackerras#ifdef __LITTLE_ENDIAN__ 196350779a2SPaul Mackerras XXSWAPD(0,0) 197350779a2SPaul Mackerras#endif 198350779a2SPaul Mackerras STXVD2X(0,R0,R4) 199c75df6f9SMichael Neuling LXVD2X(0,R1,R8) 200350779a2SPaul Mackerras PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 2010016a4cfSPaul Mackerras mtlr r0 202cd64d169SSean MacLennan MTMSRD(r6) 2030016a4cfSPaul Mackerras isync 2040016a4cfSPaul Mackerras mr r3,r9 2050016a4cfSPaul Mackerras addi r1,r1,STKFRM 2060016a4cfSPaul Mackerras blr 2070016a4cfSPaul Mackerras#endif /* CONFIG_VSX */ 208cd64d169SSean MacLennan 209350779a2SPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */ 210350779a2SPaul Mackerras/* conv_sp_to_dp(float *sp, double *dp) */ 211350779a2SPaul Mackerras_GLOBAL(conv_sp_to_dp) 212350779a2SPaul Mackerras mfmsr r6 213350779a2SPaul Mackerras ori r7, r6, MSR_FP 214350779a2SPaul Mackerras MTMSRD(r7) 215350779a2SPaul Mackerras isync 216350779a2SPaul Mackerras stfd fr0, -16(r1) 217350779a2SPaul Mackerras lfs fr0, 0(r3) 218350779a2SPaul Mackerras stfd fr0, 0(r4) 219350779a2SPaul Mackerras lfd fr0, -16(r1) 220350779a2SPaul Mackerras MTMSRD(r6) 221350779a2SPaul Mackerras isync 222350779a2SPaul Mackerras blr 223350779a2SPaul Mackerras 224350779a2SPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */ 225350779a2SPaul Mackerras/* conv_sp_to_dp(double *dp, float *sp) */ 226350779a2SPaul Mackerras_GLOBAL(conv_dp_to_sp) 227350779a2SPaul Mackerras mfmsr r6 228350779a2SPaul Mackerras ori r7, r6, MSR_FP 229350779a2SPaul Mackerras MTMSRD(r7) 230350779a2SPaul Mackerras isync 231350779a2SPaul Mackerras stfd fr0, -16(r1) 232350779a2SPaul Mackerras lfd fr0, 0(r3) 233350779a2SPaul Mackerras stfs fr0, 0(r4) 234350779a2SPaul Mackerras lfd fr0, -16(r1) 235350779a2SPaul Mackerras MTMSRD(r6) 236350779a2SPaul Mackerras isync 237350779a2SPaul Mackerras blr 238