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