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