This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH][gas][arm] Check for neon and condition in vcvt.f16.f32
- From: "Richard Earnshaw (lists)" <Richard dot Earnshaw at arm dot com>
- To: Matthew Malcomson <Matthew dot Malcomson at arm dot com>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: "nickc at redhat dot com" <nickc at redhat dot com>, nd <nd at arm dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>
- Date: Tue, 6 Nov 2018 14:55:37 +0000
- Subject: Re: [PATCH][gas][arm] Check for neon and condition in vcvt.f16.f32
- References: <DB6PR0801MB2006491D4684D00BE037CD7EE0F50@DB6PR0801MB2006.eurprd08.prod.outlook.com>
On 23/10/2018 15:43, Matthew Malcomson wrote:
> [PATCH][gas][arm] Check for neon and condition in vcvt.f16.f32
>
> VCVT between f16 and f32 is an Advanced SIMD instruction.
> Not all the VCVT alternatives need neon, hence the check for neon is in
> the encode function.
>
> The check on neon for VCVT.f16.f32 (and vice versa) is missing.
>
> vshcmd: > echo 'vcvt.f16.f32 d1, q1' | gas/as-new -mfpu=vfpxd -march=armv8.5-a -
> testdir [15:59:10] $
>
> Also, the handling of the condition code behaves differently to other
> SIMD instructions -- no error message is produced when assembling an
> instruction with a condition code suffix despite the arm encoding not
> allowing a condition code. (n.b. the actual binary produced is
> independent of the suffix).
>
> I believe the instruction should be treated similarly to VSUBL that has
> the same caveat of "must be unconditional" describing the {<c>} symbol.
> vcvt half-precision to single precision found in F6.1.58 in the ARM
> Architecture Reference Manual issue C.a, vsubl found in F6.1.240 in the
> ARM Architecture Reference Manual issue C.a
>
> Current behaviour is:
> vshcmd: > echo 'vcvteq.f16.f32 d1, q1' | gas/as-new -march=armv8.5-a+simd -
> testdir [16:12:58] $
>
> While for the vsubl instruction:
> vshcmd: > echo 'vsublne.s32 q0, d1, d1' | gas/as-new -march=armv8.5-a+simd -
> {standard input}: Assembler messages:
> {standard input}:1: Error: instruction cannot be conditional -- `vsublne.s32 q0,d1,d1'
> testdir [16:18:18] $
>
>
>
> Behaviour of the vcvt instruction after this patch:
> vshcmd: > echo 'vcvteq.f16.f32 d1, q1' | gas/as-new -march=armv8.5-a+simd -
> {standard input}: Assembler messages:
> {standard input}:1: Error: instruction cannot be conditional -- `vcvteq.f16.f32 d1,q1'
> testdir [14:09:59] $
>
> vshcmd: > echo 'vcvt.f16.f32 d1, q1' | gas/as-new -mfpu=vfpxd -march=armv8.5-a -
> {standard input}: Assembler messages:
> {standard input}:1: Error: selected FPU does not support instruction -- `vcvt.f16.f32 d1,q1'
> testdir [14:10:01] $
>
>
> Tested for arm-none-linux-gnueabihf
> Ok for trunk?
>
> gas/ChangeLog:
>
> 2018-10-23 Matthew Malcomson <matthew.malcomson@arm.com>
>
> * config/tc-arm.c (do_neon_cvt_1): Add check for neon and condition codes
> to half-precision conversion.
> * testsuite/gas/arm/neon-cond-bad-inc.s: Check vcvteq disallowed
> * testsuite/gas/arm/neon-cond-bad.l: Likewise
> * testsuite/gas/arm/neon-cond-bad_t2.d: Check vcvteq allowed in IT block
> * testsuite/gas/arm/vfp-bad.l: Ensure vcvt doesn't work without neon.
> * testsuite/gas/arm/vfp-bad.s: Likewise
>
>
Thanks, pushed.
R.
>
> ############### Attachment also inlined for ease of reply ###############
>
>
> diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
> index 80fb0c3b5ea31b399331c2b1d60e4a7ad05899cf..7235b7f62b6562703faa1bc3e0741fd72a42b085 100644
> --- a/gas/config/tc-arm.c
> +++ b/gas/config/tc-arm.c
> @@ -15914,6 +15914,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
> /* Half-precision conversions for Advanced SIMD -- neon. */
> case NS_QD:
> case NS_DQ:
> + if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
> + return;
>
> if ((rs == NS_DQ)
> && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad-inc.s b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> index 2f56773dd05d63ac1651173b7cf62f46c385d821..087c5298cddd79a5cdc85cbff0e6110c81aa963c 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> +++ b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> @@ -30,6 +30,10 @@ func:
> dyadic_eq vadd
> dyadic_eq vsub
>
> + itblock 2 eq
> + vcvteq.f16.f32 d1, q1
> + vcvteq.f32.f16 q1, d1
> +
> .macro monadic_eq op eq="eq" f32=".f32"
> itblock 2 eq
> \op\eq\f32 d0,d1
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad.l b/gas/testsuite/gas/arm/neon-cond-bad.l
> index a79f79d64f8348600e90924cb42de205e1d29ddf..331ac7d111d32050457d794aa4cefa86875de8c3 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad.l
> +++ b/gas/testsuite/gas/arm/neon-cond-bad.l
> @@ -13,17 +13,19 @@
> [^:]*:30: Error: instruction cannot be conditional -- `vaddeq\.f32 q0,q1,q2'
> [^:]*:31: Error: instruction cannot be conditional -- `vsubeq\.f32 d0,d1,d2'
> [^:]*:31: Error: instruction cannot be conditional -- `vsubeq\.f32 q0,q1,q2'
> -[^:]*:39: Error: instruction cannot be conditional -- `vabseq\.f32 d0,d1'
> -[^:]*:39: Error: instruction cannot be conditional -- `vabseq\.f32 q0,q1'
> -[^:]*:40: Error: instruction cannot be conditional -- `vnegeq\.f32 d0,d1'
> -[^:]*:40: Error: instruction cannot be conditional -- `vnegeq\.f32 q0,q1'
> -[^:]*:48: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 d0,d1'
> -[^:]*:48: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 q0,q1'
> -[^:]*:49: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 d0,d1'
> -[^:]*:49: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 q0,q1'
> -[^:]*:50: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 d0,d1'
> -[^:]*:50: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 q0,q1'
> -[^:]*:51: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 d0,d1'
> -[^:]*:51: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 q0,q1'
> -[^:]*:56: Error: instruction cannot be conditional -- `vdupeq\.32 d0,d1\[0\]'
> -[^:]*:57: Error: instruction cannot be conditional -- `vdupeq\.32 q0,d1\[1\]'
> +[^:]*:34: Error: instruction cannot be conditional -- `vcvteq\.f16\.f32 d1,q1'
> +[^:]*:35: Error: instruction cannot be conditional -- `vcvteq\.f32\.f16 q1,d1'
> +[^:]*:43: Error: instruction cannot be conditional -- `vabseq\.f32 d0,d1'
> +[^:]*:43: Error: instruction cannot be conditional -- `vabseq\.f32 q0,q1'
> +[^:]*:44: Error: instruction cannot be conditional -- `vnegeq\.f32 d0,d1'
> +[^:]*:44: Error: instruction cannot be conditional -- `vnegeq\.f32 q0,q1'
> +[^:]*:52: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 d0,d1'
> +[^:]*:52: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 q0,q1'
> +[^:]*:53: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 d0,d1'
> +[^:]*:53: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 q0,q1'
> +[^:]*:54: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 d0,d1'
> +[^:]*:54: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 q0,q1'
> +[^:]*:55: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 d0,d1'
> +[^:]*:55: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 q0,q1'
> +[^:]*:60: Error: instruction cannot be conditional -- `vdupeq\.32 d0,d1\[0\]'
> +[^:]*:61: Error: instruction cannot be conditional -- `vdupeq\.32 q0,d1\[1\]'
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad_t2.d b/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> index 517caa758ee4bb40fdd5d9d4460400c615ba28ed..abff08431e1618718b8885da4e8465dc0732b459 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> +++ b/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> @@ -31,6 +31,9 @@ Disassembly of section \.text:
> 0[0-9a-f]+ <[^>]+> ef21 0d02 vsubeq\.f32 d0, d1, d2
> 0[0-9a-f]+ <[^>]+> ef22 0d44 vsubeq\.f32 q0, q1, q2
> 0[0-9a-f]+ <[^>]+> bf04 itt eq
> +0[0-9a-f]+ <[^>]+> ffb6 1602 vcvteq.f16.f32 d1, q1
> +0[0-9a-f]+ <[^>]+> ffb6 2701 vcvteq.f32.f16 q1, d1
> +0[0-9a-f]+ <[^>]+> bf04 itt eq
> 0[0-9a-f]+ <[^>]+> ffb9 0701 vabseq\.f32 d0, d1
> 0[0-9a-f]+ <[^>]+> ffb9 0742 vabseq\.f32 q0, q1
> 0[0-9a-f]+ <[^>]+> bf04 itt eq
> diff --git a/gas/testsuite/gas/arm/vfp-bad.l b/gas/testsuite/gas/arm/vfp-bad.l
> index a1479f484fefe9ee3f33b3635e8954e3cc5437cd..fda2ce4838213c35c5d0fadab1ed830601e91a1c 100644
> --- a/gas/testsuite/gas/arm/vfp-bad.l
> +++ b/gas/testsuite/gas/arm/vfp-bad.l
> @@ -9,3 +9,5 @@
> [^:]*:11: Error: instruction does not support writeback -- `flds s0,\[r0,#-8\]!'
> [^:]*:12: Error: selected FPU does not support instruction -- `vmrs r0,MVFR2'
> [^:]*:13: Error: selected FPU does not support instruction -- `vmsr MVFR2,r2'
> +[^:]*:14: Error: selected FPU does not support instruction -- `vcvt.f16.f32 d1,q1'
> +[^:]*:15: Error: selected FPU does not support instruction -- `vcvt.f32.f16 q1,d1'
> diff --git a/gas/testsuite/gas/arm/vfp-bad.s b/gas/testsuite/gas/arm/vfp-bad.s
> index 1a446fee936be3cca99b6c28dc20928ef72a1bb1..2a83a21cc87aca26af240f1447201e5d12d987de 100644
> --- a/gas/testsuite/gas/arm/vfp-bad.s
> +++ b/gas/testsuite/gas/arm/vfp-bad.s
> @@ -11,3 +11,5 @@ entry:
> flds s0, [r0, #-8]!
> vmrs r0, MVFR2
> vmsr MVFR2, r2
> + vcvt.f16.f32 d1, q1
> + vcvt.f32.f16 q1, d1
>
>
> vcvt-error-checking.patch
>
> diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
> index 80fb0c3b5ea31b399331c2b1d60e4a7ad05899cf..7235b7f62b6562703faa1bc3e0741fd72a42b085 100644
> --- a/gas/config/tc-arm.c
> +++ b/gas/config/tc-arm.c
> @@ -15914,6 +15914,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
> /* Half-precision conversions for Advanced SIMD -- neon. */
> case NS_QD:
> case NS_DQ:
> + if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
> + return;
>
> if ((rs == NS_DQ)
> && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad-inc.s b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> index 2f56773dd05d63ac1651173b7cf62f46c385d821..087c5298cddd79a5cdc85cbff0e6110c81aa963c 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> +++ b/gas/testsuite/gas/arm/neon-cond-bad-inc.s
> @@ -30,6 +30,10 @@ func:
> dyadic_eq vadd
> dyadic_eq vsub
>
> + itblock 2 eq
> + vcvteq.f16.f32 d1, q1
> + vcvteq.f32.f16 q1, d1
> +
> .macro monadic_eq op eq="eq" f32=".f32"
> itblock 2 eq
> \op\eq\f32 d0,d1
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad.l b/gas/testsuite/gas/arm/neon-cond-bad.l
> index a79f79d64f8348600e90924cb42de205e1d29ddf..331ac7d111d32050457d794aa4cefa86875de8c3 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad.l
> +++ b/gas/testsuite/gas/arm/neon-cond-bad.l
> @@ -13,17 +13,19 @@
> [^:]*:30: Error: instruction cannot be conditional -- `vaddeq\.f32 q0,q1,q2'
> [^:]*:31: Error: instruction cannot be conditional -- `vsubeq\.f32 d0,d1,d2'
> [^:]*:31: Error: instruction cannot be conditional -- `vsubeq\.f32 q0,q1,q2'
> -[^:]*:39: Error: instruction cannot be conditional -- `vabseq\.f32 d0,d1'
> -[^:]*:39: Error: instruction cannot be conditional -- `vabseq\.f32 q0,q1'
> -[^:]*:40: Error: instruction cannot be conditional -- `vnegeq\.f32 d0,d1'
> -[^:]*:40: Error: instruction cannot be conditional -- `vnegeq\.f32 q0,q1'
> -[^:]*:48: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 d0,d1'
> -[^:]*:48: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 q0,q1'
> -[^:]*:49: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 d0,d1'
> -[^:]*:49: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 q0,q1'
> -[^:]*:50: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 d0,d1'
> -[^:]*:50: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 q0,q1'
> -[^:]*:51: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 d0,d1'
> -[^:]*:51: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 q0,q1'
> -[^:]*:56: Error: instruction cannot be conditional -- `vdupeq\.32 d0,d1\[0\]'
> -[^:]*:57: Error: instruction cannot be conditional -- `vdupeq\.32 q0,d1\[1\]'
> +[^:]*:34: Error: instruction cannot be conditional -- `vcvteq\.f16\.f32 d1,q1'
> +[^:]*:35: Error: instruction cannot be conditional -- `vcvteq\.f32\.f16 q1,d1'
> +[^:]*:43: Error: instruction cannot be conditional -- `vabseq\.f32 d0,d1'
> +[^:]*:43: Error: instruction cannot be conditional -- `vabseq\.f32 q0,q1'
> +[^:]*:44: Error: instruction cannot be conditional -- `vnegeq\.f32 d0,d1'
> +[^:]*:44: Error: instruction cannot be conditional -- `vnegeq\.f32 q0,q1'
> +[^:]*:52: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 d0,d1'
> +[^:]*:52: Error: instruction cannot be conditional -- `vcvteq\.s32\.f32 q0,q1'
> +[^:]*:53: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 d0,d1'
> +[^:]*:53: Error: instruction cannot be conditional -- `vcvteq\.u32\.f32 q0,q1'
> +[^:]*:54: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 d0,d1'
> +[^:]*:54: Error: instruction cannot be conditional -- `vcvteq\.f32\.s32 q0,q1'
> +[^:]*:55: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 d0,d1'
> +[^:]*:55: Error: instruction cannot be conditional -- `vcvteq\.f32\.u32 q0,q1'
> +[^:]*:60: Error: instruction cannot be conditional -- `vdupeq\.32 d0,d1\[0\]'
> +[^:]*:61: Error: instruction cannot be conditional -- `vdupeq\.32 q0,d1\[1\]'
> diff --git a/gas/testsuite/gas/arm/neon-cond-bad_t2.d b/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> index 517caa758ee4bb40fdd5d9d4460400c615ba28ed..abff08431e1618718b8885da4e8465dc0732b459 100644
> --- a/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> +++ b/gas/testsuite/gas/arm/neon-cond-bad_t2.d
> @@ -31,6 +31,9 @@ Disassembly of section \.text:
> 0[0-9a-f]+ <[^>]+> ef21 0d02 vsubeq\.f32 d0, d1, d2
> 0[0-9a-f]+ <[^>]+> ef22 0d44 vsubeq\.f32 q0, q1, q2
> 0[0-9a-f]+ <[^>]+> bf04 itt eq
> +0[0-9a-f]+ <[^>]+> ffb6 1602 vcvteq.f16.f32 d1, q1
> +0[0-9a-f]+ <[^>]+> ffb6 2701 vcvteq.f32.f16 q1, d1
> +0[0-9a-f]+ <[^>]+> bf04 itt eq
> 0[0-9a-f]+ <[^>]+> ffb9 0701 vabseq\.f32 d0, d1
> 0[0-9a-f]+ <[^>]+> ffb9 0742 vabseq\.f32 q0, q1
> 0[0-9a-f]+ <[^>]+> bf04 itt eq
> diff --git a/gas/testsuite/gas/arm/vfp-bad.l b/gas/testsuite/gas/arm/vfp-bad.l
> index a1479f484fefe9ee3f33b3635e8954e3cc5437cd..fda2ce4838213c35c5d0fadab1ed830601e91a1c 100644
> --- a/gas/testsuite/gas/arm/vfp-bad.l
> +++ b/gas/testsuite/gas/arm/vfp-bad.l
> @@ -9,3 +9,5 @@
> [^:]*:11: Error: instruction does not support writeback -- `flds s0,\[r0,#-8\]!'
> [^:]*:12: Error: selected FPU does not support instruction -- `vmrs r0,MVFR2'
> [^:]*:13: Error: selected FPU does not support instruction -- `vmsr MVFR2,r2'
> +[^:]*:14: Error: selected FPU does not support instruction -- `vcvt.f16.f32 d1,q1'
> +[^:]*:15: Error: selected FPU does not support instruction -- `vcvt.f32.f16 q1,d1'
> diff --git a/gas/testsuite/gas/arm/vfp-bad.s b/gas/testsuite/gas/arm/vfp-bad.s
> index 1a446fee936be3cca99b6c28dc20928ef72a1bb1..2a83a21cc87aca26af240f1447201e5d12d987de 100644
> --- a/gas/testsuite/gas/arm/vfp-bad.s
> +++ b/gas/testsuite/gas/arm/vfp-bad.s
> @@ -11,3 +11,5 @@ entry:
> flds s0, [r0, #-8]!
> vmrs r0, MVFR2
> vmsr MVFR2, r2
> + vcvt.f16.f32 d1, q1
> + vcvt.f32.f16 q1, d1
>