Commit 2cbd1cc3 authored by Stefan Agner's avatar Stefan Agner Committed by Russell King
Browse files

ARM: 8991/1: use VFP assembler mnemonics if available

The integrated assembler of Clang 10 and earlier do not allow to access
the VFP registers through the coprocessor load/store instructions:
arch/arm/vfp/vfpmodule.c:342:2: error: invalid operand for instruction
        fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK));
        ^
arch/arm/vfp/vfpinstr.h:79:6: note: expanded from macro 'fmxr'
        asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr   " #_vfp_ ", %0"
            ^
<inline asm>:1:6: note: instantiated into assembly here
        mcr p10, 7, r0, cr8, cr0, 0 @ fmxr      FPEXC, r0
            ^

This has been addressed with Clang 11 [0]. However, to support earlier
versions of Clang and for better readability use of VFP assembler
mnemonics still is preferred.

Ideally we would replace this code with the unified assembler language
mnemonics vmrs/vmsr on call sites along with .fpu assembler directives.
The GNU assembler supports the .fpu directive at least since 2.17 (when
documentation has been added). Since Linux requires binutils 2.21 it is
safe to use .fpu directive. However, binutils does not allow to use
FPINST or FPINST2 as an argument to vmrs/vmsr instructions up to
binutils 2.24 (see binutils commit 16d02dc907c5):
arch/arm/vfp/vfphw.S: Assembler messages:
arch/arm/vfp/vfphw.S:162: Error: operand 0 must be FPSID or FPSCR pr FPEXC -- `vmsr FPINST,r6'
arch/arm/vfp/vfphw.S:165: Error: operand 0 must be FPSID or FPSCR pr FPEXC -- `vmsr FPINST2,r8'
arch/arm/vfp/vfphw.S:235: Error: operand 1 must be a VFP extension System Register -- `vmrs r3,FPINST'
arch/arm/vfp/vfphw.S:238: Error: operand 1 must be a VFP extension System Register -- `vmrs r12,FPINST2'

Use as-instr in Kconfig to check if FPINST/FPINST2 can be used. If they
can be used make use of .fpu directives and UAL VFP mnemonics for
register access.

This allows to build vfpmodule.c with Clang and its integrated assembler.

[0] https://reviews.llvm.org/D59733

Link: https://github.com/ClangBuiltLinux/linux/issues/905



Signed-off-by: default avatarStefan Agner <stefan@agner.ch>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent ee440336
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2097,3 +2097,5 @@ source "drivers/firmware/Kconfig"
if CRYPTO
source "arch/arm/crypto/Kconfig"
endif

source "arch/arm/Kconfig.assembler"
+6 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

config AS_VFP_VMRS_FPINST
	def_bool $(as-instr,.fpu vfpv2\nvmrs r0$(comma)FPINST)
	help
	  Supported by binutils >= 2.24 and LLVM integrated assembler.
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#ifndef __ASM_VFP_H
#define __ASM_VFP_H

#ifndef CONFIG_AS_VFP_VMRS_FPINST
#define FPSID			cr0
#define FPSCR			cr1
#define MVFR1			cr6
@@ -16,6 +17,7 @@
#define FPEXC			cr8
#define FPINST			cr9
#define FPINST2			cr10
#endif

/* FPSID bits */
#define FPSID_IMPLEMENTER_BIT	(24)
+11 −1
Original line number Diff line number Diff line
@@ -8,6 +8,15 @@

#include <asm/vfp.h>

#ifdef CONFIG_AS_VFP_VMRS_FPINST
	.macro	VFPFMRX, rd, sysreg, cond
	vmrs\cond	\rd, \sysreg
	.endm

	.macro	VFPFMXR, sysreg, rd, cond
	vmsr\cond	\sysreg, \rd
	.endm
#else
	@ Macros to allow building with old toolkits (with no VFP support)
	.macro	VFPFMRX, rd, sysreg, cond
	MRC\cond	p10, 7, \rd, \sysreg, cr0, 0	@ FMRX	\rd, \sysreg
@@ -16,6 +25,7 @@
	.macro	VFPFMXR, sysreg, rd, cond
	MCR\cond	p10, 7, \rd, \sysreg, cr0, 0	@ FMXR	\sysreg, \rd
	.endm
#endif

	@ read all the working registers back into the VFP
	.macro	VFPFLDMIA, base, tmp
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@
ENTRY(vfp_support_entry)
	DBGSTR3	"instr %08x pc %08x state %p", r0, r2, r10

	.fpu	vfpv2
	ldr	r3, [sp, #S_PSR]	@ Neither lazy restore nor FP exceptions
	and	r3, r3, #MODE_MASK	@ are supported in kernel mode
	teq	r3, #USR_MODE
Loading