12874c5fdSThomas 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 17cd64d169SSean MacLennan#define STKFRM (PPC_MIN_STKFRM + 16) 18cd64d169SSean MacLennan 190016a4cfSPaul Mackerras/* Get the contents of frN into *p; N is in r3 and p is in r4. */ 200016a4cfSPaul Mackerras_GLOBAL(get_fpr) 21c22435a5SPaul Mackerras mflr r0 220016a4cfSPaul Mackerras mfmsr r6 230016a4cfSPaul Mackerras ori r7, r6, MSR_FP 24c22435a5SPaul Mackerras MTMSRD(r7) 25c22435a5SPaul Mackerras isync 26c22435a5SPaul Mackerras rlwinm r3,r3,3,0xf8 27c22435a5SPaul Mackerras bcl 20,31,1f 280016a4cfSPaul Mackerrasreg = 0 290016a4cfSPaul Mackerras .rept 32 30c22435a5SPaul Mackerras stfd reg, 0(r4) 31c22435a5SPaul Mackerras b 2f 32c22435a5SPaul Mackerrasreg = reg + 1 33c22435a5SPaul Mackerras .endr 340016a4cfSPaul Mackerras1: mflr r5 350016a4cfSPaul Mackerras add r5,r3,r5 360016a4cfSPaul Mackerras mtctr r5 370016a4cfSPaul Mackerras mtlr r0 380016a4cfSPaul Mackerras bctr 390016a4cfSPaul Mackerras2: MTMSRD(r6) 400016a4cfSPaul Mackerras isync 41c22435a5SPaul Mackerras blr 42c22435a5SPaul Mackerras 43c22435a5SPaul Mackerras/* Put the contents of *p into frN; N is in r3 and p is in r4. */ 440016a4cfSPaul Mackerras_GLOBAL(put_fpr) 45c22435a5SPaul Mackerras mflr r0 460016a4cfSPaul Mackerras mfmsr r6 470016a4cfSPaul Mackerras ori r7, r6, MSR_FP 48c22435a5SPaul Mackerras MTMSRD(r7) 49c22435a5SPaul Mackerras isync 50c22435a5SPaul Mackerras rlwinm r3,r3,3,0xf8 51c22435a5SPaul Mackerras bcl 20,31,1f 520016a4cfSPaul Mackerrasreg = 0 530016a4cfSPaul Mackerras .rept 32 54c22435a5SPaul Mackerras lfd reg, 0(r4) 55c22435a5SPaul Mackerras b 2f 56c22435a5SPaul Mackerrasreg = reg + 1 57c22435a5SPaul Mackerras .endr 580016a4cfSPaul Mackerras1: mflr r5 590016a4cfSPaul Mackerras add r5,r3,r5 600016a4cfSPaul Mackerras mtctr r5 610016a4cfSPaul Mackerras mtlr r0 620016a4cfSPaul Mackerras bctr 630016a4cfSPaul Mackerras2: MTMSRD(r6) 640016a4cfSPaul Mackerras isync 65c22435a5SPaul Mackerras blr 660016a4cfSPaul Mackerras 670016a4cfSPaul Mackerras#ifdef CONFIG_ALTIVEC 680016a4cfSPaul Mackerras/* Get the contents of vrN into *p; N is in r3 and p is in r4. */ 690016a4cfSPaul Mackerras_GLOBAL(get_vr) 70c22435a5SPaul Mackerras mflr r0 710016a4cfSPaul Mackerras mfmsr r6 720016a4cfSPaul Mackerras oris r7, r6, MSR_VEC@h 73c22435a5SPaul Mackerras MTMSRD(r7) 74c22435a5SPaul Mackerras isync 75c22435a5SPaul Mackerras rlwinm r3,r3,3,0xf8 76c22435a5SPaul Mackerras bcl 20,31,1f 774716e488SPaul Mackerrasreg = 0 780016a4cfSPaul Mackerras .rept 32 79c22435a5SPaul Mackerras stvx reg, 0, r4 80c22435a5SPaul Mackerras b 2f 81c22435a5SPaul Mackerrasreg = reg + 1 82c22435a5SPaul Mackerras .endr 830016a4cfSPaul Mackerras1: mflr r5 840016a4cfSPaul Mackerras add r5,r3,r5 850016a4cfSPaul Mackerras mtctr r5 864716e488SPaul Mackerras mtlr r0 870016a4cfSPaul Mackerras bctr 880016a4cfSPaul Mackerras2: MTMSRD(r6) 890016a4cfSPaul Mackerras isync 90c22435a5SPaul Mackerras blr 91c22435a5SPaul Mackerras 92c22435a5SPaul Mackerras/* Put the contents of *p into vrN; N is in r3 and p is in r4. */ 930016a4cfSPaul Mackerras_GLOBAL(put_vr) 94c22435a5SPaul Mackerras mflr r0 950016a4cfSPaul Mackerras mfmsr r6 960016a4cfSPaul Mackerras oris r7, r6, MSR_VEC@h 97c22435a5SPaul Mackerras MTMSRD(r7) 98c22435a5SPaul Mackerras isync 99c22435a5SPaul Mackerras rlwinm r3,r3,3,0xf8 100c22435a5SPaul Mackerras bcl 20,31,1f 1014716e488SPaul Mackerrasreg = 0 1020016a4cfSPaul Mackerras .rept 32 103c22435a5SPaul Mackerras lvx reg, 0, r4 104c22435a5SPaul Mackerras b 2f 105c22435a5SPaul Mackerrasreg = reg + 1 106c22435a5SPaul Mackerras .endr 1070016a4cfSPaul Mackerras1: mflr r5 1080016a4cfSPaul Mackerras add r5,r3,r5 1090016a4cfSPaul Mackerras mtctr r5 1104716e488SPaul Mackerras mtlr r0 1110016a4cfSPaul Mackerras bctr 1120016a4cfSPaul Mackerras2: MTMSRD(r6) 1130016a4cfSPaul Mackerras isync 114c22435a5SPaul Mackerras blr 1150016a4cfSPaul Mackerras#endif /* CONFIG_ALTIVEC */ 1160016a4cfSPaul Mackerras 1170016a4cfSPaul Mackerras#ifdef CONFIG_VSX 1180016a4cfSPaul Mackerras/* Get the contents of vsN into vs0; N is in r3. */ 1190016a4cfSPaul Mackerras_GLOBAL(get_vsr) 120df99e6ebSAnton Blanchard mflr r0 1210016a4cfSPaul Mackerras rlwinm r3,r3,3,0x1f8 1220016a4cfSPaul Mackerras bcl 20,31,1f 1230016a4cfSPaul Mackerras blr /* vs0 is already in vs0 */ 1240016a4cfSPaul Mackerras nop 125df99e6ebSAnton Blanchardreg = 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 1370016a4cfSPaul Mackerras/* Put the contents of vs0 into vsN; N is in r3. */ 1380016a4cfSPaul Mackerras_GLOBAL(put_vsr) 139df99e6ebSAnton Blanchard mflr r0 1400016a4cfSPaul Mackerras rlwinm r3,r3,3,0x1f8 1410016a4cfSPaul Mackerras bcl 20,31,1f 1420016a4cfSPaul Mackerras blr /* v0 is already in v0 */ 1430016a4cfSPaul Mackerras nop 144c2ce6f9fSAnton Blanchardreg = 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. */ 1570016a4cfSPaul Mackerras_GLOBAL(load_vsrn) 1580016a4cfSPaul Mackerras PPC_STLU r1,-STKFRM(r1) 159350779a2SPaul 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 1650016a4cfSPaul Mackerras MTMSRD(r7) 1660016a4cfSPaul Mackerras isync 167cd64d169SSean MacLennan beq cr7,1f 1680016a4cfSPaul Mackerras STXVD2X(0,R1,R8) 1690016a4cfSPaul Mackerras1: LXVD2X(0,R0,R4) 170c75df6f9SMichael Neuling#ifdef __LITTLE_ENDIAN__ 171350779a2SPaul Mackerras XXSWAPD(0,0) 172350779a2SPaul Mackerras#endif 173350779a2SPaul Mackerras beq cr7,4f 174350779a2SPaul Mackerras bl put_vsr 175350779a2SPaul Mackerras LXVD2X(0,R1,R8) 1760016a4cfSPaul Mackerras4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 177c75df6f9SMichael Neuling mtlr r0 1780016a4cfSPaul Mackerras MTMSRD(r6) 1790016a4cfSPaul Mackerras isync 180cd64d169SSean MacLennan 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. */ 1840016a4cfSPaul Mackerras_GLOBAL(store_vsrn) 1850016a4cfSPaul Mackerras PPC_STLU r1,-STKFRM(r1) 186350779a2SPaul 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 1910016a4cfSPaul Mackerras MTMSRD(r7) 1920016a4cfSPaul Mackerras isync 193cd64d169SSean MacLennan STXVD2X(0,R1,R8) 1940016a4cfSPaul Mackerras bl get_vsr 195c75df6f9SMichael Neuling#ifdef __LITTLE_ENDIAN__ 1960016a4cfSPaul Mackerras XXSWAPD(0,0) 197350779a2SPaul Mackerras#endif 198350779a2SPaul Mackerras STXVD2X(0,R0,R4) 199350779a2SPaul Mackerras LXVD2X(0,R1,R8) 200350779a2SPaul Mackerras PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) 201c75df6f9SMichael Neuling mtlr r0 202350779a2SPaul Mackerras MTMSRD(r6) 2030016a4cfSPaul Mackerras isync 204cd64d169SSean MacLennan mr r3,r9 2050016a4cfSPaul Mackerras addi r1,r1,STKFRM 2060016a4cfSPaul Mackerras blr 2070016a4cfSPaul Mackerras#endif /* CONFIG_VSX */ 2080016a4cfSPaul Mackerras 2090016a4cfSPaul Mackerras/* Convert single-precision to double, without disturbing FPRs. */ 210cd64d169SSean MacLennan/* 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 238350779a2SPaul Mackerras