From bc52d49c1d0e9b5d196132efb41addaf0bddad4f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Tue, 6 Nov 2018 14:52:11 +0000 Subject: [PATCH] [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). The instruction should be treated similarly to VSUBL that has the same caveat of "must be unconditional" describing the {} 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 2018-11-06 Matthew Malcomson * 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. --- gas/ChangeLog | 11 +++++++++ gas/config/tc-arm.c | 2 ++ gas/testsuite/gas/arm/neon-cond-bad-inc.s | 4 +++ gas/testsuite/gas/arm/neon-cond-bad.l | 30 ++++++++++++----------- gas/testsuite/gas/arm/neon-cond-bad_t2.d | 3 +++ gas/testsuite/gas/arm/vfp-bad.l | 2 ++ gas/testsuite/gas/arm/vfp-bad.s | 2 ++ 7 files changed, 40 insertions(+), 14 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 601f2aa7cc3..3aa87c7204d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2018-11-06 Matthew Malcomson + + * 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. + 2018-11-06 Alan Modra * config/tc-ppc.c (insn_validate): Don't ignore mask in diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 80fb0c3b5ea..7235b7f62b6 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 2f56773dd05..087c5298cdd 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 a79f79d64f8..331ac7d111d 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 517caa758ee..abff08431e1 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 a1479f484fe..fda2ce48382 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 1a446fee936..2a83a21cc87 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 -- 2.30.2