diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index af6550eeb95db17f444acc7e6bfdb73e3dc14f3c..7e0df057c6ab3223ed7665f616f119507aec3dec 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -16885,12 +16885,42 @@ do_neon_mac_maybe_scalar (void) static void do_neon_fmac (void) { - if (try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS) + if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma) + && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS) return; - if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL) + if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH)) return; + if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)) + { + enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL); + struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, + N_EQK); + + if (rs == NS_QQR) + { + if (inst.operands[2].reg == REG_SP) + as_tsktsk (MVE_BAD_SP); + else if (inst.operands[2].reg == REG_PC) + as_tsktsk (MVE_BAD_PC); + + inst.instruction = 0xee310e40; + inst.instruction |= (et.size == 16) << 28; + inst.instruction |= HI1 (inst.operands[0].reg) << 22; + inst.instruction |= LOW4 (inst.operands[1].reg) << 16; + inst.instruction |= LOW4 (inst.operands[0].reg) << 12; + inst.instruction |= HI1 (inst.operands[1].reg) << 6; + inst.instruction |= inst.operands[2].reg; + inst.is_neon = 1; + return; + } + } + else + { + constraint (!inst.operands[2].isvec, BAD_FPU); + } + neon_dyadic_misc (NT_untyped, N_IF_32, 0); } @@ -23822,11 +23852,12 @@ static const struct asm_opcode insns[] = #define ARM_VARIANT & fpu_vfp_ext_fma #undef THUMB_VARIANT #define THUMB_VARIANT & fpu_vfp_ext_fma - /* Mnemonics shared by Neon and VFP. These are included in the + /* Mnemonics shared by Neon, VFP and MVE. These are included in the VFP FMA variant; NEON and VFP FMA always includes the NEON FMA instructions. */ - nCEF(vfma, _vfma, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac), - nCEF(vfms, _vfms, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac), + mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac), + mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac), + /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas; the v form should always be used. */ cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic), diff --git a/gas/testsuite/gas/arm/mve-vfma-vfms-bad.d b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.d new file mode 100644 index 0000000000000000000000000000000000000000..925d74edf93760d927bad3d31e0c595d4213877c --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.d @@ -0,0 +1,5 @@ +#name: bad MVE FP VFMA and VFMS instructions +#as: -march=armv8.1-m.main+mve.fp +#error_output: mve-vfma-vfms-bad.l + +.*: +file format .*arm.* diff --git a/gas/testsuite/gas/arm/mve-vfma-vfms-bad.l b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.l new file mode 100644 index 0000000000000000000000000000000000000000..9a01adb665e6bd12a5d08160d0c9ea24bc35a116 --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.l @@ -0,0 +1,35 @@ +[^:]*: Assembler messages: +[^:]*:24: Warning: instruction is UNPREDICTABLE with SP operand +[^:]*:25: Warning: instruction is UNPREDICTABLE with PC operand +[^:]*:26: Error: bad type in SIMD instruction -- `vfma.f64 q0,q1,q2' +[^:]*:27: Error: bad type in SIMD instruction -- `vfma.32 q0,q1,q2' +[^:]*:28: Error: bad type in SIMD instruction -- `vfms.f64 q0,q1,q2' +[^:]*:29: Error: bad type in SIMD instruction -- `vfms.32 q0,q1,q2' +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:32: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:33: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:35: Error: syntax error -- `vfmaeq.f16 q0,q1,q2' +[^:]*:36: Error: syntax error -- `vfmaeq.f16 q0,q1,q2' +[^:]*:38: Error: syntax error -- `vfmaeq.f16 q0,q1,q2' +[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vfmat.f16 q0,q1,q2' +[^:]*:41: Error: instruction missing MVE vector predication code -- `vfma.f16 q0,q1,q2' +[^:]*:43: Error: syntax error -- `vfmseq.f16 q0,q1,q2' +[^:]*:44: Error: syntax error -- `vfmseq.f16 q0,q1,q2' +[^:]*:46: Error: syntax error -- `vfmseq.f16 q0,q1,q2' +[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vfmst.f16 q0,q1,q2' +[^:]*:49: Error: instruction missing MVE vector predication code -- `vfms.f16 q0,q1,q2' diff --git a/gas/testsuite/gas/arm/mve-vfma-vfms-bad.s b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.s new file mode 100644 index 0000000000000000000000000000000000000000..c821f2b44106d83bc7a11d4bd7811be73dd4eb1a --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vfma-vfms-bad.s @@ -0,0 +1,49 @@ +.macro cond1 +.irp cond, eq, ne, gt, ge, lt, le +it \cond +vfma.f32 q0, q1, q2 +.endr +.endm + +.macro cond2 +.irp cond, eq, ne, gt, ge, lt, le +it \cond +vfma.f32 q0, q1, r2 +.endr +.endm + +.macro cond3 +.irp cond, eq, ne, gt, ge, lt, le +it \cond +vfms.f32 q0, q1, q2 +.endr +.endm + +.syntax unified +.thumb +vfma.f32 q0, q1, sp +vfma.f32 q0, q1, pc +vfma.f64 q0, q1, q2 +vfma.32 q0, q1, q2 +vfms.f64 q0, q1, q2 +vfms.32 q0, q1, q2 +vfma.f64 d0, d1, d2 +cond1 +cond2 +cond3 +it eq +vfmaeq.f16 q0, q1, q2 +vfmaeq.f16 q0, q1, q2 +vpst +vfmaeq.f16 q0, q1, q2 +vfmat.f16 q0, q1, q2 +vpst +vfma.f16 q0, q1, q2 +it eq +vfmseq.f16 q0, q1, q2 +vfmseq.f16 q0, q1, q2 +vpst +vfmseq.f16 q0, q1, q2 +vfmst.f16 q0, q1, q2 +vpst +vfms.f16 q0, q1, q2