From d58196e061969786922cae5cdaa2ade56dadd95f Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Thu, 16 May 2019 11:39:24 +0100 Subject: [PATCH] [PATCH 17/57][Arm][GAS] Add support for MVE instructions: vfma and vfms gas/ChangeLog: 2019-05-16 Andre Vieira * config/tc-arm.c (do_neon_fmac): Change to support MVE variants. (insns): Change to accept MVE variants. * testsuite/gas/arm/mve-vfma-vfms-bad.d: New test. * testsuite/gas/arm/mve-vfma-vfms-bad.l: New test. * testsuite/gas/arm/mve-vfma-vfms-bad.s: New test. --- gas/ChangeLog | 8 +++++ gas/config/tc-arm.c | 41 ++++++++++++++++++++++---- gas/testsuite/gas/arm/mve-vfma-vfms-bad.d | 5 ++++ gas/testsuite/gas/arm/mve-vfma-vfms-bad.l | 35 ++++++++++++++++++++++ gas/testsuite/gas/arm/mve-vfma-vfms-bad.s | 49 +++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 gas/testsuite/gas/arm/mve-vfma-vfms-bad.d create mode 100644 gas/testsuite/gas/arm/mve-vfma-vfms-bad.l create mode 100644 gas/testsuite/gas/arm/mve-vfma-vfms-bad.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 8b6ba62..d51ec39 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,13 @@ 2019-05-16 Andre Vieira + * config/tc-arm.c (do_neon_fmac): Change to support MVE variants. + (insns): Change to accept MVE variants. + * testsuite/gas/arm/mve-vfma-vfms-bad.d: New test. + * testsuite/gas/arm/mve-vfma-vfms-bad.l: New test. + * testsuite/gas/arm/mve-vfma-vfms-bad.s: New test. + +2019-05-16 Andre Vieira + * config/tc-arm.c (M_MNEM_vddup, M_MNEM_vdwdup, M_MNEM_vidup, M_MNEM_viwdup): New instruction encodings. (NEON_SHAPE_DEF): New shapes. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 9196476..58b8258 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -16882,12 +16882,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); } @@ -23819,11 +23849,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 0000000..925d74e --- /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 0000000..9a01adb --- /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 0000000..c821f2b --- /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 -- 2.7.4