From 7df54120334049020e377ec17a0fdf4ecc63d6a7 Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Thu, 16 May 2019 11:40:26 +0100 Subject: [PATCH] [PATCH 18/57][Arm][GAS] Add support for MVE instructions: vhcadd, vhadd, vhsub and vrhadd gas/ChangeLog: 2019-05-16 Andre Vieira * config/tc-arm.c (enum operand_parse_code): New operand. (parse_operands): Handle new operand. (mve_encode_qqr): Change to support new instructions. (enum vfp_or_neon_is_neon_bits): Moved. (vfp_or_neon_is_neon): Moved. (check_simd_pred_availability): Moved. (do_neon_dyadic_i_su): Changed to support MVE variants. (neon_dyadic_misc): Changed mve_encode_qqr call. (do_mve_vbrsr): Likewise. (do_mve_vhcadd): New encoding function. (insns): Change existing to accept MVE variants and add new. * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d: New test. * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l: New test. * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s: New test. * testsuite/gas/arm/mve-vhcadd-bad.d: New test. * testsuite/gas/arm/mve-vhcadd-bad.l: New test. * testsuite/gas/arm/mve-vhcadd-bad.s: New test. --- gas/ChangeLog | 20 ++ gas/config/tc-arm.c | 243 +++++++++++------- .../gas/arm/mve-vhadd-vhsub-vrhadd-bad.d | 5 + .../gas/arm/mve-vhadd-vhsub-vrhadd-bad.l | 71 +++++ .../gas/arm/mve-vhadd-vhsub-vrhadd-bad.s | 69 +++++ gas/testsuite/gas/arm/mve-vhcadd-bad.d | 5 + gas/testsuite/gas/arm/mve-vhcadd-bad.l | 17 ++ gas/testsuite/gas/arm/mve-vhcadd-bad.s | 23 ++ 8 files changed, 358 insertions(+), 95 deletions(-) create mode 100644 gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d create mode 100644 gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l create mode 100644 gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s create mode 100644 gas/testsuite/gas/arm/mve-vhcadd-bad.d create mode 100644 gas/testsuite/gas/arm/mve-vhcadd-bad.l create mode 100644 gas/testsuite/gas/arm/mve-vhcadd-bad.s diff --git a/gas/ChangeLog b/gas/ChangeLog index d51ec393c0d..48141b89fb7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,23 @@ +2019-05-16 Andre Vieira + + * config/tc-arm.c (enum operand_parse_code): New operand. + (parse_operands): Handle new operand. + (mve_encode_qqr): Change to support new instructions. + (enum vfp_or_neon_is_neon_bits): Moved. + (vfp_or_neon_is_neon): Moved. + (check_simd_pred_availability): Moved. + (do_neon_dyadic_i_su): Changed to support MVE variants. + (neon_dyadic_misc): Changed mve_encode_qqr call. + (do_mve_vbrsr): Likewise. + (do_mve_vhcadd): New encoding function. + (insns): Change existing to accept MVE variants and add new. + * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d: New test. + * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l: New test. + * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s: New test. + * testsuite/gas/arm/mve-vhcadd-bad.d: New test. + * testsuite/gas/arm/mve-vhcadd-bad.l: New test. + * testsuite/gas/arm/mve-vhcadd-bad.s: New test. + 2019-05-16 Andre Vieira * config/tc-arm.c (do_neon_fmac): Change to support MVE variants. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 58b8258a475..cc555f8a7a0 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -6902,6 +6902,7 @@ enum operand_parse_code OP_RNSD, /* Neon single or double precision register */ OP_RNDQ, /* Neon double or quad precision register */ OP_RNDQMQ, /* Neon double, quad or MVE vector register. */ + OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */ OP_RNSDQ, /* Neon single, double or quad precision register */ OP_RNSC, /* Neon scalar D[X] */ OP_RVC, /* VFP control register */ @@ -7242,6 +7243,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb) try_nq: case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break; case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break; + case OP_RNDQMQR: + po_reg_or_goto (REG_TYPE_RN, try_rndqmq); + break; + try_rndqmq: case OP_oRNDQMQ: case OP_RNDQMQ: po_reg_or_goto (REG_TYPE_MQ, try_rndq); @@ -15820,7 +15825,7 @@ neon_dp_fixup (struct arm_it* insn) } static void -mve_encode_qqr (int size, int fp) +mve_encode_qqr (int size, int U, int fp) { if (inst.operands[2].reg == REG_SP) as_tsktsk (MVE_BAD_SP); @@ -15847,6 +15852,16 @@ mve_encode_qqr (int size, int fp) /* vsub. */ else if (((unsigned)inst.instruction) == 0x1000800) inst.instruction = 0xee011f40; + /* vhadd. */ + else if (((unsigned)inst.instruction) == 0) + inst.instruction = 0xee000f40; + /* vhsub. */ + else if (((unsigned)inst.instruction) == 0x200) + inst.instruction = 0xee001f40; + + /* Set U-bit. */ + inst.instruction |= U << 28; + /* Setting bits for size. */ inst.instruction |= neon_logbits (size) << 20; } @@ -15945,15 +15960,112 @@ neon_two_same (int qbit, int ubit, int size) neon_dp_fixup (&inst); } +enum vfp_or_neon_is_neon_bits +{ +NEON_CHECK_CC = 1, +NEON_CHECK_ARCH = 2, +NEON_CHECK_ARCH8 = 4 +}; + +/* Call this function if an instruction which may have belonged to the VFP or + Neon instruction sets, but turned out to be a Neon instruction (due to the + operand types involved, etc.). We have to check and/or fix-up a couple of + things: + + - Make sure the user hasn't attempted to make a Neon instruction + conditional. + - Alter the value in the condition code field if necessary. + - Make sure that the arch supports Neon instructions. + + Which of these operations take place depends on bits from enum + vfp_or_neon_is_neon_bits. + + WARNING: This function has side effects! If NEON_CHECK_CC is used and the + current instruction's condition is COND_ALWAYS, the condition field is + changed to inst.uncond_value. This is necessary because instructions shared + between VFP and Neon may be conditional for the VFP variants only, and the + unconditional Neon version must have, e.g., 0xF in the condition field. */ + +static int +vfp_or_neon_is_neon (unsigned check) +{ +/* Conditions are always legal in Thumb mode (IT blocks). */ +if (!thumb_mode && (check & NEON_CHECK_CC)) + { + if (inst.cond != COND_ALWAYS) + { + first_error (_(BAD_COND)); + return FAIL; + } + if (inst.uncond_value != -1) + inst.instruction |= inst.uncond_value << 28; + } + + + if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1)) + || ((check & NEON_CHECK_ARCH8) + && !mark_feature_used (&fpu_neon_ext_armv8))) + { + first_error (_(BAD_FPU)); + return FAIL; + } + +return SUCCESS; +} + +static int +check_simd_pred_availability (int fp, unsigned check) +{ +if (inst.cond > COND_ALWAYS) + { + if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) + { + inst.error = BAD_FPU; + return 1; + } + inst.pred_insn_type = INSIDE_VPT_INSN; + } +else if (inst.cond < COND_ALWAYS) + { + if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) + inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; + else if (vfp_or_neon_is_neon (check) == FAIL) + return 2; + } +else + { + if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext) + && vfp_or_neon_is_neon (check) == FAIL) + return 3; + + if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) + inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; + } +return 0; +} + /* Neon instruction encoders, in approximate order of appearance. */ static void do_neon_dyadic_i_su (void) { - enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL); - struct neon_type_el et = neon_check_type (3, rs, - N_EQK, N_EQK, N_SU_32 | N_KEY); - neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size); + if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)) + return; + + enum neon_shape rs; + struct neon_type_el et; + if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) + rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL); + else + rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL); + + et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY); + + + if (rs != NS_QQR) + neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size); + else + mve_encode_qqr (et.size, et.type == NT_unsigned, 0); } static void @@ -16120,90 +16232,6 @@ neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size) return FAIL; } -enum vfp_or_neon_is_neon_bits -{ -NEON_CHECK_CC = 1, -NEON_CHECK_ARCH = 2, -NEON_CHECK_ARCH8 = 4 -}; - -/* Call this function if an instruction which may have belonged to the VFP or - Neon instruction sets, but turned out to be a Neon instruction (due to the - operand types involved, etc.). We have to check and/or fix-up a couple of - things: - - - Make sure the user hasn't attempted to make a Neon instruction - conditional. - - Alter the value in the condition code field if necessary. - - Make sure that the arch supports Neon instructions. - - Which of these operations take place depends on bits from enum - vfp_or_neon_is_neon_bits. - - WARNING: This function has side effects! If NEON_CHECK_CC is used and the - current instruction's condition is COND_ALWAYS, the condition field is - changed to inst.uncond_value. This is necessary because instructions shared - between VFP and Neon may be conditional for the VFP variants only, and the - unconditional Neon version must have, e.g., 0xF in the condition field. */ - -static int -vfp_or_neon_is_neon (unsigned check) -{ -/* Conditions are always legal in Thumb mode (IT blocks). */ -if (!thumb_mode && (check & NEON_CHECK_CC)) - { - if (inst.cond != COND_ALWAYS) - { - first_error (_(BAD_COND)); - return FAIL; - } - if (inst.uncond_value != -1) - inst.instruction |= inst.uncond_value << 28; - } - - - if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1)) - || ((check & NEON_CHECK_ARCH8) - && !mark_feature_used (&fpu_neon_ext_armv8))) - { - first_error (_(BAD_FPU)); - return FAIL; - } - -return SUCCESS; -} - -static int -check_simd_pred_availability (int fp, unsigned check) -{ -if (inst.cond > COND_ALWAYS) - { - if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) - { - inst.error = BAD_FPU; - return 1; - } - inst.pred_insn_type = INSIDE_VPT_INSN; - } -else if (inst.cond < COND_ALWAYS) - { - if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) - inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; - else if (vfp_or_neon_is_neon (check) == FAIL) - return 2; - } -else - { - if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext) - && vfp_or_neon_is_neon (check) == FAIL) - return 3; - - if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) - inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; - } -return 0; -} - static void do_neon_logic (void) { @@ -16332,7 +16360,7 @@ neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types, { NEON_ENCODE (FLOAT, inst); if (rs == NS_QQR) - mve_encode_qqr (et.size, 1); + mve_encode_qqr (et.size, 0, 1); else neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1); } @@ -16340,7 +16368,7 @@ neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types, { NEON_ENCODE (INTEGER, inst); if (rs == NS_QQR) - mve_encode_qqr (et.size, 0); + mve_encode_qqr (et.size, 0, 0); else neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size); } @@ -16991,6 +17019,30 @@ do_mve_vaddv (void) mve_encode_rq (et.type == NT_unsigned, et.size); } +static void +do_mve_vhcadd (void) +{ + enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL); + struct neon_type_el et + = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY); + + if (inst.cond > COND_ALWAYS) + inst.pred_insn_type = INSIDE_VPT_INSN; + else + inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; + + unsigned rot = inst.relocs[0].exp.X_add_number; + constraint (rot != 90 && rot != 270, _("immediate out of range")); + + if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg) + as_tsktsk (_("Warning: 32-bit element size and same first and third " + "operand makes instruction UNPREDICTABLE")); + + mve_encode_qqq (0, et.size); + inst.instruction |= (rot == 270) << 12; + inst.is_neon = 1; +} + static void do_mve_vadc (void) { @@ -17021,7 +17073,7 @@ do_mve_vbrsr (void) else inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN; - mve_encode_qqr (et.size, 0); + mve_encode_qqr (et.size, 0, 0); } static void @@ -23585,11 +23637,8 @@ static const struct asm_opcode insns[] = /* integer ops, valid types S8 S16 S32 U8 U16 U32. */ NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su), NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su), - NUF(vhadd, 0000000, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su), NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su), - NUF(vrhadd, 0000100, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su), NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su), - NUF(vhsub, 0000200, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su), NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su), /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */ NUF(vqadd, 0000010, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su), @@ -24271,6 +24320,7 @@ static const struct asm_opcode insns[] = ToC("vpsteee", fe712f4d, 0, (), mve_vpt), /* MVE and MVE FP only. */ + mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd), mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc), mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc), mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc), @@ -24383,6 +24433,9 @@ static const struct asm_opcode insns[] = MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls), MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz), mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup), + MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su), + MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su), + MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su), #undef ARM_VARIANT #define ARM_VARIANT & arm_ext_v8_3 diff --git a/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d new file mode 100644 index 00000000000..acb12a42c67 --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.d @@ -0,0 +1,5 @@ +#name: bad MVE VHADD, VHSUB and VRHADD instructions +#as: -march=armv8.1-m.main+mve +#error_output: mve-vhadd-vhsub-vrhadd-bad.l + +.*: +file format .*arm.* diff --git a/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l new file mode 100644 index 00000000000..e49015c6639 --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.l @@ -0,0 +1,71 @@ +[^:]*: Assembler messages: +[^:]*:10: Error: bad type in SIMD instruction -- `vhadd.i8 q0,q1,q2' +[^:]*:11: Error: bad type in SIMD instruction -- `vhadd.s64 q0,q1,q2' +[^:]*:12: Error: bad type in SIMD instruction -- `vhadd.i8 q0,q1,r2' +[^:]*:13: Error: bad type in SIMD instruction -- `vhadd.s64 q0,q1,r2' +[^:]*:14: Error: bad type in SIMD instruction -- `vhsub.i16 q0,q1,q2' +[^:]*:15: Error: bad type in SIMD instruction -- `vhsub.u64 q0,q1,q2' +[^:]*:16: Error: bad type in SIMD instruction -- `vhsub.i16 q0,q1,r2' +[^:]*:17: Error: bad type in SIMD instruction -- `vhsub.u64 q0,q1,r2' +[^:]*:18: Error: bad type in SIMD instruction -- `vrhadd.i32 q0,q1,q2' +[^:]*:19: Error: bad type in SIMD instruction -- `vrhadd.s64 q0,q1,q2' +[^:]*:20: Warning: instruction is UNPREDICTABLE with SP operand +[^:]*:21: Warning: instruction is UNPREDICTABLE with PC operand +[^:]*:22: Warning: instruction is UNPREDICTABLE with SP operand +[^:]*:23: Warning: instruction is UNPREDICTABLE with PC operand +[^:]*:24: Error: garbage following instruction -- `vrhadd.s8 q0,q1,r2' +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:26: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:27: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:28: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:29: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:31: Error: syntax error -- `vhaddeq.s8 q0,q1,r2' +[^:]*:32: Error: syntax error -- `vhaddeq.s8 q0,q1,r2' +[^:]*:34: Error: syntax error -- `vhaddeq.s8 q0,q1,r2' +[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vhaddt.s8 q0,q1,r2' +[^:]*:37: Error: instruction missing MVE vector predication code -- `vhadd.s8 q0,q1,r2' +[^:]*:39: Error: syntax error -- `vhaddeq.s8 q0,q1,q2' +[^:]*:40: Error: syntax error -- `vhaddeq.s8 q0,q1,q2' +[^:]*:42: Error: syntax error -- `vhaddeq.s8 q0,q1,q2' +[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vhaddt.s8 q0,q1,q2' +[^:]*:45: Error: instruction missing MVE vector predication code -- `vhadd.s8 q0,q1,q2' +[^:]*:47: Error: syntax error -- `vhsubeq.s8 q0,q1,r2' +[^:]*:48: Error: syntax error -- `vhsubeq.s8 q0,q1,r2' +[^:]*:50: Error: syntax error -- `vhsubeq.s8 q0,q1,r2' +[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vhsubt.s8 q0,q1,r2' +[^:]*:53: Error: instruction missing MVE vector predication code -- `vhsub.s8 q0,q1,r2' +[^:]*:55: Error: syntax error -- `vhsubeq.s8 q0,q1,q2' +[^:]*:56: Error: syntax error -- `vhsubeq.s8 q0,q1,q2' +[^:]*:58: Error: syntax error -- `vhsubeq.s8 q0,q1,q2' +[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vhsubt.s8 q0,q1,q2' +[^:]*:61: Error: instruction missing MVE vector predication code -- `vhsub.s8 q0,q1,q2' +[^:]*:63: Error: syntax error -- `vrhaddeq.s8 q0,q1,q2' +[^:]*:64: Error: syntax error -- `vrhaddeq.s8 q0,q1,q2' +[^:]*:66: Error: syntax error -- `vrhaddeq.s8 q0,q1,q2' +[^:]*:67: Error: vector predicated instruction should be in VPT/VPST block -- `vrhaddt.s8 q0,q1,q2' +[^:]*:69: Error: instruction missing MVE vector predication code -- `vrhadd.s8 q0,q1,q2' diff --git a/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s new file mode 100644 index 00000000000..bebefc933b4 --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhadd-vhsub-vrhadd-bad.s @@ -0,0 +1,69 @@ +.macro cond, op, lastreg +.irp cond, eq, ne, gt, ge, lt, le +it \cond +\op\().s8 q0, q1, \lastreg +.endr +.endm + +.syntax unified +.thumb +vhadd.i8 q0, q1, q2 +vhadd.s64 q0, q1, q2 +vhadd.i8 q0, q1, r2 +vhadd.s64 q0, q1, r2 +vhsub.i16 q0, q1, q2 +vhsub.u64 q0, q1, q2 +vhsub.i16 q0, q1, r2 +vhsub.u64 q0, q1, r2 +vrhadd.i32 q0, q1, q2 +vrhadd.s64 q0, q1, q2 +vhadd.s8 q0, q1, sp +vhadd.s8 q0, q1, pc +vhsub.s8 q0, q1, sp +vhsub.s8 q0, q1, pc +vrhadd.s8 q0, q1, r2 +cond vhadd, r2 +cond vhadd, q2 +cond vhsub, r2 +cond vhsub, q2 +cond vrhadd, q2 +it eq +vhaddeq.s8 q0, q1, r2 +vhaddeq.s8 q0, q1, r2 +vpst +vhaddeq.s8 q0, q1, r2 +vhaddt.s8 q0, q1, r2 +vpst +vhadd.s8 q0, q1, r2 +it eq +vhaddeq.s8 q0, q1, q2 +vhaddeq.s8 q0, q1, q2 +vpst +vhaddeq.s8 q0, q1, q2 +vhaddt.s8 q0, q1, q2 +vpst +vhadd.s8 q0, q1, q2 +it eq +vhsubeq.s8 q0, q1, r2 +vhsubeq.s8 q0, q1, r2 +vpst +vhsubeq.s8 q0, q1, r2 +vhsubt.s8 q0, q1, r2 +vpst +vhsub.s8 q0, q1, r2 +it eq +vhsubeq.s8 q0, q1, q2 +vhsubeq.s8 q0, q1, q2 +vpst +vhsubeq.s8 q0, q1, q2 +vhsubt.s8 q0, q1, q2 +vpst +vhsub.s8 q0, q1, q2 +it eq +vrhaddeq.s8 q0, q1, q2 +vrhaddeq.s8 q0, q1, q2 +vpst +vrhaddeq.s8 q0, q1, q2 +vrhaddt.s8 q0, q1, q2 +vpst +vrhadd.s8 q0, q1, q2 diff --git a/gas/testsuite/gas/arm/mve-vhcadd-bad.d b/gas/testsuite/gas/arm/mve-vhcadd-bad.d new file mode 100644 index 00000000000..51b37a4bf1f --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhcadd-bad.d @@ -0,0 +1,5 @@ +#name: bad MVE VHCADD instructions +#as: -march=armv8.1-m.main+mve +#error_output: mve-vhcadd-bad.l + +.*: +file format .*arm.* diff --git a/gas/testsuite/gas/arm/mve-vhcadd-bad.l b/gas/testsuite/gas/arm/mve-vhcadd-bad.l new file mode 100644 index 00000000000..61200723dfa --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhcadd-bad.l @@ -0,0 +1,17 @@ +[^:]*: Assembler messages: +[^:]*:10: Error: bad type in SIMD instruction -- `vhcadd.u8 q0,q1,q2,#90' +[^:]*:11: Error: bad type in SIMD instruction -- `vhcadd.i8 q0,q1,q2,#90' +[^:]*:12: Error: bad type in SIMD instruction -- `vhcadd.s64 q0,q1,q2,#90' +[^:]*:13: Error: immediate out of range -- `vhcadd.s8 q0,q1,q2,#0' +[^:]*:14: Error: immediate out of range -- `vhcadd.s8 q0,q1,q2,#180' +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block +[^:]*:17: Error: syntax error -- `vhcaddeq.s8 q0,q1,q2,#90' +[^:]*:18: Error: syntax error -- `vhcaddeq.s8 q0,q1,q2,#90' +[^:]*:20: Error: syntax error -- `vhcaddeq.s8 q0,q1,q2,#90' +[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vhcaddt.s8 q0,q1,q2,#90' +[^:]*:23: Error: instruction missing MVE vector predication code -- `vhcadd.s8 q0,q1,q2,#90' diff --git a/gas/testsuite/gas/arm/mve-vhcadd-bad.s b/gas/testsuite/gas/arm/mve-vhcadd-bad.s new file mode 100644 index 00000000000..ede5b7e45e0 --- /dev/null +++ b/gas/testsuite/gas/arm/mve-vhcadd-bad.s @@ -0,0 +1,23 @@ +.macro cond +.irp cond, eq, ne, gt, ge, lt, le +it \cond +vhcadd.s8 q0, q1, q2, #90 +.endr +.endm + +.syntax unified +.thumb +vhcadd.u8 q0, q1, q2, #90 +vhcadd.i8 q0, q1, q2, #90 +vhcadd.s64 q0, q1, q2, #90 +vhcadd.s8 q0, q1, q2, #0 +vhcadd.s8 q0, q1, q2, #180 +cond +it eq +vhcaddeq.s8 q0, q1, q2, #90 +vhcaddeq.s8 q0, q1, q2, #90 +vpst +vhcaddeq.s8 q0, q1, q2, #90 +vhcaddt.s8 q0, q1, q2, #90 +vpst +vhcadd.s8 q0, q1, q2, #90 -- 2.30.2