1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * arch/arm/include/asm/vfpmacros.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Assembler-only file containing VFP macros and register definitions. 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun #include <asm/hwcap.h> 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <asm/vfp.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifdef CONFIG_AS_VFP_VMRS_FPINST 12*4882a593Smuzhiyun .macro VFPFMRX, rd, sysreg, cond 13*4882a593Smuzhiyun vmrs\cond \rd, \sysreg 14*4882a593Smuzhiyun .endm 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun .macro VFPFMXR, sysreg, rd, cond 17*4882a593Smuzhiyun vmsr\cond \sysreg, \rd 18*4882a593Smuzhiyun .endm 19*4882a593Smuzhiyun #else 20*4882a593Smuzhiyun @ Macros to allow building with old toolkits (with no VFP support) 21*4882a593Smuzhiyun .macro VFPFMRX, rd, sysreg, cond 22*4882a593Smuzhiyun MRC\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMRX \rd, \sysreg 23*4882a593Smuzhiyun .endm 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun .macro VFPFMXR, sysreg, rd, cond 26*4882a593Smuzhiyun MCR\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMXR \sysreg, \rd 27*4882a593Smuzhiyun .endm 28*4882a593Smuzhiyun #endif 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun @ read all the working registers back into the VFP 31*4882a593Smuzhiyun .macro VFPFLDMIA, base, tmp 32*4882a593Smuzhiyun .fpu vfpv2 33*4882a593Smuzhiyun #if __LINUX_ARM_ARCH__ < 6 34*4882a593Smuzhiyun fldmiax \base!, {d0-d15} 35*4882a593Smuzhiyun #else 36*4882a593Smuzhiyun vldmia \base!, {d0-d15} 37*4882a593Smuzhiyun #endif 38*4882a593Smuzhiyun #ifdef CONFIG_VFPv3 39*4882a593Smuzhiyun .fpu vfpv3 40*4882a593Smuzhiyun #if __LINUX_ARM_ARCH__ <= 6 41*4882a593Smuzhiyun ldr \tmp, =elf_hwcap @ may not have MVFR regs 42*4882a593Smuzhiyun ldr \tmp, [\tmp, #0] 43*4882a593Smuzhiyun tst \tmp, #HWCAP_VFPD32 44*4882a593Smuzhiyun vldmiane \base!, {d16-d31} 45*4882a593Smuzhiyun addeq \base, \base, #32*4 @ step over unused register space 46*4882a593Smuzhiyun #else 47*4882a593Smuzhiyun VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 48*4882a593Smuzhiyun and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field 49*4882a593Smuzhiyun cmp \tmp, #2 @ 32 x 64bit registers? 50*4882a593Smuzhiyun vldmiaeq \base!, {d16-d31} 51*4882a593Smuzhiyun addne \base, \base, #32*4 @ step over unused register space 52*4882a593Smuzhiyun #endif 53*4882a593Smuzhiyun #endif 54*4882a593Smuzhiyun .endm 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun @ write all the working registers out of the VFP 57*4882a593Smuzhiyun .macro VFPFSTMIA, base, tmp 58*4882a593Smuzhiyun #if __LINUX_ARM_ARCH__ < 6 59*4882a593Smuzhiyun fstmiax \base!, {d0-d15} 60*4882a593Smuzhiyun #else 61*4882a593Smuzhiyun vstmia \base!, {d0-d15} 62*4882a593Smuzhiyun #endif 63*4882a593Smuzhiyun #ifdef CONFIG_VFPv3 64*4882a593Smuzhiyun .fpu vfpv3 65*4882a593Smuzhiyun #if __LINUX_ARM_ARCH__ <= 6 66*4882a593Smuzhiyun ldr \tmp, =elf_hwcap @ may not have MVFR regs 67*4882a593Smuzhiyun ldr \tmp, [\tmp, #0] 68*4882a593Smuzhiyun tst \tmp, #HWCAP_VFPD32 69*4882a593Smuzhiyun vstmiane \base!, {d16-d31} 70*4882a593Smuzhiyun addeq \base, \base, #32*4 @ step over unused register space 71*4882a593Smuzhiyun #else 72*4882a593Smuzhiyun VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 73*4882a593Smuzhiyun and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field 74*4882a593Smuzhiyun cmp \tmp, #2 @ 32 x 64bit registers? 75*4882a593Smuzhiyun vstmiaeq \base!, {d16-d31} 76*4882a593Smuzhiyun addne \base, \base, #32*4 @ step over unused register space 77*4882a593Smuzhiyun #endif 78*4882a593Smuzhiyun #endif 79*4882a593Smuzhiyun .endm 80