[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4366c303e707a43071d5bc54f00cce01@agner.ch>
Date: Sat, 29 Feb 2020 23:58:40 +0100
From: Stefan Agner <stefan@...er.ch>
To: linux@...linux.org.uk
Cc: arnd@...db.de, manojgupta@...gle.com, jiancai@...gle.com,
linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
clang-built-linux@...glegroups.com
Subject: Re: [PATCH] ARM: use assembly mnemonics for VFP register access
On 2020-02-21 07:34, Stefan Agner wrote:
> Clang's integrated assembler does not allow to to use the mcr
> instruction to access floating point co-processor registers:
> 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
> ^
>
> 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. Use the .fpu directive and mnemonics for VFP
> register access.
>
> This allows to build vfpmodule.c with Clang and its integrated assembler.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/905
> Signed-off-by: Stefan Agner <stefan@...er.ch>
> ---
> arch/arm/vfp/vfpinstr.h | 12 ++++--------
> 1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h
> index 38dc154e39ff..799ccf065406 100644
> --- a/arch/arm/vfp/vfpinstr.h
> +++ b/arch/arm/vfp/vfpinstr.h
> @@ -62,21 +62,17 @@
> #define FPSCR_C (1 << 29)
> #define FPSCR_V (1 << 28)
>
> -/*
> - * Since we aren't building with -mfpu=vfp, we need to code
> - * these instructions using their MRC/MCR equivalents.
> - */
> -#define vfpreg(_vfp_) #_vfp_
> -
> #define fmrx(_vfp_) ({ \
> u32 __v; \
> - asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \
> + asm(".fpu vfpv2\n" \
> + "vmrs %0, " #_vfp_ \
> : "=r" (__v) : : "cc"); \
> __v; \
> })
>
> #define fmxr(_vfp_,_var_) \
> - asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \
> + asm(".fpu vfpv2\n" \
> + "vmsr " #_vfp_ ", %0" \
> : : "r" (_var_) : "cc")
>
> u32 vfp_single_cpdo(u32 inst, u32 fpscr);
I just found out that this fails with binutils 2.23.1. Since we support
binutils back to 2.21 I guess that is not OK..?
CC arch/arm/vfp/vfpmodule.o
/tmp/cc2Vcw98.s: Assembler messages:
/tmp/cc2Vcw98.s:920: Error: operand 1 must be a VFP extension System
Register -- `vmrs r6,FPINST'
/tmp/cc2Vcw98.s:948: Error: operand 1 must be a VFP extension System
Register -- `vmrs r6,FPINST2'
Looking into binutils history reveals that FPINST/FPINST2 has been
allowed with 16d02dc907c5717b5f47076bb90ae3795e73b59f
("gas/config/tc-arm.c (do_vmrs): Accept all control registers") which
made it into binutils 2.24...
I don't have a particular good idea how to make this work for Clang and
GCC other than a some ifdef's...
--
Stefan
Powered by blists - more mailing lists