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