public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
@ 2019-05-01 16:51 Andre Vieira (lists)
  2019-05-01 16:53 ` [PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp Andre Vieira (lists)
                   ` (60 more replies)
  0 siblings, 61 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:51 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, Richard Earnshaw

Hi,

This patch series adds support for all M-profile Vector Extension(MVE) 
instructions to GAS and Objdump.  Their specifications can be found on 
Arm Developer (see https://developer.arm.com/docs/ddi0553/latest).

The patch series is split into three main groups:
- patches 1-36 are GAS patches
- patches 37-56 are OBJDUMP patches
- patch 57 contains all positive testing

The reason to split the testing is because we use assembly macros to 
generate extensive testing, which leads to massive 'expected result' 
files. Which would require zipping most of the patches to be able to 
send them over email. So instead we decided to collate all positive 
testing into one patch and only zip that one. The negative tests are 
smaller and have been included per relevant patch.

The expected value for positive tests have been compared to a different, 
internal implementation.

Cheers,
Andre

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
@ 2019-05-01 16:53 ` Andre Vieira (lists)
  2019-05-01 16:55 ` [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd Andre Vieira (lists)
                   ` (59 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:53 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]

Add CLI support for the mve architecture extensions.

Is this OK for trunk?

Cheers,
Andre

bfd/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* elf32-arm.c (elf32_arm_merge_eabi_attributes): Add case
         for Tag_MVE_arch

binutils/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* readelf.c (arm_attr_tag_MVE_arch): New array for Tag_MVE_arch
         values.
         (arm_attr_public_tag arm_attr_public_tags): Add case for
         Tag_MVE_arch

elfcpp/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* arm.h (Tag_MVE_arch): Define new enum value.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (mve_ext, mve_fp_ext): New features.
         (armv8_1m_main_ext_table): Add new extensions.
         (aeabi_set_public_attributes): Translate new features to
         new build attributes.
         (arm_convert_symbolic_attribute): Add Tag_MVE_arch.

         * doc/c-arm.texi: Document new extensions and new build attribute.

include/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* elf/arm.h (Tag_MVE_arch): Define new enum value.
	* opcode/arm.h (FPU_MVE, FPU_MVE_FP): New MACROs
         for new features.

[-- Attachment #2: 1.patch --]
[-- Type: text/x-patch, Size: 6261 bytes --]

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index dfe65d6d01588bdc588f22a65b979b2234bacb41..0970669b16cc150b8b296c16e55a2b8750184a9d 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -14712,6 +14712,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
 	case Tag_CPU_unaligned_access:
 	case Tag_T2EE_use:
 	case Tag_MPextension_use:
+	case Tag_MVE_arch:
 	  /* Use the largest value specified.  */
 	  if (in_attr[i].i > out_attr[i].i)
 	    out_attr[i].i = in_attr[i].i;
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1fe71824776d979365ae936c6e35af8558da2683..dc7e5805c31654a530836f3e079e7247df89f24d 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14434,6 +14434,9 @@ static const char * arm_attr_tag_Virtualization_use[] =
 static const char * arm_attr_tag_MPextension_use_legacy[] =
   {"Not Allowed", "Allowed"};
 
+static const char * arm_attr_tag_MVE_arch[] =
+  {"No MVE", "MVE Integer only", "MVE Integer and FP"};
+
 #define LOOKUP(id, name) \
   {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
 static arm_attr_public_tag arm_attr_public_tags[] =
@@ -14473,6 +14476,7 @@ static arm_attr_public_tag arm_attr_public_tags[] =
   LOOKUP(42, MPextension_use),
   LOOKUP(44, DIV_use),
   LOOKUP(46, DSP_extension),
+  LOOKUP(48, MVE_arch),
   {64, "nodefaults", 0, NULL},
   {65, "also_compatible_with", 0, NULL},
   LOOKUP(66, T2EE_use),
diff --git a/elfcpp/arm.h b/elfcpp/arm.h
index 19048658ece500ef4406972a453d79d283a4e805..aa573440c28035701b5ea0c265de38b800c63fa0 100644
--- a/elfcpp/arm.h
+++ b/elfcpp/arm.h
@@ -305,6 +305,7 @@ enum
   Tag_MPextension_use = 42,
   Tag_undefined43 = 43,
   Tag_DIV_use = 44,
+  Tag_MVE_arch = 48,
   Tag_nodefaults = 64,
   Tag_also_compatible_with = 65,
   Tag_T2EE_use = 66,
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 8035fa1db4dcf88393c96f8d54a55766ca1ab580..692a73cc20be01a043dfff5fbf4ab0d3bdc87f2c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -302,6 +302,10 @@ static const arm_feature_set fpu_neon_ext_v1 =
   ARM_FEATURE_COPROC (FPU_NEON_EXT_V1);
 static const arm_feature_set fpu_vfp_v3_or_neon_ext =
   ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
+static const arm_feature_set mve_ext =
+  ARM_FEATURE_COPROC (FPU_MVE);
+static const arm_feature_set mve_fp_ext =
+  ARM_FEATURE_COPROC (FPU_MVE_FP);
 #ifdef OBJ_ELF
 static const arm_feature_set fpu_vfp_fp16 =
   ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
@@ -27251,6 +27255,12 @@ static const struct arm_ext_table armv8_1m_main_ext_table[] =
   ARM_ADD ("fp.dp",
 	   ARM_FEATURE (0, ARM_EXT2_FP16_INST,
 			FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
+  ARM_EXT ("mve", ARM_FEATURE_COPROC (FPU_MVE),
+	   ARM_FEATURE_COPROC (FPU_MVE | FPU_MVE_FP)),
+  ARM_ADD ("mve.fp",
+	   ARM_FEATURE (0, ARM_EXT2_FP16_INST,
+			FPU_MVE | FPU_MVE_FP | FPU_VFP_V5_SP_D16 |
+			FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
   { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
 };
 
@@ -28428,6 +28438,11 @@ aeabi_set_public_attributes (void)
 	}
     }
 
+  if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
+    aeabi_set_attribute_int (Tag_MVE_arch, 2);
+  else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
+    aeabi_set_attribute_int (Tag_MVE_arch, 1);
+
   /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch).  */
   if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
     aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
@@ -28769,6 +28784,7 @@ arm_convert_symbolic_attribute (const char *name)
       T (Tag_T2EE_use),
       T (Tag_Virtualization_use),
       T (Tag_DSP_extension),
+      T (Tag_MVE_arch),
       /* We deliberately do not include Tag_MPextension_use_legacy.  */
 #undef T
     };
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index 4c595d8bf0ee7a3b0ff77e1ddc6ab073c5c3e589..d35a34df47e197d9f836cc1da76c89b230a741dd 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -363,8 +363,13 @@ For @code{armv8.1-m.main}:
 for Armv8.1-M Mainline with 16 double-word registers.
 @code{+fp.dp}: Enables double precision scalar Floating Point Extensions for
 Armv8.1-M Mainline, implies @code{+fp}.
+@code{+mve}: Enables integer only M-profile Vector Extension for
+Armv8.1-M Mainline, implies @code{+dsp}.
+@code{+mve.fp}: Enables Floating Point M-profile Vector Extension for
+Armv8.1-M Mainline, implies @code{+mve} and @code{+fp}.
 @code{+nofp}: Disables all FPU instructions.
 @code{+nodsp}: Disables DSP Extension.
+@code{+nomve}: Disables all M-profile Vector Extensions.
 
 For @code{armv8-a}:
 
@@ -891,7 +896,7 @@ The @var{tag} is either an attribute number, or one of the following:
 @code{Tag_CPU_raw_name}, @code{Tag_CPU_name}, @code{Tag_CPU_arch},
 @code{Tag_CPU_arch_profile}, @code{Tag_ARM_ISA_use},
 @code{Tag_THUMB_ISA_use}, @code{Tag_FP_arch}, @code{Tag_WMMX_arch},
-@code{Tag_Advanced_SIMD_arch}, @code{Tag_PCS_config},
+@code{Tag_Advanced_SIMD_arch}, @code{Tag_MVE_arch}, @code{Tag_PCS_config},
 @code{Tag_ABI_PCS_R9_use}, @code{Tag_ABI_PCS_RW_data},
 @code{Tag_ABI_PCS_RO_data}, @code{Tag_ABI_PCS_GOT_use},
 @code{Tag_ABI_PCS_wchar_t}, @code{Tag_ABI_FP_rounding},
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 9f22ffed2b5c664c72ff53fafdf9c074d1e126b9..5cb99706443838cd2d43accab9e713d53304bd00 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -326,6 +326,7 @@ enum
   Tag_undefined_43,
   Tag_DIV_use,
   Tag_DSP_extension = 46,
+  Tag_MVE_arch = 48,
   Tag_nodefaults = 64,
   Tag_also_compatible_with,
   Tag_T2EE_use,
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 73fb2e3f43c5fd2d77dc796b7decb329c5a8a57f..a870905907b38f001812f460e3cd816e9675f851 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -103,6 +103,8 @@
 #define FPU_VFP_EXT_ARMV8xD  0x00002000	/* Single-precision FP for ARMv8.  */
 #define FPU_NEON_EXT_RDMA    0x00001000	/* v8.1 Adv.SIMD extensions.	   */
 #define FPU_NEON_EXT_DOTPROD 0x00000800	/* Dot Product extension.	   */
+#define FPU_MVE		     0x00000400 /* MVE Integer extension.	   */
+#define FPU_MVE_FP	     0x00000200 /* MVE Floating Point extension.   */
 
 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
  2019-05-01 16:53 ` [PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp Andre Vieira (lists)
@ 2019-05-01 16:55 ` Andre Vieira (lists)
  2019-05-02 10:56   ` Nick Clifton
  2019-05-01 16:56 ` [PATCH 3/57][Arm][GAS] Add support for MVE instructions: vabs and vneg Andre Vieira (lists)
                   ` (58 subsequent siblings)
  60 siblings, 1 reply; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:55 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 6804 bytes --]

Hello,

This patch adds most of the framework used by the rest of the GAS 
patches for MVE.

This framework adds
1) VPT/VPST block-handling, reusing IT-block handling already present in 
GAS. This patch also cleans up the IT-block handling
adding more appropriate diagnostics for instructions used inside an IT 
block where they shouldn't, or using condition codes when they are not 
allowed.
The comments above the now named 'handle_pred_state' function, explain 
this in detail.

2) Helper functions to check neon availability and/or mve.


This patch further implements the MVE instructions VPST, VADD, VSUB and 
VABD.  VPST is completely new. But VADD, VSUB and VABD clash mnemonic 
wise with NEON, this patch illustrates how other instructions with 
similar mnemonic clashes are handled.

Cheers,
Andre



gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum it_instruction_type): Rename to...
         (enum pred_instruction_type): ... this. Include VPT types.
         (it_insn_type): Rename to ...
         (pred_insn_type): .. this.
         (arm_it): Change comment.
        	(enum arm_reg_type): Add new value.
         (reg_expected_msgs): New entry.
         (asm_opcode): Add mayBeVecPred member.
         (BAD_SYNTAX, BAD_NOT_VPT, BAD_OUT_VPT, BAD_VPT_COND, MVE_NOT_IT,
          MVE_NOT_VPT, MVE_BAD_PC, MVE_BAD_SP): New diagnostic MACROS.
         (arm_vcond_hsh): New table for vector condition codes.
	(now_it): Rename to ...
	(now_pred): ... this.
	(now_it_compatible): Rename to ...
	(now_pred_compatible): ... this.
	(in_it_block): Rename to ...
	(in_pred_block): ... this.
	(handle_it_state): Rename to ...
	(handle_pred_state): ... this. And change it to accept VPT blocks.
	(set_it_insn_type): Rename to ...
	(set_pred_insn_type): ... this.
	(set_it_insn_type_nonvoid): Rename to ...
	(set_pred_insn_type_nonvoid): ... this.
	(set_it_insn_type_last): Rename to ...
	(set_pred_insn_type_last): ... this.
	(record_feature_use): Moved.
	(mark_feature_used): Likewise.
	(parse_typed_reg_or_scalar): Add new case for REG_TYPE_MQ.
	(emit_insn): Use renamed functions and variables.
   	(enum operand_parse_code): Add new operands.
	(parse_operands): Handle new operands.
	(do_scalar_fp16_v82_encode): Change predication detection.
	(do_it): Use renamed functions and variables.
	(do_t_add_sub): Likewise.
	(do_t_arit3): Likewise.
	(do_t_arit3c): Likewise.
	(do_t_blx): Likewise.
	(do_t_branch): Likewise.
	(do_t_bkpt_hlt1): Likewise.
	(do_t_branch23): Likewise.
	(do_t_bx): Likewise.
	(do_t_bxj): Likewise.
	(do_t_cond): Likewise.
	(do_t_csdb): Likewise.
	(do_t_cps): Likewise.
	(do_t_cpsi): Likewise.
	(do_t_cbz): Likewise.
	(do_t_it): Likewise.
	(do_mve_vpt): New function to handle VPT blocks.
	(encode_thumb2_multi): Use renamed functions and variables.
	(do_t_ldst): Use renamed functions and variables.
	(do_t_mov_cmp): Likewise.
	(do_t_mvn_tst): Likewise.
	(do_t_mul): Likewise.
	(do_t_nop): Likewise.
	(do_t_neg): Likewise.
	(do_t_rsb): Likewise.
	(do_t_setend): Likewise.
	(do_t_shift): Likewise.
	(do_t_smc): Likewise.
	(do_t_tb): Likewise.
	(do_t_udf): Likewise.
	(do_t_loloop): Likewise.
	(do_neon_cvt_1): Likewise.
	(do_vfp_nsyn_cvt_fpv8): Likewise.
	(do_vsel): Likewise.
	(do_vmaxnm): Likewise.
	(do_vrint_1): Likewise.
	(do_crypto_2op_1): Likewise.
	(do_crypto_3op_1): Likewise.
	(do_crc32_1): Likewise.
	(it_fsm_pre_encode): Likewise.
	(it_fsm_post_encode): Likewise.
	(force_automatic_it_block_close): Likewise.
	(check_it_blocks_finished): Likewise.
	(check_pred_blocks_finished): Likewise.
	(arm_cleanup): Likewise.
	(now_it_add_mask): Rename to ...
	(now_pred_add_mask): ... this. And use new variables and functions.
	(NEON_ENC_TAB): Add entries for vabdl, vaddl and vsubl.
       	(N_I_MVE, N_F_MVE, N_SU_MVE): New MACROs.
	(neon_check_type): Generalize error message.
	(mve_encode_qqr): New MVE generic encoding function.
	(neon_dyadic_misc): Change to accept MVE variants.
	(do_neon_dyadic_if_su): Likewise.
	(do_neon_addsub_if_i): Likewise.
	(do_neon_dyadic_long): Likewise.
	(vfp_or_neon_is_neon): Add extra checks.
	(check_simd_pred_availability): Helper function to check
         SIMD instruction availability with respect to predication.
	(enum opcode_tag): New suffix value.
	(opcode_lookup): Change to handle VPT blocks.
	(new_automatic_it_block): Rename to ...
	(close_automatic_it_block): ...this.
         (TxCE, TxC3, TxC3w, TUE, TUEc, TUF, CE, C3, ToC, ToU,
         toC, toU, CL, cCE, cCL, C3E, xCM_, UE, UF, NUF, nUF,
         NCE_tag, NCE, NCEF, nCE_tag, nCE, nCEF): Add default value for new
         field.
         (mCEF, mnCEF, mnCE, MNUF, mnUF, mToC, MNCE, MNCEF): New
         MACROs.
         (insns): Redefine vadd, vsub, cabd, vabdl, vaddl, vsubl to accept
         MVE variants. Add entries for vscclrm, and vpst.
         (md_begin): Add arm_vcond_hsh initialization.
	* config/tc-arm.h (enum it_state): Rename to...
	(enum pred_state): ...this.
	(struct current_it): Rename to...
	(struct current_pred): ...this.
	(enum pred_type): New enum.
	(struct arm_segment_info_type): Use current_pred.
	* testsuite/gas/arm/armv8_3-a-fp-bad.l: Update error message.
	* testsuite/gas/arm/armv8_3-a-simd-bad.l: Update error message.
	* testsuite/gas/arm/dotprod-illegal.l: Update error message.
	* testsuite/gas/arm/mve-vaddsubabd-bad-1.d: New test.
	* testsuite/gas/arm/mve-vaddsubabd-bad-1.l: New test.
	* testsuite/gas/arm/mve-vaddsubabd-bad-1.s: New test.
	* testsuite/gas/arm/mve-vaddsubabd-bad-2.d: New test.
	* testsuite/gas/arm/mve-vaddsubabd-bad-2.l: New test.
	* testsuite/gas/arm/mve-vaddsubabd-bad-2.s: New test.
	* testsuite/gas/arm/mve-vpst-bad.d: New test.
	* testsuite/gas/arm/mve-vpst-bad.l: New test.
	* testsuite/gas/arm/mve-vpst-bad.s: New test.
	* testsuite/gas/arm/neon-ldst-es-bad.l:

On 01/05/2019 17:51, Andre Vieira (lists) wrote:
> Hi,
> 
> This patch series adds support for all M-profile Vector Extension(MVE) 
> instructions to GAS and Objdump.  Their specifications can be found on 
> Arm Developer (see https://developer.arm.com/docs/ddi0553/latest).
> 
> The patch series is split into three main groups:
> - patches 1-36 are GAS patches
> - patches 37-56 are OBJDUMP patches
> - patch 57 contains all positive testing
> 
> The reason to split the testing is because we use assembly macros to 
> generate extensive testing, which leads to massive 'expected result' 
> files. Which would require zipping most of the patches to be able to 
> send them over email. So instead we decided to collate all positive 
> testing into one patch and only zip that one. The negative tests are 
> smaller and have been included per relevant patch.
> 
> The expected value for positive tests have been compared to a different, 
> internal implementation.
> 
> Cheers,
> Andre

[-- Attachment #2: 2.patch --]
[-- Type: text/x-patch, Size: 98828 bytes --]

diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 0d5e79c7ad9fe9a8c416d6f95609a0e2596eba26..39cc9680b96524c730c15fff1af22b180b9c70d1 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -254,21 +254,25 @@ arm_min (int am_p1, int am_p2)
 /* Registers are generally saved at negative offsets to the CFA.  */
 #define DWARF2_CIE_DATA_ALIGNMENT     (-4)
 
-/* State variables for IT block handling.  */
-enum it_state
+/* State variables for predication block handling.  */
+enum pred_state
 {
-  OUTSIDE_IT_BLOCK, MANUAL_IT_BLOCK, AUTOMATIC_IT_BLOCK
+  OUTSIDE_PRED_BLOCK, MANUAL_PRED_BLOCK, AUTOMATIC_PRED_BLOCK
 };
-struct current_it
+enum pred_type {
+  SCALAR_PRED, VECTOR_PRED
+};
+struct current_pred
 {
   int mask;
-  enum it_state state;
+  enum pred_state state;
   int cc;
   int block_length;
   char *insn;
   int state_handled;
   int warn_deprecated;
   int insn_cond;
+  enum pred_type type;
 };
 
 #ifdef OBJ_ELF
@@ -303,7 +307,7 @@ struct arm_segment_info_type
      emitted only once per section, to save unnecessary bloat.  */
   unsigned int marked_pr_dependency;
 
-  struct current_it current_it;
+  struct current_pred current_pred;
 };
 
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 692a73cc20be01a043dfff5fbf4ab0d3bdc87f2c..19729d290c7c5de95ee620d5b6817ab6497b613d 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -453,16 +453,20 @@ struct neon_type
   unsigned elems;
 };
 
-enum it_instruction_type
+enum pred_instruction_type
 {
-   OUTSIDE_IT_INSN,
+   OUTSIDE_PRED_INSN,
+   INSIDE_VPT_INSN,
    INSIDE_IT_INSN,
    INSIDE_IT_LAST_INSN,
    IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
 			      if inside, should be the last one.  */
    NEUTRAL_IT_INSN,        /* This could be either inside or outside,
 			      i.e. BKPT and NOP.  */
-   IT_INSN                 /* The IT insn has been parsed.  */
+   IT_INSN,		   /* The IT insn has been parsed.  */
+   VPT_INSN,		   /* The VPT/VPST insn has been parsed.  */
+   MVE_OUTSIDE_PRED_INSN   /* Instruction to indicate a MVE instruction without
+			      a predication code.  */
 };
 
 /* The maximum number of operands we need.  */
@@ -494,7 +498,7 @@ struct arm_it
     int			     pc_rel;
   } relocs[ARM_IT_MAX_RELOCS];
 
-  enum it_instruction_type it_insn_type;
+  enum pred_instruction_type pred_insn_type;
 
   struct
   {
@@ -511,7 +515,7 @@ struct arm_it
        instructions. This allows us to disambiguate ARM <-> vector insns.  */
     unsigned regisimm   : 1;  /* 64-bit immediate, reg forms high 32 bits.  */
     unsigned isvec      : 1;  /* Is a single, double or quad VFP/Neon reg.  */
-    unsigned isquad     : 1;  /* Operand is Neon quad-precision register.  */
+    unsigned isquad     : 1;  /* Operand is SIMD quad register.  */
     unsigned issingle   : 1;  /* Operand is VFP single-precision register.  */
     unsigned hasreloc	: 1;  /* Operand has relocation suffix.  */
     unsigned writeback	: 1;  /* Operand has trailing !  */
@@ -633,12 +637,13 @@ enum arm_reg_type
   REG_TYPE_MVFX,
   REG_TYPE_MVDX,
   REG_TYPE_MVAX,
+  REG_TYPE_MQ,
   REG_TYPE_DSPSC,
   REG_TYPE_MMXWR,
   REG_TYPE_MMXWC,
   REG_TYPE_MMXWCG,
   REG_TYPE_XSCALE,
-  REG_TYPE_RNB
+  REG_TYPE_RNB,
 };
 
 /* Structure for a hash table entry for a register.
@@ -680,6 +685,7 @@ const char * const reg_expected_msgs[] =
   [REG_TYPE_MMXWC]  = N_("iWMMXt control register expected"),
   [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
   [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
+  [REG_TYPE_MQ]	    = N_("MVE vector register expected"),
   [REG_TYPE_RNB]    = N_("")
 };
 
@@ -719,6 +725,9 @@ struct asm_opcode
 
   /* Function to call to encode instruction in Thumb format.  */
   void (* tencode) (void);
+
+  /* Indicates whether this instruction may be vector predicated.  */
+  unsigned int mayBeVecPred : 1;
 };
 
 /* Defines for various bits that we will want to toggle.  */
@@ -841,6 +850,7 @@ struct asm_opcode
 #define THUMB_LOAD_BIT 0x0800
 #define THUMB2_LOAD_BIT 0x00100000
 
+#define BAD_SYNTAX	_("syntax error")
 #define BAD_ARGS	_("bad arguments to instruction")
 #define BAD_SP          _("r13 not allowed here")
 #define BAD_PC		_("r15 not allowed here")
@@ -852,9 +862,13 @@ struct asm_opcode
 #define BAD_BRANCH	_("branch must be last instruction in IT block")
 #define BAD_BRANCH_OFF	_("branch out of range or not a multiple of 2")
 #define BAD_NOT_IT	_("instruction not allowed in IT block")
+#define BAD_NOT_VPT	_("instruction missing MVE vector predication code")
 #define BAD_FPU		_("selected FPU does not support instruction")
 #define BAD_OUT_IT 	_("thumb conditional instruction should be in IT block")
+#define BAD_OUT_VPT	\
+	_("vector predicated instruction should be in VPT/VPST block")
 #define BAD_IT_COND	_("incorrect condition in IT block")
+#define BAD_VPT_COND	_("incorrect condition in VPT/VPST block")
 #define BAD_IT_IT 	_("IT falling in the range of a previous IT block")
 #define MISSING_FNSTART	_("missing .fnstart before unwinding directive")
 #define BAD_PC_ADDRESSING \
@@ -865,9 +879,18 @@ struct asm_opcode
 #define BAD_FP16	_("selected processor does not support fp16 instruction")
 #define UNPRED_REG(R)	_("using " R " results in unpredictable behaviour")
 #define THUMB1_RELOC_ONLY  _("relocation valid in thumb1 code only")
+#define MVE_NOT_IT	_("Warning: instruction is UNPREDICTABLE in an IT " \
+			  "block")
+#define MVE_NOT_VPT	_("Warning: instruction is UNPREDICTABLE in a VPT " \
+			  "block")
+#define MVE_BAD_PC	_("Warning: instruction is UNPREDICTABLE with PC" \
+			  " operand")
+#define MVE_BAD_SP	_("Warning: instruction is UNPREDICTABLE with SP" \
+			  " operand")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
+static struct hash_control * arm_vcond_hsh;
 static struct hash_control * arm_shift_hsh;
 static struct hash_control * arm_psr_hsh;
 static struct hash_control * arm_v7m_psr_hsh;
@@ -919,15 +942,15 @@ typedef enum asmfunc_states
 static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
 
 #ifdef OBJ_ELF
-#  define now_it seg_info (now_seg)->tc_segment_info_data.current_it
+#  define now_pred seg_info (now_seg)->tc_segment_info_data.current_pred
 #else
-static struct current_it now_it;
+static struct current_pred now_pred;
 #endif
 
 static inline int
-now_it_compatible (int cond)
+now_pred_compatible (int cond)
 {
-  return (cond & ~1) == (now_it.cc & ~1);
+  return (cond & ~1) == (now_pred.cc & ~1);
 }
 
 static inline int
@@ -936,39 +959,39 @@ conditional_insn (void)
   return inst.cond != COND_ALWAYS;
 }
 
-static int in_it_block (void);
+static int in_pred_block (void);
 
-static int handle_it_state (void);
+static int handle_pred_state (void);
 
 static void force_automatic_it_block_close (void);
 
 static void it_fsm_post_encode (void);
 
-#define set_it_insn_type(type)			\
+#define set_pred_insn_type(type)			\
   do						\
     {						\
-      inst.it_insn_type = type;			\
-      if (handle_it_state () == FAIL)		\
+      inst.pred_insn_type = type;			\
+      if (handle_pred_state () == FAIL)		\
 	return;					\
     }						\
   while (0)
 
-#define set_it_insn_type_nonvoid(type, failret) \
+#define set_pred_insn_type_nonvoid(type, failret) \
   do						\
     {                                           \
-      inst.it_insn_type = type;			\
-      if (handle_it_state () == FAIL)		\
+      inst.pred_insn_type = type;			\
+      if (handle_pred_state () == FAIL)		\
 	return failret;				\
     }						\
   while(0)
 
-#define set_it_insn_type_last()				\
+#define set_pred_insn_type_last()				\
   do							\
     {							\
       if (inst.cond == COND_ALWAYS)			\
-	set_it_insn_type (IF_INSIDE_IT_LAST_INSN);	\
+	set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);	\
       else						\
-	set_it_insn_type (INSIDE_IT_LAST_INSN);		\
+	set_pred_insn_type (INSIDE_IT_LAST_INSN);		\
     }							\
   while (0)
 
@@ -1500,6 +1523,32 @@ parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
 #define NEON_ALL_LANES		15
 #define NEON_INTERLEAVE_LANES	14
 
+/* Record a use of the given feature.  */
+static void
+record_feature_use (const arm_feature_set *feature)
+{
+  if (thumb_mode)
+    ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
+  else
+    ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
+}
+
+/* If the given feature available in the selected CPU, mark it as used.
+   Returns TRUE iff feature is available.  */
+static bfd_boolean
+mark_feature_used (const arm_feature_set *feature)
+{
+  /* Ensure the option is valid on the current architecture.  */
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
+    return FALSE;
+
+  /* Add the appropriate architecture feature for the barrier option used.
+     */
+  record_feature_use (feature);
+
+  return TRUE;
+}
+
 /* Parse either a register or a scalar, with an optional type. Return the
    register number, and optionally fill in the actual type of the register
    when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
@@ -1546,6 +1595,26 @@ parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
 	  && (reg->type == REG_TYPE_MMXWCG)))
     type = (enum arm_reg_type) reg->type;
 
+  if (type == REG_TYPE_MQ)
+    {
+      if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	return FAIL;
+
+      if (!reg || reg->type != REG_TYPE_NQ)
+	return FAIL;
+
+      if (reg->number > 14 && !mark_feature_used (&fpu_vfp_ext_d32))
+	{
+	  first_error (_("expected MVE register [q0..q7]"));
+	  return FAIL;
+	}
+      type = REG_TYPE_NQ;
+    }
+  else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+	   && (type == REG_TYPE_NQ))
+    return FAIL;
+
+
   if (type != reg->type)
     return FAIL;
 
@@ -3765,10 +3834,10 @@ emit_insn (expressionS *exp, int nbytes)
 	    }
 	  else
 	    {
-	      if (now_it.state == AUTOMATIC_IT_BLOCK)
-		set_it_insn_type_nonvoid (OUTSIDE_IT_INSN, 0);
+	      if (now_pred.state == AUTOMATIC_PRED_BLOCK)
+		set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
 	      else
-		set_it_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
+		set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
 
 	      if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
 		emit_thumb32_expr (exp);
@@ -6296,31 +6365,6 @@ parse_cond (char **str)
   return c->value;
 }
 
-/* Record a use of the given feature.  */
-static void
-record_feature_use (const arm_feature_set *feature)
-{
-  if (thumb_mode)
-    ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
-  else
-    ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
-}
-
-/* If the given feature is currently allowed, mark it as used and return TRUE.
-   Return FALSE otherwise.  */
-static bfd_boolean
-mark_feature_used (const arm_feature_set *feature)
-{
-  /* Ensure the option is currently allowed.  */
-  if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
-    return FALSE;
-
-  /* Add the appropriate architecture feature for the barrier option used.  */
-  record_feature_use (feature);
-
-  return TRUE;
-}
-
 /* Parse an option for a barrier instruction.  Returns the encoding for the
    option, or FAIL.  */
 static int
@@ -6646,10 +6690,15 @@ enum operand_parse_code
   OP_RVS,	/* VFP single precision register */
   OP_RVD,	/* VFP double precision register (0..15) */
   OP_RND,       /* Neon double precision register (0..31) */
+  OP_RNDMQ,     /* Neon double precision (0..31) or MVE vector register.  */
+  OP_RNDMQR,    /* Neon double precision (0..31), MVE vector or ARM register.
+		 */
   OP_RNQ,	/* Neon quad precision register */
+  OP_RNQMQ,	/* Neon quad or MVE vector register.  */
   OP_RVSD,	/* VFP single or double precision register */
   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_RNSDQ,	/* Neon single, double or quad precision register */
   OP_RNSC,      /* Neon scalar D[X] */
   OP_RVC,	/* VFP control register */
@@ -6664,6 +6713,10 @@ enum operand_parse_code
   OP_RIWG,	/* iWMMXt wCG register */
   OP_RXA,	/* XScale accumulator register */
 
+  OP_RNSDQMQ,	/* Neon single, double or quad register or MVE vector register
+		 */
+  OP_RNSDQMQR,	/* Neon single, double or quad register, MVE vector register or
+		   GPR (no SP/SP)  */
   /* New operands for Armv8.1-M Mainline.  */
   OP_LR,	/* ARM LR register */
   OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
@@ -6756,8 +6809,11 @@ enum operand_parse_code
   OP_oRRw,	 /* ARM register, not r15, optional trailing ! */
   OP_oRND,       /* Optional Neon double precision register */
   OP_oRNQ,       /* Optional Neon quad precision register */
+  OP_oRNDQMQ,     /* Optional Neon double, quad or MVE vector register.  */
   OP_oRNDQ,      /* Optional Neon double or quad precision register */
   OP_oRNSDQ,	 /* Optional single, double or quad precision vector register */
+  OP_oRNSDQMQ,	 /* Optional single, double or quad register or MVE vector
+		    register.  */
   OP_oSHll,	 /* LSL immediate */
   OP_oSHar,	 /* ASR immediate */
   OP_oSHllar,	 /* LSL or ASR immediate */
@@ -6929,6 +6985,14 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_RVS:   po_reg_or_fail (REG_TYPE_VFS);	  break;
 	case OP_RVD:   po_reg_or_fail (REG_TYPE_VFD);	  break;
 	case OP_oRND:
+	case OP_RNDMQR:
+	  po_reg_or_goto (REG_TYPE_RN, try_rndmq);
+	  break;
+	try_rndmq:
+	case OP_RNDMQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rnd);
+	  break;
+	try_rnd:
 	case OP_RND:   po_reg_or_fail (REG_TYPE_VFD);	  break;
 	case OP_RVC:
 	  po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
@@ -6948,14 +7012,34 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_RIWG:  po_reg_or_fail (REG_TYPE_MMXWCG);  break;
 	case OP_RXA:   po_reg_or_fail (REG_TYPE_XSCALE);  break;
 	case OP_oRNQ:
+	case OP_RNQMQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_nq);
+	  break;
+	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_oRNDQMQ:
+	case OP_RNDQMQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rndq);
+	  break;
+	try_rndq:
 	case OP_oRNDQ:
 	case OP_RNDQ:  po_reg_or_fail (REG_TYPE_NDQ);     break;
 	case OP_RVSD:  po_reg_or_fail (REG_TYPE_VFSD);    break;
 	case OP_oRNSDQ:
 	case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ);    break;
-
+	case OP_RNSDQMQR:
+	  po_reg_or_goto (REG_TYPE_RN, try_mq);
+	  break;
+	  try_mq:
+	case OP_oRNSDQMQ:
+	case OP_RNSDQMQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
+	  break;
+	  try_nsdq2:
+	  po_reg_or_fail (REG_TYPE_NSDQ);
+	  inst.error = 0;
+	  break;
 	/* Neon scalar. Using an element size of 8 means that some invalid
 	   scalars are accepted here, so deal with those in later code.  */
 	case OP_RNSC:  po_scalar_or_goto (8, failure);    break;
@@ -7493,7 +7577,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  /* The parse routine should already have set inst.error, but set a
 	     default here just in case.  */
 	  if (!inst.error)
-	    inst.error = _("syntax error");
+	    inst.error = BAD_SYNTAX;
 	  return FAIL;
 	}
 
@@ -7505,7 +7589,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  && upat[i+1] == OP_stop)
 	{
 	  if (!inst.error)
-	    inst.error = _("syntax error");
+	    inst.error = BAD_SYNTAX;
 	  return FAIL;
 	}
 
@@ -7586,7 +7670,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 static void
 do_scalar_fp16_v82_encode (void)
 {
-  if (inst.cond != COND_ALWAYS)
+  if (inst.cond < COND_ALWAYS)
     as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
 	       " the behaviour is UNPREDICTABLE"));
   constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
@@ -9059,9 +9143,9 @@ do_it (void)
   inst.size = 0;
   if (unified_syntax)
     {
-      set_it_insn_type (IT_INSN);
-      now_it.mask = (inst.instruction & 0xf) | 0x10;
-      now_it.cc = inst.operands[0].imm;
+      set_pred_insn_type (IT_INSN);
+      now_pred.mask = (inst.instruction & 0xf) | 0x10;
+      now_pred.cc = inst.operands[0].imm;
     }
 }
 
@@ -10803,7 +10887,7 @@ do_t_add_sub (void)
 	: inst.operands[0].reg);  /* Rd, foo -> Rd, Rd, foo */
 
   if (Rd == REG_PC)
-    set_it_insn_type_last ();
+    set_pred_insn_type_last ();
 
   if (unified_syntax)
     {
@@ -10814,9 +10898,9 @@ do_t_add_sub (void)
       flags = (inst.instruction == T_MNEM_adds
 	       || inst.instruction == T_MNEM_subs);
       if (flags)
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
       if (!inst.operands[2].isreg)
 	{
 	  int add;
@@ -11093,9 +11177,9 @@ do_t_arit3 (void)
 
 	  /* See if we can do this with a 16-bit instruction.  */
 	  if (THUMB_SETS_FLAGS (inst.instruction))
-	    narrow = !in_it_block ();
+	    narrow = !in_pred_block ();
 	  else
-	    narrow = in_it_block ();
+	    narrow = in_pred_block ();
 
 	  if (Rd > 7 || Rn > 7 || Rs > 7)
 	    narrow = FALSE;
@@ -11181,9 +11265,9 @@ do_t_arit3c (void)
 
 	  /* See if we can do this with a 16-bit instruction.  */
 	  if (THUMB_SETS_FLAGS (inst.instruction))
-	    narrow = !in_it_block ();
+	    narrow = !in_pred_block ();
 	  else
-	    narrow = in_it_block ();
+	    narrow = in_pred_block ();
 
 	  if (Rd > 7 || Rn > 7 || Rs > 7)
 	    narrow = FALSE;
@@ -11322,7 +11406,7 @@ do_t_bfx (void)
 static void
 do_t_blx (void)
 {
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
 
   if (inst.operands[0].isreg)
     {
@@ -11346,9 +11430,9 @@ do_t_branch (void)
   bfd_reloc_code_real_type reloc;
 
   cond = inst.cond;
-  set_it_insn_type (IF_INSIDE_IT_LAST_INSN);
+  set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
 
-  if (in_it_block ())
+  if (in_pred_block ())
     {
       /* Conditional branches inside IT blocks are encoded as unconditional
 	 branches.  */
@@ -11415,7 +11499,7 @@ do_t_bkpt_hlt1 (int range)
       inst.instruction |= inst.operands[0].imm;
     }
 
-  set_it_insn_type (NEUTRAL_IT_INSN);
+  set_pred_insn_type (NEUTRAL_IT_INSN);
 }
 
 static void
@@ -11433,7 +11517,7 @@ do_t_bkpt (void)
 static void
 do_t_branch23 (void)
 {
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
   encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
 
   /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
@@ -11461,7 +11545,7 @@ do_t_branch23 (void)
 static void
 do_t_bx (void)
 {
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
   inst.instruction |= inst.operands[0].reg << 3;
   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.	 The reloc
      should cause the alignment to be checked once it is known.	 This is
@@ -11473,7 +11557,7 @@ do_t_bxj (void)
 {
   int Rm;
 
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
   Rm = inst.operands[0].reg;
   reject_bad_reg (Rm);
   inst.instruction |= Rm << 16;
@@ -11499,20 +11583,20 @@ do_t_clz (void)
 static void
 do_t_csdb (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 }
 
 static void
 do_t_cps (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   inst.instruction |= inst.operands[0].imm;
 }
 
 static void
 do_t_cpsi (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   if (unified_syntax
       && (inst.operands[1].present || inst.size_req == 4)
       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
@@ -11559,7 +11643,7 @@ do_t_cpy (void)
 static void
 do_t_cbz (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   constraint (inst.operands[0].reg > 7, BAD_HIREG);
   inst.instruction |= inst.operands[0].reg;
   inst.relocs[0].pc_rel = 1;
@@ -11605,10 +11689,11 @@ do_t_it (void)
 {
   unsigned int cond = inst.operands[0].imm;
 
-  set_it_insn_type (IT_INSN);
-  now_it.mask = (inst.instruction & 0xf) | 0x10;
-  now_it.cc = cond;
-  now_it.warn_deprecated = FALSE;
+  set_pred_insn_type (IT_INSN);
+  now_pred.mask = (inst.instruction & 0xf) | 0x10;
+  now_pred.cc = cond;
+  now_pred.warn_deprecated = FALSE;
+  now_pred.type = SCALAR_PRED;
 
   /* If the condition is a negative condition, invert the mask.  */
   if ((cond & 0x1) == 0x0)
@@ -11618,22 +11703,22 @@ do_t_it (void)
       if ((mask & 0x7) == 0)
 	{
 	  /* No conversion needed.  */
-	  now_it.block_length = 1;
+	  now_pred.block_length = 1;
 	}
       else if ((mask & 0x3) == 0)
 	{
 	  mask ^= 0x8;
-	  now_it.block_length = 2;
+	  now_pred.block_length = 2;
 	}
       else if ((mask & 0x1) == 0)
 	{
 	  mask ^= 0xC;
-	  now_it.block_length = 3;
+	  now_pred.block_length = 3;
 	}
       else
 	{
 	  mask ^= 0xE;
-	  now_it.block_length = 4;
+	  now_pred.block_length = 4;
 	}
 
       inst.instruction &= 0xfff0;
@@ -11643,6 +11728,18 @@ do_t_it (void)
   inst.instruction |= cond << 4;
 }
 
+static void
+do_mve_vpt (void)
+{
+  /* We are dealing with a vector predicated block.  */
+  set_pred_insn_type (VPT_INSN);
+  now_pred.cc = 0;
+  now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
+		  | ((inst.instruction & 0xe000) >> 13);
+  now_pred.warn_deprecated = FALSE;
+  now_pred.type = VECTOR_PRED;
+}
+
 /* Helper function used for both push/pop and ldm/stm.  */
 static void
 encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
@@ -11669,7 +11766,7 @@ encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
 	  if (mask & (1 << 14))
 	    inst.error = _("LR and PC should not both be in register list");
 	  else
-	    set_it_insn_type_last ();
+	    set_pred_insn_type_last ();
 	}
     }
   else if (store)
@@ -11883,7 +11980,7 @@ do_t_ldst (void)
   if (inst.operands[0].isreg
       && !inst.operands[0].preind
       && inst.operands[0].reg == REG_PC)
-    set_it_insn_type_last ();
+    set_pred_insn_type_last ();
 
   opcode = inst.instruction;
   if (unified_syntax)
@@ -12142,7 +12239,7 @@ do_t_mov_cmp (void)
   Rm = inst.operands[1].reg;
 
   if (Rn == REG_PC)
-    set_it_insn_type_last ();
+    set_pred_insn_type_last ();
 
   if (unified_syntax)
     {
@@ -12154,7 +12251,7 @@ do_t_mov_cmp (void)
 
       low_regs = (Rn <= 7 && Rm <= 7);
       opcode = inst.instruction;
-      if (in_it_block ())
+      if (in_pred_block ())
 	narrow = opcode != T_MNEM_movs;
       else
 	narrow = opcode != T_MNEM_movs || low_regs;
@@ -12225,7 +12322,7 @@ do_t_mov_cmp (void)
       if (!inst.operands[1].isreg)
 	{
 	  /* Immediate operand.  */
-	  if (!in_it_block () && opcode == T_MNEM_mov)
+	  if (!in_pred_block () && opcode == T_MNEM_mov)
 	    narrow = 0;
 	  if (low_regs && narrow)
 	    {
@@ -12261,7 +12358,7 @@ do_t_mov_cmp (void)
 	  /* Register shifts are encoded as separate shift instructions.  */
 	  bfd_boolean flags = (inst.instruction == T_MNEM_movs);
 
-	  if (in_it_block ())
+	  if (in_pred_block ())
 	    narrow = !flags;
 	  else
 	    narrow = flags;
@@ -12317,7 +12414,7 @@ do_t_mov_cmp (void)
 	      && (inst.instruction == T_MNEM_mov
 		  || inst.instruction == T_MNEM_movs))
 	    {
-	      if (in_it_block ())
+	      if (in_pred_block ())
 		narrow = (inst.instruction == T_MNEM_mov);
 	      else
 		narrow = (inst.instruction == T_MNEM_movs);
@@ -12496,9 +12593,9 @@ do_t_mvn_tst (void)
 	       || inst.instruction == T_MNEM_tst)
 	narrow = TRUE;
       else if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
 
       if (!inst.operands[1].isreg)
 	{
@@ -12663,9 +12760,9 @@ do_t_mul (void)
 	  || Rm > 7)
 	narrow = FALSE;
       else if (inst.instruction == T_MNEM_muls)
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
     }
   else
     {
@@ -12731,7 +12828,7 @@ do_t_mull (void)
 static void
 do_t_nop (void)
 {
-  set_it_insn_type (NEUTRAL_IT_INSN);
+  set_pred_insn_type (NEUTRAL_IT_INSN);
 
   if (unified_syntax)
     {
@@ -12769,9 +12866,9 @@ do_t_neg (void)
       bfd_boolean narrow;
 
       if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
       if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
 	narrow = FALSE;
       if (inst.size_req == 4)
@@ -13033,9 +13130,9 @@ do_t_rsb (void)
       bfd_boolean narrow;
 
       if ((inst.instruction & 0x00100000) != 0)
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
 
       if (Rd > 7 || Rs > 7)
 	narrow = FALSE;
@@ -13073,7 +13170,7 @@ do_t_setend (void)
       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
       as_tsktsk (_("setend use is deprecated for ARMv8"));
 
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   if (inst.operands[0].imm)
     inst.instruction |= 0x8;
 }
@@ -13103,9 +13200,9 @@ do_t_shift (void)
 	}
 
       if (THUMB_SETS_FLAGS (inst.instruction))
-	narrow = !in_it_block ();
+	narrow = !in_pred_block ();
       else
-	narrow = in_it_block ();
+	narrow = in_pred_block ();
       if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
 	narrow = FALSE;
       if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
@@ -13275,7 +13372,7 @@ do_t_smc (void)
   inst.instruction |= (value & 0x0ff0);
   inst.instruction |= (value & 0x000f) << 16;
   /* PR gas/15623: SMC instructions must be last in an IT block.  */
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
 }
 
 static void
@@ -13450,7 +13547,7 @@ do_t_tb (void)
   int half;
 
   half = (inst.instruction & 0x10) != 0;
-  set_it_insn_type_last ();
+  set_pred_insn_type_last ();
   constraint (inst.operands[0].immisreg,
 	      _("instruction requires register index"));
 
@@ -13486,7 +13583,7 @@ do_t_udf (void)
       inst.instruction |= inst.operands[0].imm;
     }
 
-  set_it_insn_type (NEUTRAL_IT_INSN);
+  set_pred_insn_type (NEUTRAL_IT_INSN);
 }
 
 
@@ -13674,7 +13771,7 @@ do_t_loloop (void)
 {
   unsigned long insn = inst.instruction;
 
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   inst.instruction = THUMB_OP32 (inst.instruction);
 
   switch (insn)
@@ -13716,13 +13813,16 @@ struct neon_tab_entry
 /* Map overloaded Neon opcodes to their respective encodings.  */
 #define NEON_ENC_TAB					\
   X(vabd,	0x0000700, 0x1200d00, N_INV),		\
+  X(vabdl,	0x0800700, N_INV,     N_INV),		\
   X(vmax,	0x0000600, 0x0000f00, N_INV),		\
   X(vmin,	0x0000610, 0x0200f00, N_INV),		\
   X(vpadd,	0x0000b10, 0x1000d00, N_INV),		\
   X(vpmax,	0x0000a00, 0x1000f00, N_INV),		\
   X(vpmin,	0x0000a10, 0x1200f00, N_INV),		\
   X(vadd,	0x0000800, 0x0000d00, N_INV),		\
+  X(vaddl,	0x0800000, N_INV,     N_INV),		\
   X(vsub,	0x1000800, 0x0200d00, N_INV),		\
+  X(vsubl,	0x0800200, N_INV,     N_INV),		\
   X(vceq,	0x1000810, 0x0000e00, 0x1b10100),	\
   X(vcge,	0x0000310, 0x1000e00, 0x1b10080),	\
   X(vcgt,	0x0000300, 0x1200e00, 0x1b10000),	\
@@ -13865,6 +13965,7 @@ NEON_ENC_TAB
   X(3, (Q, Q, I), QUAD),		\
   X(3, (D, D, S), DOUBLE),		\
   X(3, (Q, Q, S), QUAD),		\
+  X(3, (Q, Q, R), QUAD),		\
   X(2, (D, D), DOUBLE),			\
   X(2, (Q, Q), QUAD),			\
   X(2, (D, S), DOUBLE),			\
@@ -14054,6 +14155,9 @@ enum neon_type_mask
 #define N_I_ALL    (N_I8 | N_I16 | N_I32 | N_I64)
 #define N_IF_32    (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
 #define N_F_ALL    (N_F16 | N_F32 | N_F64)
+#define N_I_MVE	   (N_I8 | N_I16 | N_I32)
+#define N_F_MVE	   (N_F16 | N_F32)
+#define N_SU_MVE   (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
 
 /* Pass this as the first type argument to neon_check_type to ignore types
    altogether.  */
@@ -14582,7 +14686,7 @@ neon_check_type (unsigned els, enum neon_shape ns, ...)
 
 		  if ((given_type & types_allowed) == 0)
 		    {
-		      first_error (_("bad type in Neon instruction"));
+		      first_error (_("bad type in SIMD instruction"));
 		      return badtype;
 		    }
 		}
@@ -15025,6 +15129,45 @@ neon_logbits (unsigned x)
 #define LOW4(R) ((R) & 0xf)
 #define HI1(R) (((R) >> 4) & 1)
 
+static void
+mve_encode_qqr (int size, int fp)
+{
+  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);
+
+  if (fp)
+    {
+      /* vadd.  */
+      if (((unsigned)inst.instruction) == 0xd00)
+	inst.instruction = 0xee300f40;
+      /* vsub.  */
+      else if (((unsigned)inst.instruction) == 0x200d00)
+	inst.instruction = 0xee301f40;
+
+      /* Setting size which is 1 for F16 and 0 for F32.  */
+      inst.instruction |= (size == 16) << 28;
+    }
+  else
+    {
+      /* vadd.  */
+      if (((unsigned)inst.instruction) == 0x800)
+	inst.instruction = 0xee010f40;
+      /* vsub.  */
+      else if (((unsigned)inst.instruction) == 0x1000800)
+	inst.instruction = 0xee011f40;
+      /* Setting bits for size.  */
+      inst.instruction |= neon_logbits (size) << 20;
+    }
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= inst.operands[2].reg;
+  inst.is_neon = 1;
+}
+
 /* Encode insns with bit pattern:
 
   |28/24|23|22 |21 20|19 16|15 12|11    8|7|6|5|4|3  0|
@@ -15346,26 +15489,27 @@ static void
 neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
 		  unsigned destbits)
 {
-  enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+  enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
   struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
 					    types | N_KEY);
   if (et.type == NT_float)
     {
       NEON_ENCODE (FLOAT, inst);
-      neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
+      if (rs == NS_QQR)
+	mve_encode_qqr (et.size, 1);
+      else
+	neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
     }
   else
     {
       NEON_ENCODE (INTEGER, inst);
-      neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
+      if (rs == NS_QQR)
+	mve_encode_qqr (et.size, 0);
+      else
+	neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
     }
 }
 
-static void
-do_neon_dyadic_if_su (void)
-{
-  neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
-}
 
 static void
 do_neon_dyadic_if_su_d (void)
@@ -15424,32 +15568,93 @@ vfp_or_neon_is_neon (unsigned check)
 	inst.instruction |= inst.uncond_value << 28;
     }
 
-  if ((check & NEON_CHECK_ARCH)
-      && !mark_feature_used (&fpu_neon_ext_v1))
+
+    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)
     {
-      first_error (_(BAD_FPU));
-      return FAIL;
+      if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  inst.error = BAD_FPU;
+	  return 1;
+	}
+      inst.pred_insn_type = INSIDE_VPT_INSN;
     }
-
-  if ((check & NEON_CHECK_ARCH8)
-      && !mark_feature_used (&fpu_neon_ext_armv8))
+  else if (inst.cond < COND_ALWAYS)
     {
-      first_error (_(BAD_FPU));
-      return FAIL;
+      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;
 
-  return SUCCESS;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+    }
+  return 0;
 }
 
 static void
-do_neon_addsub_if_i (void)
+do_neon_dyadic_if_su (void)
 {
-  if (try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
+  enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
+  struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
+					    N_SUF_32 | N_KEY);
+
+  if (check_simd_pred_availability (et.type == NT_float,
+				    NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
-  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+  neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
+}
+
+static void
+do_neon_addsub_if_i (void)
+{
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
+      && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
     return;
 
+  enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
+  struct neon_type_el et = neon_check_type (3, rs, N_EQK,
+					    N_EQK, N_IF_32 | N_I64 | N_KEY);
+
+  constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
+  /* If we are parsing Q registers and the element types match MVE, which NEON
+     also supports, then we must check whether this is an instruction that can
+     be used by both MVE/NEON.  This distinction can be made based on whether
+     they are predicated or not.  */
+  if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
+    {
+      if (check_simd_pred_availability (et.type == NT_float,
+					NEON_CHECK_ARCH | NEON_CHECK_CC))
+	return;
+    }
+  else
+    {
+      /* If they are either in a D register or are using an unsupported.  */
+      if (rs != NS_QQR
+	  && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+	return;
+    }
+
   /* The "untyped" case can't happen. Do this to stop the "U" bit being
      affected if we specify unsigned args.  */
   neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
@@ -16131,7 +16336,7 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
     constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
 		_(BAD_FP16));
 
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   switch (flavour)
     {
@@ -16286,7 +16491,7 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
       if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
 	{
 	  NEON_ENCODE (FLOAT, inst);
-	  set_it_insn_type (OUTSIDE_IT_INSN);
+	  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
 	  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
 	    return;
@@ -16587,10 +16792,49 @@ neon_mixed_length (struct neon_type_el et, unsigned size)
 static void
 do_neon_dyadic_long (void)
 {
-  /* FIXME: Type checking for lengthening op.  */
-  struct neon_type_el et = neon_check_type (3, NS_QDD,
-    N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
-  neon_mixed_length (et, et.size);
+  enum neon_shape rs = neon_select_shape (NS_QDD, NS_QQQ, NS_QQR, NS_NULL);
+  if (rs == NS_QDD)
+    {
+      if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
+	return;
+
+      NEON_ENCODE (INTEGER, inst);
+      /* FIXME: Type checking for lengthening op.  */
+      struct neon_type_el et = neon_check_type (3, NS_QDD,
+	N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
+      neon_mixed_length (et, et.size);
+    }
+  else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+	   && (inst.cond == 0xf || inst.cond == 0x10))
+    {
+      /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
+	 in an IT block with le/lt conditions.  */
+
+      if (inst.cond == 0xf)
+	inst.cond = 0xb;
+      else if (inst.cond == 0x10)
+	inst.cond = 0xd;
+
+      inst.pred_insn_type = INSIDE_IT_INSN;
+
+      if (inst.instruction == N_MNEM_vaddl)
+	{
+	  inst.instruction = N_MNEM_vadd;
+	  do_neon_addsub_if_i ();
+	}
+      else if (inst.instruction == N_MNEM_vsubl)
+	{
+	  inst.instruction = N_MNEM_vsub;
+	  do_neon_addsub_if_i ();
+	}
+      else if (inst.instruction == N_MNEM_vabdl)
+	{
+	  inst.instruction = N_MNEM_vabd;
+	  do_neon_dyadic_if_su ();
+	}
+    }
+  else
+    first_error (BAD_FPU);
 }
 
 static void
@@ -17863,7 +18107,7 @@ do_vfp_nsyn_fpv8 (enum neon_shape rs)
 static void
 do_vsel (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
     first_error (_("invalid instruction shape"));
@@ -17872,7 +18116,7 @@ do_vsel (void)
 static void
 do_vmaxnm (void)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
     return;
@@ -17905,7 +18149,7 @@ do_vrint_1 (enum neon_cvt_mode mode)
       /* VFP encodings.  */
       if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
 	  || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
-	set_it_insn_type (OUTSIDE_IT_INSN);
+	set_pred_insn_type (OUTSIDE_PRED_INSN);
 
       NEON_ENCODE (FPV8, inst);
       if (rs == NS_FF || rs == NS_HH)
@@ -17941,7 +18185,7 @@ do_vrint_1 (enum neon_cvt_mode mode)
       if (et.type == NT_invtype)
 	return;
 
-      set_it_insn_type (OUTSIDE_IT_INSN);
+      set_pred_insn_type (OUTSIDE_PRED_INSN);
       NEON_ENCODE (FLOAT, inst);
 
       if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
@@ -18170,7 +18414,7 @@ do_neon_dotproduct_u (void)
 static void
 do_crypto_2op_1 (unsigned elttype, int op)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
       == NT_invtype)
@@ -18195,7 +18439,7 @@ do_crypto_2op_1 (unsigned elttype, int op)
 static void
 do_crypto_3op_1 (int u, int op)
 {
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
 		       N_32 | N_UNT | N_KEY).type == NT_invtype)
@@ -18298,7 +18542,7 @@ do_crc32_1 (unsigned int poly, unsigned int sz)
   unsigned int Rn = inst.operands[1].reg;
   unsigned int Rm = inst.operands[2].reg;
 
-  set_it_insn_type (OUTSIDE_IT_INSN);
+  set_pred_insn_type (OUTSIDE_PRED_INSN);
   inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
   inst.instruction |= LOW4 (Rn) << 16;
   inst.instruction |= LOW4 (Rm);
@@ -18540,9 +18784,10 @@ enum opcode_tag
   OT_unconditionalF,	/* Instruction cannot be conditionalized
 			   and carries 0xF in its ARM condition field.  */
   OT_csuffix,		/* Instruction takes a conditional suffix.  */
-  OT_csuffixF,		/* Some forms of the instruction take a conditional
-			   suffix, others place 0xF where the condition field
-			   would be.  */
+  OT_csuffixF,		/* Some forms of the instruction take a scalar
+			   conditional suffix, others place 0xF where the
+			   condition field would be, others take a vector
+			   conditional suffix.  */
   OT_cinfix3,		/* Instruction takes a conditional infix,
 			   beginning at character index 3.  (In
 			   unified mode, it becomes a suffix.)  */
@@ -18688,17 +18933,35 @@ opcode_lookup (char **str)
       inst.cond = cond->value;
       return opcode;
     }
+ if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+   {
+    /* Cannot have a conditional suffix on a mnemonic of less than a character.
+     */
+    if (end - base < 2)
+      return NULL;
+     affix = end - 1;
+     cond = (const struct asm_cond *) hash_find_n (arm_vcond_hsh, affix, 1);
+     opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
+						      affix - base);
+     /* If this opcode can not be vector predicated then don't accept it with a
+	vector predication code.  */
+     if (opcode && !opcode->mayBeVecPred)
+       opcode = NULL;
+   }
+  if (!opcode || !cond)
+    {
+      /* Cannot have a conditional suffix on a mnemonic of less than two
+	 characters.  */
+      if (end - base < 3)
+	return NULL;
 
-  /* Cannot have a conditional suffix on a mnemonic of less than two
-     characters.  */
-  if (end - base < 3)
-    return NULL;
+      /* Look for suffixed mnemonic.  */
+      affix = end - 2;
+      cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
+      opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
+							affix - base);
+    }
 
-  /* Look for suffixed mnemonic.  */
-  affix = end - 2;
-  cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
-  opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
-						    affix - base);
   if (opcode && cond)
     {
       /* step CE */
@@ -18777,7 +19040,7 @@ opcode_lookup (char **str)
 
 /* This function generates an initial IT instruction, leaving its block
    virtually open for the new instructions. Eventually,
-   the mask will be updated by now_it_add_mask () each time
+   the mask will be updated by now_pred_add_mask () each time
    a new instruction needs to be included in the IT block.
    Finally, the block is closed with close_automatic_it_block ().
    The block closure can be requested either from md_assemble (),
@@ -18786,14 +19049,14 @@ opcode_lookup (char **str)
 static void
 new_automatic_it_block (int cond)
 {
-  now_it.state = AUTOMATIC_IT_BLOCK;
-  now_it.mask = 0x18;
-  now_it.cc = cond;
-  now_it.block_length = 1;
+  now_pred.state = AUTOMATIC_PRED_BLOCK;
+  now_pred.mask = 0x18;
+  now_pred.cc = cond;
+  now_pred.block_length = 1;
   mapping_state (MAP_THUMB);
-  now_it.insn = output_it_inst (cond, now_it.mask, NULL);
-  now_it.warn_deprecated = FALSE;
-  now_it.insn_cond = TRUE;
+  now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
+  now_pred.warn_deprecated = FALSE;
+  now_pred.insn_cond = TRUE;
 }
 
 /* Close an automatic IT block.
@@ -18802,29 +19065,29 @@ new_automatic_it_block (int cond)
 static void
 close_automatic_it_block (void)
 {
-  now_it.mask = 0x10;
-  now_it.block_length = 0;
+  now_pred.mask = 0x10;
+  now_pred.block_length = 0;
 }
 
 /* Update the mask of the current automatically-generated IT
    instruction. See comments in new_automatic_it_block ().  */
 
 static void
-now_it_add_mask (int cond)
+now_pred_add_mask (int cond)
 {
 #define CLEAR_BIT(value, nbit)  ((value) & ~(1 << (nbit)))
 #define SET_BIT_VALUE(value, bitvalue, nbit)  (CLEAR_BIT (value, nbit) \
 					      | ((bitvalue) << (nbit)))
   const int resulting_bit = (cond & 1);
 
-  now_it.mask &= 0xf;
-  now_it.mask = SET_BIT_VALUE (now_it.mask,
+  now_pred.mask &= 0xf;
+  now_pred.mask = SET_BIT_VALUE (now_pred.mask,
 				   resulting_bit,
-				  (5 - now_it.block_length));
-  now_it.mask = SET_BIT_VALUE (now_it.mask,
+				  (5 - now_pred.block_length));
+  now_pred.mask = SET_BIT_VALUE (now_pred.mask,
 				   1,
-				   ((5 - now_it.block_length) - 1) );
-  output_it_inst (now_it.cc, now_it.mask, now_it.insn);
+				   ((5 - now_pred.block_length) - 1));
+  output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
 
 #undef CLEAR_BIT
 #undef SET_BIT_VALUE
@@ -18832,9 +19095,9 @@ now_it_add_mask (int cond)
 
 /* The IT blocks handling machinery is accessed through the these functions:
      it_fsm_pre_encode ()               from md_assemble ()
-     set_it_insn_type ()                optional, from the tencode functions
-     set_it_insn_type_last ()           ditto
-     in_it_block ()                     ditto
+     set_pred_insn_type ()		optional, from the tencode functions
+     set_pred_insn_type_last ()		ditto
+     in_pred_block ()			ditto
      it_fsm_post_encode ()              from md_assemble ()
      force_automatic_it_block_close ()  from label handling functions
 
@@ -18844,37 +19107,38 @@ now_it_add_mask (int cond)
 	on the inst.condition.
      2) During the tencode function, two things may happen:
 	a) The tencode function overrides the IT insn type by
-	   calling either set_it_insn_type (type) or set_it_insn_type_last ().
+	   calling either set_pred_insn_type (type) or
+	   set_pred_insn_type_last ().
 	b) The tencode function queries the IT block state by
-	   calling in_it_block () (i.e. to determine narrow/not narrow mode).
+	   calling in_pred_block () (i.e. to determine narrow/not narrow mode).
 
-	Both set_it_insn_type and in_it_block run the internal FSM state
-	handling function (handle_it_state), because: a) setting the IT insn
+	Both set_pred_insn_type and in_pred_block run the internal FSM state
+	handling function (handle_pred_state), because: a) setting the IT insn
 	type may incur in an invalid state (exiting the function),
 	and b) querying the state requires the FSM to be updated.
 	Specifically we want to avoid creating an IT block for conditional
 	branches, so it_fsm_pre_encode is actually a guess and we can't
 	determine whether an IT block is required until the tencode () routine
 	has decided what type of instruction this actually it.
-	Because of this, if set_it_insn_type and in_it_block have to be used,
-	set_it_insn_type has to be called first.
+	Because of this, if set_pred_insn_type and in_pred_block have to be
+	used, set_pred_insn_type has to be called first.
 
-	set_it_insn_type_last () is a wrapper of set_it_insn_type (type), that
-	determines the insn IT type depending on the inst.cond code.
+	set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
+	that determines the insn IT type depending on the inst.cond code.
 	When a tencode () routine encodes an instruction that can be
 	either outside an IT block, or, in the case of being inside, has to be
-	the last one, set_it_insn_type_last () will determine the proper
+	the last one, set_pred_insn_type_last () will determine the proper
 	IT instruction type based on the inst.cond code. Otherwise,
-	set_it_insn_type can be called for overriding that logic or
+	set_pred_insn_type can be called for overriding that logic or
 	for covering other cases.
 
-	Calling handle_it_state () may not transition the IT block state to
-	OUTSIDE_IT_BLOCK immediately, since the (current) state could be
+	Calling handle_pred_state () may not transition the IT block state to
+	OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
 	still queried. Instead, if the FSM determines that the state should
-	be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
+	be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
 	after the tencode () function: that's what it_fsm_post_encode () does.
 
-	Since in_it_block () calls the state handling function to get an
+	Since in_pred_block () calls the state handling function to get an
 	updated state, an error may occur (due to invalid insns combination).
 	In that case, inst.error is set.
 	Therefore, inst.error has to be checked after the execution of
@@ -18882,74 +19146,150 @@ now_it_add_mask (int cond)
 
      3) Back in md_assemble(), it_fsm_post_encode () is called to commit
 	any pending state change (if any) that didn't take place in
-	handle_it_state () as explained above.  */
+	handle_pred_state () as explained above.  */
 
 static void
 it_fsm_pre_encode (void)
 {
   if (inst.cond != COND_ALWAYS)
-    inst.it_insn_type = INSIDE_IT_INSN;
+    inst.pred_insn_type =  INSIDE_IT_INSN;
   else
-    inst.it_insn_type = OUTSIDE_IT_INSN;
+    inst.pred_insn_type = OUTSIDE_PRED_INSN;
 
-  now_it.state_handled = 0;
+  now_pred.state_handled = 0;
 }
 
 /* IT state FSM handling function.  */
+/* MVE instructions and non-MVE instructions are handled differently because of
+   the introduction of VPT blocks.
+   Specifications say that any non-MVE instruction inside a VPT block is
+   UNPREDICTABLE, with the exception of the BKPT instruction.  Whereas most MVE
+   instructions are deemed to be UNPREDICTABLE if inside an IT block.  For the
+   few exceptions this will be handled at their respective handler functions.
+   The error messages provided depending on the different combinations possible
+   are described in the cases below:
+   For 'most' MVE instructions:
+   1) In an IT block, with an IT code: syntax error
+   2) In an IT block, with a VPT code: error: must be in a VPT block
+   3) In an IT block, with no code: warning: UNPREDICTABLE
+   4) In a VPT block, with an IT code: syntax error
+   5) In a VPT block, with a VPT code: OK!
+   6) In a VPT block, with no code: error: missing code
+   7) Outside a pred block, with an IT code: error: syntax error
+   8) Outside a pred block, with a VPT code: error: should be in a VPT block
+   9) Outside a pred block, with no code: OK!
+   For non-MVE instructions:
+   10) In an IT block, with an IT code: OK!
+   11) In an IT block, with a VPT code: syntax error
+   12) In an IT block, with no code: error: missing code
+   13) In a VPT block, with an IT code: error: should be in an IT block
+   14) In a VPT block, with a VPT code: syntax error
+   15) In a VPT block, with no code: UNPREDICTABLE
+   16) Outside a pred block, with an IT code: error: should be in an IT block
+   17) Outside a pred block, with a VPT code: syntax error
+   18) Outside a pred block, with no code: OK!
+ */
+
 
 static int
-handle_it_state (void)
+handle_pred_state (void)
 {
-  now_it.state_handled = 1;
-  now_it.insn_cond = FALSE;
+  now_pred.state_handled = 1;
+  now_pred.insn_cond = FALSE;
 
-  switch (now_it.state)
+  switch (now_pred.state)
     {
-    case OUTSIDE_IT_BLOCK:
-      switch (inst.it_insn_type)
+    case OUTSIDE_PRED_BLOCK:
+      switch (inst.pred_insn_type)
 	{
-	case OUTSIDE_IT_INSN:
+	case MVE_OUTSIDE_PRED_INSN:
+	  if (inst.cond < COND_ALWAYS)
+	    {
+	      /* Case 7: Outside a pred block, with an IT code: error: syntax
+		 error.  */
+	      inst.error = BAD_SYNTAX;
+	      return FAIL;
+	    }
+	  /* Case 9:  Outside a pred block, with no code: OK!  */
+	  break;
+	case OUTSIDE_PRED_INSN:
+	  if (inst.cond > COND_ALWAYS)
+	    {
+	      /* Case 17:  Outside a pred block, with a VPT code: syntax error.
+	       */
+	      inst.error = BAD_SYNTAX;
+	      return FAIL;
+	    }
+	  /* Case 18: Outside a pred block, with no code: OK!  */
 	  break;
 
+	case INSIDE_VPT_INSN:
+	  /* Case 8: Outside a pred block, with a VPT code: error: should be in
+	     a VPT block.  */
+	  inst.error = BAD_OUT_VPT;
+	  return FAIL;
+
 	case INSIDE_IT_INSN:
 	case INSIDE_IT_LAST_INSN:
-	  if (thumb_mode == 0)
-	    {
-	      if (unified_syntax
-		  && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
-		as_tsktsk (_("Warning: conditional outside an IT block"\
-			     " for Thumb."));
-	    }
-	  else
+	  if (inst.cond < COND_ALWAYS)
 	    {
-	      if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
-		  && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
+	      /* Case 16: Outside a pred block, with an IT code: error: should
+		 be in an IT block.  */
+	      if (thumb_mode == 0)
 		{
-		  /* Automatically generate the IT instruction.  */
-		  new_automatic_it_block (inst.cond);
-		  if (inst.it_insn_type == INSIDE_IT_LAST_INSN)
-		    close_automatic_it_block ();
+		  if (unified_syntax
+		      && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
+		    as_tsktsk (_("Warning: conditional outside an IT block"\
+				 " for Thumb."));
 		}
 	      else
 		{
-		  inst.error = BAD_OUT_IT;
-		  return FAIL;
+		  if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
+		      && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
+		    {
+		      /* Automatically generate the IT instruction.  */
+		      new_automatic_it_block (inst.cond);
+		      if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
+			close_automatic_it_block ();
+		    }
+		  else
+		    {
+		      inst.error = BAD_OUT_IT;
+		      return FAIL;
+		    }
 		}
+	      break;
 	    }
-	  break;
-
+	  else if (inst.cond > COND_ALWAYS)
+	    {
+	      /* Case 17: Outside a pred block, with a VPT code: syntax error.
+	       */
+	      inst.error = BAD_SYNTAX;
+	      return FAIL;
+	    }
+	  else
+	    gas_assert (0);
 	case IF_INSIDE_IT_LAST_INSN:
 	case NEUTRAL_IT_INSN:
 	  break;
 
+	case VPT_INSN:
+	  if (inst.cond != COND_ALWAYS)
+	    first_error (BAD_SYNTAX);
+	  now_pred.state = MANUAL_PRED_BLOCK;
+	  now_pred.block_length = 0;
+	  now_pred.type = VECTOR_PRED;
+	  now_pred.cc = 0;
+	  break;
 	case IT_INSN:
-	  now_it.state = MANUAL_IT_BLOCK;
-	  now_it.block_length = 0;
+	  now_pred.state = MANUAL_PRED_BLOCK;
+	  now_pred.block_length = 0;
+	  now_pred.type = SCALAR_PRED;
 	  break;
 	}
       break;
 
-    case AUTOMATIC_IT_BLOCK:
+    case AUTOMATIC_PRED_BLOCK:
       /* Three things may happen now:
 	 a) We should increment current it block size;
 	 b) We should close current it block (closing insn or 4 insns);
@@ -18957,82 +19297,211 @@ handle_it_state (void)
 	 to incompatible conditions or
 	 4 insns-length block reached).  */
 
-      switch (inst.it_insn_type)
+      switch (inst.pred_insn_type)
 	{
-	case OUTSIDE_IT_INSN:
+	case INSIDE_VPT_INSN:
+	case VPT_INSN:
+	case MVE_OUTSIDE_PRED_INSN:
+	  gas_assert (0);
+	case OUTSIDE_PRED_INSN:
 	  /* The closure of the block shall happen immediately,
-	     so any in_it_block () call reports the block as closed.  */
+	     so any in_pred_block () call reports the block as closed.  */
 	  force_automatic_it_block_close ();
 	  break;
 
 	case INSIDE_IT_INSN:
 	case INSIDE_IT_LAST_INSN:
 	case IF_INSIDE_IT_LAST_INSN:
-	  now_it.block_length++;
+	  now_pred.block_length++;
 
-	  if (now_it.block_length > 4
-	      || !now_it_compatible (inst.cond))
+	  if (now_pred.block_length > 4
+	      || !now_pred_compatible (inst.cond))
 	    {
 	      force_automatic_it_block_close ();
-	      if (inst.it_insn_type != IF_INSIDE_IT_LAST_INSN)
+	      if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
 		new_automatic_it_block (inst.cond);
 	    }
 	  else
 	    {
-	      now_it.insn_cond = TRUE;
-	      now_it_add_mask (inst.cond);
+	      now_pred.insn_cond = TRUE;
+	      now_pred_add_mask (inst.cond);
 	    }
 
-	  if (now_it.state == AUTOMATIC_IT_BLOCK
-	      && (inst.it_insn_type == INSIDE_IT_LAST_INSN
-		  || inst.it_insn_type == IF_INSIDE_IT_LAST_INSN))
+	  if (now_pred.state == AUTOMATIC_PRED_BLOCK
+	      && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
+		  || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
 	    close_automatic_it_block ();
 	  break;
 
 	case NEUTRAL_IT_INSN:
-	  now_it.block_length++;
-	  now_it.insn_cond = TRUE;
+	  now_pred.block_length++;
+	  now_pred.insn_cond = TRUE;
 
-	  if (now_it.block_length > 4)
+	  if (now_pred.block_length > 4)
 	    force_automatic_it_block_close ();
 	  else
-	    now_it_add_mask (now_it.cc & 1);
+	    now_pred_add_mask (now_pred.cc & 1);
 	  break;
 
 	case IT_INSN:
 	  close_automatic_it_block ();
-	  now_it.state = MANUAL_IT_BLOCK;
+	  now_pred.state = MANUAL_PRED_BLOCK;
 	  break;
 	}
       break;
 
-    case MANUAL_IT_BLOCK:
+    case MANUAL_PRED_BLOCK:
       {
-	/* Check conditional suffixes.  */
-	const int cond = now_it.cc ^ ((now_it.mask >> 4) & 1) ^ 1;
-	int is_last;
-	now_it.mask <<= 1;
-	now_it.mask &= 0x1f;
-	is_last = (now_it.mask == 0x10);
-	now_it.insn_cond = TRUE;
-
-	switch (inst.it_insn_type)
+	int cond, is_last;
+	if (now_pred.type == SCALAR_PRED)
 	  {
-	  case OUTSIDE_IT_INSN:
-	    inst.error = BAD_NOT_IT;
-	    return FAIL;
+	    /* Check conditional suffixes.  */
+	    cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
+	    now_pred.mask <<= 1;
+	    now_pred.mask &= 0x1f;
+	    is_last = (now_pred.mask == 0x10);
+	  }
+	else
+	  {
+	    now_pred.cc ^= (now_pred.mask >> 4);
+	    cond = now_pred.cc + 0xf;
+	    now_pred.mask <<= 1;
+	    now_pred.mask &= 0x1f;
+	    is_last = now_pred.mask == 0x10;
+	  }
+	now_pred.insn_cond = TRUE;
 
+	switch (inst.pred_insn_type)
+	  {
+	  case OUTSIDE_PRED_INSN:
+	    if (now_pred.type == SCALAR_PRED)
+	      {
+		if (inst.cond == COND_ALWAYS)
+		  {
+		    /* Case 12: In an IT block, with no code: error: missing
+		       code.  */
+		    inst.error = BAD_NOT_IT;
+		    return FAIL;
+		  }
+		else if (inst.cond > COND_ALWAYS)
+		  {
+		    /* Case 11: In an IT block, with a VPT code: syntax error.
+		     */
+		    inst.error = BAD_SYNTAX;
+		    return FAIL;
+		  }
+		else if (thumb_mode)
+		  {
+		    /* This is for some special cases where a non-MVE
+		       instruction is not allowed in an IT block, such as cbz,
+		       but are put into one with a condition code.
+		       You could argue this should be a syntax error, but we
+		       gave the 'not allowed in IT block' diagnostic in the
+		       past so we will keep doing so.  */
+		    inst.error = BAD_NOT_IT;
+		    return FAIL;
+		  }
+		break;
+	      }
+	    else
+	      {
+		/* Case 15: In a VPT block, with no code: UNPREDICTABLE.  */
+		as_tsktsk (MVE_NOT_VPT);
+		return SUCCESS;
+	      }
+	  case MVE_OUTSIDE_PRED_INSN:
+	    if (now_pred.type == SCALAR_PRED)
+	      {
+		if (inst.cond == COND_ALWAYS)
+		  {
+		    /* Case 3: In an IT block, with no code: warning:
+		       UNPREDICTABLE.  */
+		    as_tsktsk (MVE_NOT_IT);
+		    return SUCCESS;
+		  }
+		else if (inst.cond < COND_ALWAYS)
+		  {
+		    /* Case 1: In an IT block, with an IT code: syntax error.
+		     */
+		    inst.error = BAD_SYNTAX;
+		    return FAIL;
+		  }
+		else
+		  gas_assert (0);
+	      }
+	    else
+	      {
+		if (inst.cond < COND_ALWAYS)
+		  {
+		    /* Case 4: In a VPT block, with an IT code: syntax error.
+		     */
+		    inst.error = BAD_SYNTAX;
+		    return FAIL;
+		  }
+		else if (inst.cond == COND_ALWAYS)
+		  {
+		    /* Case 6: In a VPT block, with no code: error: missing
+		       code.  */
+		    inst.error = BAD_NOT_VPT;
+		    return FAIL;
+		  }
+		else
+		  {
+		    gas_assert (0);
+		  }
+	      }
 	  case INSIDE_IT_INSN:
-	    if (cond != inst.cond)
+	    if (inst.cond > COND_ALWAYS)
 	      {
-		inst.error = BAD_IT_COND;
+		/* Case 11: In an IT block, with a VPT code: syntax error.  */
+		/* Case 14: In a VPT block, with a VPT code: syntax error.  */
+		inst.error = BAD_SYNTAX;
+		return FAIL;
+	      }
+	    else if (now_pred.type == SCALAR_PRED)
+	      {
+		/* Case 10: In an IT block, with an IT code: OK!  */
+		if (cond != inst.cond)
+		  {
+		    inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
+		      BAD_VPT_COND;
+		    return FAIL;
+		  }
+	      }
+	    else
+	      {
+		/* Case 13: In a VPT block, with an IT code: error: should be
+		   in an IT block.  */
+		inst.error = BAD_OUT_IT;
 		return FAIL;
 	      }
 	    break;
 
+	  case INSIDE_VPT_INSN:
+	    if (now_pred.type == SCALAR_PRED)
+	      {
+		/* Case 2: In an IT block, with a VPT code: error: must be in a
+		   VPT block.  */
+		inst.error = BAD_OUT_VPT;
+		return FAIL;
+	      }
+	    /* Case 5:  In a VPT block, with a VPT code: OK!  */
+	    else if (cond != inst.cond)
+	      {
+		inst.error = BAD_VPT_COND;
+		return FAIL;
+	      }
+	    break;
 	  case INSIDE_IT_LAST_INSN:
 	  case IF_INSIDE_IT_LAST_INSN:
-	    if (cond != inst.cond)
+	    if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
+	      {
+		/* Case 4: In a VPT block, with an IT code: syntax error.  */
+		/* Case 11: In an IT block, with a VPT code: syntax error.  */
+		inst.error = BAD_SYNTAX;
+		return FAIL;
+	      }
+	    else if (cond != inst.cond)
 	      {
 		inst.error = BAD_IT_COND;
 		return FAIL;
@@ -19045,14 +19514,37 @@ handle_it_state (void)
 	    break;
 
 	  case NEUTRAL_IT_INSN:
-	    /* The BKPT instruction is unconditional even in an IT block.  */
+	    /* The BKPT instruction is unconditional even in a IT or VPT
+	       block.  */
 	    break;
 
 	  case IT_INSN:
-	    inst.error = BAD_IT_IT;
-	    return FAIL;
+	    if (now_pred.type == SCALAR_PRED)
+	      {
+		inst.error = BAD_IT_IT;
+		return FAIL;
+	      }
+	    /* fall through.  */
+	  case VPT_INSN:
+	    if (inst.cond == COND_ALWAYS)
+	      {
+		/* Executing a VPT/VPST instruction inside an IT block or a
+		   VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
+		 */
+		if (now_pred.type == SCALAR_PRED)
+		  as_tsktsk (MVE_NOT_IT);
+		else
+		  as_tsktsk (MVE_NOT_VPT);
+		return SUCCESS;
+	      }
+	    else
+	      {
+		/* VPT/VPST do not accept condition codes.  */
+		inst.error = BAD_SYNTAX;
+		return FAIL;
+	      }
 	  }
-      }
+	}
       break;
     }
 
@@ -19086,11 +19578,11 @@ it_fsm_post_encode (void)
 {
   int is_last;
 
-  if (!now_it.state_handled)
-    handle_it_state ();
+  if (!now_pred.state_handled)
+    handle_pred_state ();
 
-  if (now_it.insn_cond
-      && !now_it.warn_deprecated
+  if (now_pred.insn_cond
+      && !now_pred.warn_deprecated
       && warn_on_deprecated
       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
       && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
@@ -19099,7 +19591,7 @@ it_fsm_post_encode (void)
 	{
 	  as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
 		     "performance deprecated in ARMv8-A and ARMv8-R"));
-	  now_it.warn_deprecated = TRUE;
+	  now_pred.warn_deprecated = TRUE;
 	}
       else
 	{
@@ -19113,7 +19605,7 @@ it_fsm_post_encode (void)
 			       "instructions of the following class are "
 			       "performance deprecated in ARMv8-A and "
 			       "ARMv8-R: %s"), p->description);
-		  now_it.warn_deprecated = TRUE;
+		  now_pred.warn_deprecated = TRUE;
 		  break;
 		}
 
@@ -19121,41 +19613,41 @@ it_fsm_post_encode (void)
 	    }
 	}
 
-      if (now_it.block_length > 1)
+      if (now_pred.block_length > 1)
 	{
 	  as_tsktsk (_("IT blocks containing more than one conditional "
 		     "instruction are performance deprecated in ARMv8-A and "
 		     "ARMv8-R"));
-	  now_it.warn_deprecated = TRUE;
+	  now_pred.warn_deprecated = TRUE;
 	}
     }
 
-  is_last = (now_it.mask == 0x10);
-  if (is_last)
-    {
-      now_it.state = OUTSIDE_IT_BLOCK;
-      now_it.mask = 0;
-    }
+    is_last = (now_pred.mask == 0x10);
+    if (is_last)
+      {
+	now_pred.state = OUTSIDE_PRED_BLOCK;
+	now_pred.mask = 0;
+      }
 }
 
 static void
 force_automatic_it_block_close (void)
 {
-  if (now_it.state == AUTOMATIC_IT_BLOCK)
+  if (now_pred.state == AUTOMATIC_PRED_BLOCK)
     {
       close_automatic_it_block ();
-      now_it.state = OUTSIDE_IT_BLOCK;
-      now_it.mask = 0;
+      now_pred.state = OUTSIDE_PRED_BLOCK;
+      now_pred.mask = 0;
     }
 }
 
 static int
-in_it_block (void)
+in_pred_block (void)
 {
-  if (!now_it.state_handled)
-    handle_it_state ();
+  if (!now_pred.state_handled)
+    handle_pred_state ();
 
-  return now_it.state != OUTSIDE_IT_BLOCK;
+  return now_pred.state != OUTSIDE_PRED_BLOCK;
 }
 
 /* Whether OPCODE only has T32 encoding.  Since this function is only used by
@@ -19308,7 +19800,7 @@ md_assemble (char *str)
 
       if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
 	{
-	  /* Prepare the it_insn_type for those encodings that don't set
+	  /* Prepare the pred_insn_type for those encodings that don't set
 	     it.  */
 	  it_fsm_pre_encode ();
 
@@ -19411,21 +19903,30 @@ md_assemble (char *str)
 }
 
 static void
-check_it_blocks_finished (void)
+check_pred_blocks_finished (void)
 {
 #ifdef OBJ_ELF
   asection *sect;
 
   for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
-    if (seg_info (sect)->tc_segment_info_data.current_it.state
-	== MANUAL_IT_BLOCK)
+    if (seg_info (sect)->tc_segment_info_data.current_pred.state
+	== MANUAL_PRED_BLOCK)
       {
-	as_warn (_("section '%s' finished with an open IT block."),
-		 sect->name);
+	if (now_pred.type == SCALAR_PRED)
+	  as_warn (_("section '%s' finished with an open IT block."),
+		   sect->name);
+	else
+	  as_warn (_("section '%s' finished with an open VPT/VPST block."),
+		   sect->name);
       }
 #else
-  if (now_it.state == MANUAL_IT_BLOCK)
-    as_warn (_("file finished with an open IT block."));
+  if (now_pred.state == MANUAL_PRED_BLOCK)
+    {
+      if (now_pred.type == SCALAR_PRED)
+       as_warn (_("file finished with an open IT block."));
+      else
+	as_warn (_("file finished with an open VPT/VPST block."));
+    }
 #endif
 }
 
@@ -19827,7 +20328,7 @@ static struct reloc_entry reloc_names[] =
 };
 #endif
 
-/* Table of all conditional affixes.  0xF is not defined as a condition code.  */
+/* Table of all conditional affixes.  */
 static const struct asm_cond conds[] =
 {
   {"eq", 0x0},
@@ -19846,6 +20347,11 @@ static const struct asm_cond conds[] =
   {"le", 0xd},
   {"al", 0xe}
 };
+static const struct asm_cond vconds[] =
+{
+    {"t", 0xf},
+    {"e", 0x10}
+};
 
 #define UL_BARRIER(L,U,CODE,FEAT) \
   { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
@@ -19904,7 +20410,7 @@ static struct asm_barrier_opt barrier_opt_names[] =
 /* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix.  */
 #define TxCE(mnem, op, top, nops, ops, ae, te) \
   { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##ae, do_##te }
+    THUMB_VARIANT, do_##ae, do_##te, 0 }
 
 /* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
    a T_MNEM_xyz enumerator.  */
@@ -19917,10 +20423,10 @@ static struct asm_barrier_opt barrier_opt_names[] =
    infix after the third character.  */
 #define TxC3(mnem, op, top, nops, ops, ae, te) \
   { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##ae, do_##te }
+    THUMB_VARIANT, do_##ae, do_##te, 0 }
 #define TxC3w(mnem, op, top, nops, ops, ae, te) \
   { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##ae, do_##te }
+    THUMB_VARIANT, do_##ae, do_##te, 0 }
 #define TC3(mnem, aop, top, nops, ops, ae, te) \
       TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
 #define TC3w(mnem, aop, top, nops, ops, ae, te) \
@@ -19935,74 +20441,74 @@ static struct asm_barrier_opt barrier_opt_names[] =
    conditionally, so this is checked separately.  */
 #define TUE(mnem, op, top, nops, ops, ae, te)				\
   { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##ae, do_##te }
+    THUMB_VARIANT, do_##ae, do_##te, 0 }
 
 /* Same as TUE but the encoding function for ARM and Thumb modes is the same.
    Used by mnemonics that have very minimal differences in the encoding for
    ARM and Thumb variants and can be handled in a common function.  */
 #define TUEc(mnem, op, top, nops, ops, en) \
   { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##en, do_##en }
+    THUMB_VARIANT, do_##en, do_##en, 0 }
 
 /* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
    condition code field.  */
 #define TUF(mnem, op, top, nops, ops, ae, te)				\
   { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
-    THUMB_VARIANT, do_##ae, do_##te }
+    THUMB_VARIANT, do_##ae, do_##te, 0 }
 
 /* ARM-only variants of all the above.  */
 #define CE(mnem,  op, nops, ops, ae)	\
-  { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
+  { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 #define C3(mnem, op, nops, ops, ae)	\
-  { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
+  { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 /* Thumb-only variants of TCE and TUE.  */
 #define ToC(mnem, top, nops, ops, te) \
   { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
-    do_##te }
+    do_##te, 0 }
 
 #define ToU(mnem, top, nops, ops, te) \
   { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
-    NULL, do_##te }
+    NULL, do_##te, 0 }
 
 /* T_MNEM_xyz enumerator variants of ToC.  */
 #define toC(mnem, top, nops, ops, te) \
   { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
-    do_##te }
+    do_##te, 0 }
 
 /* T_MNEM_xyz enumerator variants of ToU.  */
 #define toU(mnem, top, nops, ops, te) \
   { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
-    NULL, do_##te }
+    NULL, do_##te, 0 }
 
 /* Legacy mnemonics that always have conditional infix after the third
    character.  */
 #define CL(mnem, op, nops, ops, ae)	\
   { mnem, OPS##nops ops, OT_cinfix3_legacy, \
-    0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
+    0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 /* Coprocessor instructions.  Isomorphic between Arm and Thumb-2.  */
 #define cCE(mnem,  op, nops, ops, ae)	\
-  { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
+  { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
 
 /* Legacy coprocessor instructions where conditional infix and conditional
    suffix are ambiguous.  For consistency this includes all FPA instructions,
    not just the potentially ambiguous ones.  */
 #define cCL(mnem, op, nops, ops, ae)	\
   { mnem, OPS##nops ops, OT_cinfix3_legacy, \
-    0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
+    0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
 
 /* Coprocessor, takes either a suffix or a position-3 infix
    (for an FPA corner case). */
 #define C3E(mnem, op, nops, ops, ae) \
   { mnem, OPS##nops ops, OT_csuf_or_in3, \
-    0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
+    0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
 
 #define xCM_(m1, m2, m3, op, nops, ops, ae)	\
   { m1 #m2 m3, OPS##nops ops, \
     sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
-    0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
+    0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 #define CM(m1, m2, op, nops, ops, ae)	\
   xCM_ (m1,   , m2, op, nops, ops, ae),	\
@@ -20026,47 +20532,83 @@ static struct asm_barrier_opt barrier_opt_names[] =
   xCM_ (m1, al, m2, op, nops, ops, ae)
 
 #define UE(mnem, op, nops, ops, ae)	\
-  { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
+  { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 #define UF(mnem, op, nops, ops, ae)	\
-  { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
+  { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
 
 /* Neon data-processing. ARM versions are unconditional with cond=0xf.
    The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
    use the same encoding function for each.  */
 #define NUF(mnem, op, nops, ops, enc)					\
   { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op,		\
-    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
 
 /* Neon data processing, version which indirects through neon_enc_tab for
    the various overloaded versions of opcodes.  */
 #define nUF(mnem, op, nops, ops, enc)					\
   { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op,	\
-    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
 
 /* Neon insn with conditional suffix for the ARM version, non-overloaded
    version.  */
-#define NCE_tag(mnem, op, nops, ops, enc, tag)				\
+#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p)				\
   { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT,		\
-    THUMB_VARIANT, do_##enc, do_##enc }
+    THUMB_VARIANT, do_##enc, do_##enc, mve_p }
 
 #define NCE(mnem, op, nops, ops, enc)					\
-   NCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
+   NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
 
 #define NCEF(mnem, op, nops, ops, enc)					\
-    NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
+    NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
 
 /* Neon insn with conditional suffix for the ARM version, overloaded types.  */
-#define nCE_tag(mnem, op, nops, ops, enc, tag)				\
+#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p)				\
   { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op,		\
-    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
 
 #define nCE(mnem, op, nops, ops, enc)					\
-   nCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
+   nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
 
 #define nCEF(mnem, op, nops, ops, enc)					\
-    nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
+    nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
+
+/*   */
+#define mCEF(mnem, op, nops, ops, enc)				\
+  { #mnem, OPS##nops ops, OT_csuffixF, 0, M_MNEM##op,		\
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
+
+
+/* nCEF but for MVE predicated instructions.  */
+#define mnCEF(mnem, op, nops, ops, enc)					\
+    nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
+
+/* nCE but for MVE predicated instructions.  */
+#define mnCE(mnem, op, nops, ops, enc)					\
+   nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
 
+/* NUF but for potentially MVE predicated instructions.  */
+#define MNUF(mnem, op, nops, ops, enc)					\
+  { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op,		\
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
+
+/* nUF but for potentially MVE predicated instructions.  */
+#define mnUF(mnem, op, nops, ops, enc)					\
+  { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op,	\
+    ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
+
+/* ToC but for potentially MVE predicated instructions.  */
+#define mToC(mnem, top, nops, ops, te) \
+  { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
+    do_##te, 1 }
+
+/* NCE but for MVE predicated instructions.  */
+#define MNCE(mnem, op, nops, ops, enc)					\
+   NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
+
+/* NCEF but for MVE predicated instructions.  */
+#define MNCEF(mnem, op, nops, ops, enc)					\
+    NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
 #define do_0 0
 
 static const struct asm_opcode insns[] =
@@ -21370,9 +21912,6 @@ static const struct asm_opcode insns[] =
  nCEF(vmla,     _vmla,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
  nCEF(vmls,     _vmls,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
 
- nCEF(vadd,     _vadd,    3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
- nCEF(vsub,     _vsub,    3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
-
  NCEF(vabs,     1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
  NCEF(vneg,     1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
 
@@ -21465,7 +22004,6 @@ static const struct asm_opcode insns[] =
  NUF(vbif,      1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
  NUF(vbifq,     1300110, 3, (RNQ,  RNQ,  RNQ),  neon_bitfield),
   /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32.  */
- nUF(vabd,      _vabd,    3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
  nUF(vabdq,     _vabd,    3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_if_su),
  nUF(vmax,      _vmax,    3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
  nUF(vmaxq,     _vmax,    3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_if_su),
@@ -21566,9 +22104,6 @@ static const struct asm_opcode insns[] =
   /* Data processing, three registers of different lengths.  */
   /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32.  */
  NUF(vabal,     0800500, 3, (RNQ, RND, RND),  neon_abal),
- NUF(vabdl,     0800700, 3, (RNQ, RND, RND),  neon_dyadic_long),
- NUF(vaddl,     0800000, 3, (RNQ, RND, RND),  neon_dyadic_long),
- NUF(vsubl,     0800200, 3, (RNQ, RND, RND),  neon_dyadic_long),
   /* If not scalar, fall back to neon_dyadic_long.
      Vector types as above, scalar types S16 S32 U16 U32.  */
  nUF(vmlal,     _vmlal,   3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
@@ -22083,7 +22618,40 @@ static const struct asm_opcode insns[] =
  toU("le",  _le,  2, (oLR, EXP),	 t_loloop),
 
  ToC("clrm",	e89f0000, 1, (CLRMLST),  t_clrm),
- ToC("vscclrm",	ec9f0a00, 1, (VRSDVLST), t_vscclrm)
+ ToC("vscclrm",	ec9f0a00, 1, (VRSDVLST), t_vscclrm),
+
+#undef  THUMB_VARIANT
+#define THUMB_VARIANT & mve_ext
+ ToC("vpst",	fe710f4d, 0, (), mve_vpt),
+ ToC("vpstt",	fe318f4d, 0, (), mve_vpt),
+ ToC("vpste",	fe718f4d, 0, (), mve_vpt),
+ ToC("vpsttt",	fe314f4d, 0, (), mve_vpt),
+ ToC("vpstte",	fe31cf4d, 0, (), mve_vpt),
+ ToC("vpstet",	fe71cf4d, 0, (), mve_vpt),
+ ToC("vpstee",	fe714f4d, 0, (), mve_vpt),
+ ToC("vpstttt",	fe312f4d, 0, (), mve_vpt),
+ ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
+ ToC("vpsttet",	fe31ef4d, 0, (), mve_vpt),
+ ToC("vpsttee",	fe31af4d, 0, (), mve_vpt),
+ ToC("vpstett",	fe71af4d, 0, (), mve_vpt),
+ ToC("vpstete",	fe71ef4d, 0, (), mve_vpt),
+ ToC("vpsteet",	fe716f4d, 0, (), mve_vpt),
+ ToC("vpsteee",	fe712f4d, 0, (), mve_vpt),
+
+#undef  ARM_VARIANT
+#define ARM_VARIANT    & fpu_vfp_ext_v1xd
+#undef  THUMB_VARIANT
+#define THUMB_VARIANT  & arm_ext_v6t2
+
+ mnCEF(vadd,     _vadd,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
+ mnCEF(vsub,     _vsub,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
+
+#undef ARM_VARIANT
+#define ARM_VARIANT & fpu_neon_ext_v1
+ mnUF(vabd,      _vabd,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
+ mnUF(vabdl,     _vabdl,	  3, (RNQMQ, RNDMQ, RNDMQ),   neon_dyadic_long),
+ mnUF(vaddl,     _vaddl,	  3, (RNQMQ, RNDMQ, RNDMQR),  neon_dyadic_long),
+ mnUF(vsubl,     _vsubl,	  3, (RNQMQ, RNDMQ, RNDMQR),  neon_dyadic_long),
 };
 #undef ARM_VARIANT
 #undef THUMB_VARIANT
@@ -25962,8 +26530,8 @@ arm_cleanup (void)
 {
   literal_pool * pool;
 
-  /* Ensure that all the IT blocks are properly closed.  */
-  check_it_blocks_finished ();
+  /* Ensure that all the predication blocks are properly closed.  */
+  check_pred_blocks_finished ();
 
   for (pool = list_of_pools; pool; pool = pool->next)
     {
@@ -26155,6 +26723,7 @@ md_begin (void)
 
   if (	 (arm_ops_hsh = hash_new ()) == NULL
       || (arm_cond_hsh = hash_new ()) == NULL
+      || (arm_vcond_hsh = hash_new ()) == NULL
       || (arm_shift_hsh = hash_new ()) == NULL
       || (arm_psr_hsh = hash_new ()) == NULL
       || (arm_v7m_psr_hsh = hash_new ()) == NULL
@@ -26167,6 +26736,8 @@ md_begin (void)
     hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
   for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
     hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
+  for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
+    hash_insert (arm_vcond_hsh, vconds[i].template_name, (void *) (vconds + i));
   for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
     hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
   for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
diff --git a/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l b/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l
index 755b6f74aed07b54a57efcfd1ac5e0aadd6e61b7..6b7e30ff1d96bf0cc1e49141bd3924bf8afa2b13 100644
--- a/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l
+++ b/gas/testsuite/gas/arm/armv8_3-a-fp-bad.l
@@ -3,5 +3,5 @@
 [^:]+:4: Error: VFP single precision register expected -- `vjcvt\.s32\.f64 r0,d1'
 [^:]+:5: Error: VFP/Neon double precision register expected -- `vjcvt\.s32\.f64 s0,s1'
 [^:]+:6: Error: VFP/Neon double precision register expected -- `vjcvt\.s32\.f32 s0,s1'
-[^:]+:7: Error: bad type in Neon instruction -- `vjcvt\.s32\.f32 s0,d1'
-[^:]+:8: Error: bad type in Neon instruction -- `vjcvt\.f32\.f64 s0,d1'
+[^:]+:7: Error: bad type in SIMD instruction -- `vjcvt\.s32\.f32 s0,d1'
+[^:]+:8: Error: bad type in SIMD instruction -- `vjcvt\.f32\.f64 s0,d1'
diff --git a/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l b/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l
index 2a3ea9b1d24dde073216b951b9eebed48fa2130f..d440d64011f63b687691a7e05e4e0f5cedcfb19b 100644
--- a/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l
+++ b/gas/testsuite/gas/arm/armv8_3-a-simd-bad.l
@@ -3,15 +3,15 @@
 [^:]+:7: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#0'
 [^:]+:8: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#180'
 [^:]+:9: Error: Neon double or quad precision register expected -- `vcadd\.f16 s0,s1,s2,#90'
-[^:]+:10: Error: bad type in Neon instruction -- `vcadd\.f64 d0,d1,d2,#90'
-[^:]+:11: Error: bad type in Neon instruction -- `vcadd\.f64 q0,q1,q2,#90'
+[^:]+:10: Error: bad type in SIMD instruction -- `vcadd\.f64 d0,d1,d2,#90'
+[^:]+:11: Error: bad type in SIMD instruction -- `vcadd\.f64 q0,q1,q2,#90'
 [^:]+:13: Error: operand types can't be inferred -- `vcmla d0,d1,d2,#90'
 [^:]+:14: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#-90'
 [^:]+:15: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#120'
 [^:]+:16: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#360'
 [^:]+:17: Error: Neon double or quad precision register expected -- `vcmla\.f16 s0,s1,s2,#90'
-[^:]+:18: Error: bad type in Neon instruction -- `vcmla\.f64 d0,d1,d2,#90'
-[^:]+:19: Error: bad type in Neon instruction -- `vcmla\.f64 q0,q1,q2,#90'
+[^:]+:18: Error: bad type in SIMD instruction -- `vcmla\.f64 d0,d1,d2,#90'
+[^:]+:19: Error: bad type in SIMD instruction -- `vcmla\.f64 q0,q1,q2,#90'
 [^:]+:21: Error: only D registers may be indexed -- `vcmla\.f16 q0,q1,q2\[0\],#90'
 [^:]+:22: Error: only D registers may be indexed -- `vcmla\.f32 q0,q1,q2\[0\],#90'
 [^:]+:23: Error: scalar out of range -- `vcmla\.f16 d0,d1,d2\[2\],#90'
@@ -22,15 +22,15 @@
 [^:]+:32: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#0'
 [^:]+:33: Error: immediate out of range -- `vcadd\.f32 q0,q1,q2,#180'
 [^:]+:34: Error: Neon double or quad precision register expected -- `vcadd\.f16 s0,s1,s2,#90'
-[^:]+:35: Error: bad type in Neon instruction -- `vcadd\.f64 d0,d1,d2,#90'
-[^:]+:36: Error: bad type in Neon instruction -- `vcadd\.f64 q0,q1,q2,#90'
+[^:]+:35: Error: bad type in SIMD instruction -- `vcadd\.f64 d0,d1,d2,#90'
+[^:]+:36: Error: bad type in SIMD instruction -- `vcadd\.f64 q0,q1,q2,#90'
 [^:]+:38: Error: operand types can't be inferred -- `vcmla d0,d1,d2,#90'
 [^:]+:39: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#-90'
 [^:]+:40: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#120'
 [^:]+:41: Error: immediate out of range -- `vcmla\.f32 q0,q1,q2,#360'
 [^:]+:42: Error: Neon double or quad precision register expected -- `vcmla\.f16 s0,s1,s2,#90'
-[^:]+:43: Error: bad type in Neon instruction -- `vcmla\.f64 d0,d1,d2,#90'
-[^:]+:44: Error: bad type in Neon instruction -- `vcmla\.f64 q0,q1,q2,#90'
+[^:]+:43: Error: bad type in SIMD instruction -- `vcmla\.f64 d0,d1,d2,#90'
+[^:]+:44: Error: bad type in SIMD instruction -- `vcmla\.f64 q0,q1,q2,#90'
 [^:]+:46: Error: only D registers may be indexed -- `vcmla\.f16 q0,q1,q2\[0\],#90'
 [^:]+:47: Error: only D registers may be indexed -- `vcmla\.f32 q0,q1,q2\[0\],#90'
 [^:]+:48: Error: scalar out of range -- `vcmla\.f16 d0,d1,d2\[2\],#90'
diff --git a/gas/testsuite/gas/arm/dotprod-illegal.l b/gas/testsuite/gas/arm/dotprod-illegal.l
index 5b88bc3002b9516956822f5604e33261d164722b..c0c8708b367ef14c36cb8ecc6d57722d3200591e 100644
--- a/gas/testsuite/gas/arm/dotprod-illegal.l
+++ b/gas/testsuite/gas/arm/dotprod-illegal.l
@@ -1,9 +1,9 @@
 [^:]*: Assembler messages:
-[^:]*:4: Error: bad type in Neon instruction -- `vudot.s8 d0,d2,d5'
-[^:]*:6: Error: bad type in Neon instruction -- `vudot.u16 d0,d2,d5'
-[^:]*:7: Error: bad type in Neon instruction -- `vsdot.s16 d1,d12,d18'
-[^:]*:9: Error: bad type in Neon instruction -- `vudot.u32 d2,d22,d1'
-[^:]*:10: Error: bad type in Neon instruction -- `vsdot.s32 d3,d30,d9'
+[^:]*:4: Error: bad type in SIMD instruction -- `vudot.s8 d0,d2,d5'
+[^:]*:6: Error: bad type in SIMD instruction -- `vudot.u16 d0,d2,d5'
+[^:]*:7: Error: bad type in SIMD instruction -- `vsdot.s16 d1,d12,d18'
+[^:]*:9: Error: bad type in SIMD instruction -- `vudot.u32 d2,d22,d1'
+[^:]*:10: Error: bad type in SIMD instruction -- `vsdot.s32 d3,d30,d9'
 [^:]*:12: Error: scalar out of range for multiply instruction -- `vudot.u8 d31,d2,d16\[0\]'
 [^:]*:13: Error: scalar out of range for multiply instruction -- `vsdot.s8 q13,q14,d22\[1\]'
 [^:]*:15: Error: scalar out of range for multiply instruction -- `vudot.u8 d1,d8,d15\[2\]'
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.d b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..86394e3edbda1b9a9760a44ce07263bbfa9de694
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VADD, VSUB and VABD instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vaddsubabd-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.l b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..d4d7bfe7f89b688de35744f19a4c3bd7f3519546
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.l
@@ -0,0 +1,55 @@
+[^:]*: Assembler messages:
+[^:]*:11: Error: bad type in SIMD instruction -- `vadd.p8 q0,q1,q2'
+[^:]*:12: Error: selected FPU does not support instruction -- `vadd.f16 q0,q1,q2'
+[^:]*:13: Error: selected FPU does not support instruction -- `vadd.f32 q0,q1,q2'
+[^:]*:14: Error: selected FPU does not support instruction -- `vadd.i64 q0,q1,q2'
+[^:]*: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
+[^:]*:16: Error: bad type in SIMD instruction -- `vsub.p8 q0,q1,q2'
+[^:]*:17: Error: selected FPU does not support instruction -- `vsub.f16 q0,q1,q2'
+[^:]*:18: Error: selected FPU does not support instruction -- `vsub.f32 q0,q1,q2'
+[^:]*:19: Error: selected FPU does not support instruction -- `vsub.i64 q0,q1,q2'
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Error: bad type in SIMD instruction -- `vadd.p8 q0,q1,r2'
+[^:]*:22: Error: selected FPU does not support instruction -- `vadd.f16 q0,q1,r2'
+[^:]*:23: Error: selected FPU does not support instruction -- `vadd.f32 q0,q1,r2'
+[^:]*:24: Error: selected FPU does not support instruction -- `vadd.i64 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: Error: bad type in SIMD instruction -- `vsub.p8 q0,q1,r2'
+[^:]*:27: Error: selected FPU does not support instruction -- `vsub.f16 q0,q1,r2'
+[^:]*:28: Error: selected FPU does not support instruction -- `vsub.f32 q0,q1,r2'
+[^:]*:29: Error: selected FPU does not support instruction -- `vsub.i64 q0,q1,r2'
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:31: Error: bad type in SIMD instruction -- `vabd.p8 q0,q1,q2'
+[^:]*:32: Error: selected FPU does not support instruction -- `vabd.f16 q0,q1,q2'
+[^:]*:33: Error: selected FPU does not support instruction -- `vabd.f32 q0,q1,q2'
+[^:]*:34: Error: bad type in SIMD instruction -- `vabd.i64 q0,q1,q2'
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:37: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:38: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:39: Warning: instruction is UNPREDICTABLE with PC operand
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.s b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..809937d4c1ed99974b1670ce95edb70c2edf8ed1
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-1.s
@@ -0,0 +1,39 @@
+.macro cond op, lastreg, size
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\size q0, q1, \lastreg
+.endr
+.endm
+
+.syntax unified
+.text
+.thumb
+vadd.p8 q0, q1, q2
+vadd.f16 q0, q1, q2
+vadd.f32 q0, q1, q2
+vadd.i64 q0, q1, q2
+cond vadd, q2, .i32
+vsub.p8 q0, q1, q2
+vsub.f16 q0, q1, q2
+vsub.f32 q0, q1, q2
+vsub.i64 q0, q1, q2
+cond vsub, q2, .i32
+vadd.p8 q0, q1, r2
+vadd.f16 q0, q1, r2
+vadd.f32 q0, q1, r2
+vadd.i64 q0, q1, r2
+cond vadd, r2, .i32
+vsub.p8 q0, q1, r2
+vsub.f16 q0, q1, r2
+vsub.f32 q0, q1, r2
+vsub.i64 q0, q1, r2
+cond vsub, r2, .i32
+vabd.p8 q0, q1, q2
+vabd.f16 q0, q1, q2
+vabd.f32 q0, q1, q2
+vabd.i64 q0, q1, q2
+cond vabd, q2, .s32
+vadd.i32 q0, q1, sp
+vsub.i32 q0, q1, sp
+vadd.i32 q0, q1, pc
+vsub.i32 q0, q1, pc
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.d b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..602dc3276ae1f916196f777ad9d934fbe229ec68
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.d
@@ -0,0 +1,6 @@
+#name: bad MVE FP VADD, VSUB and VABD instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vaddsubabd-bad-2.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.l b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..77d634c45618edabd6f95174741dd66772b111cb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.l
@@ -0,0 +1,46 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vadd.p8 q0,q1,q2'
+[^:]*:14: Error: selected FPU does not support instruction -- `vadd.i64 q0,q1,q2'
+[^:]*: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
+[^:]*:16: Error: bad type in SIMD instruction -- `vsub.p8 q0,q1,q2'
+[^:]*:17: Error: selected FPU does not support instruction -- `vsub.i64 q0,q1,q2'
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: bad type in SIMD instruction -- `vadd.p8 q0,q1,r2'
+[^:]*:20: Error: selected FPU does not support instruction -- `vadd.i64 q0,q1,r2'
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Error: bad type in SIMD instruction -- `vsub.p8 q0,q1,r2'
+[^:]*:23: Error: selected FPU does not support instruction -- `vsub.i64 q0,q1,r2'
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Error: bad type in SIMD instruction -- `vabd.p8 q0,q1,q2'
+[^:]*:26: Error: bad type in SIMD instruction -- `vabd.i64 q0,q1,q2'
+[^:]*: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 with SP operand
+[^:]*:29: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:30: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:31: Warning: instruction is UNPREDICTABLE with PC operand
+
diff --git a/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.s b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..15242909d9657ba56709c128d96928e677af2036
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddsubabd-bad-2.s
@@ -0,0 +1,32 @@
+.macro cond op, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().f32 q0, q1, \lastreg
+.endr
+.endm
+
+
+
+.syntax unified
+.text
+.thumb
+vadd.p8 q0, q1, q2
+vadd.i64 q0, q1, q2
+cond vadd, q2
+vsub.p8 q0, q1, q2
+vsub.i64 q0, q1, q2
+cond vsub, q2
+vadd.p8 q0, q1, r2
+vadd.i64 q0, q1, r2
+cond vadd, r2
+vsub.p8 q0, q1, r2
+vsub.i64 q0, q1, r2
+cond vsub, r2
+vabd.p8 q0, q1, q2
+vabd.i64 q0, q1, q2
+cond vabd, q2
+vadd.i32 q0, q1, sp
+vsub.i32 q0, q1, sp
+vadd.i32 q0, q1, pc
+vsub.i32 q0, q1, pc
+
diff --git a/gas/testsuite/gas/arm/mve-vpst-bad.d b/gas/testsuite/gas/arm/mve-vpst-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..f328abc80f188ded287273fe04edee4ed42e4f15
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpst-bad.d
@@ -0,0 +1,6 @@
+#name: bad VPST instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vpst-bad.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vpst-bad.l b/gas/testsuite/gas/arm/mve-vpst-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..35a56890c85fd44ac22e47ea97b3bddd6811f14e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpst-bad.l
@@ -0,0 +1,19 @@
+[^:]*: Assembler messages:
+[^:]*:6: Error: syntax error -- `vpsteq'
+[^:]*:9: Error: vector predicated instruction should be in VPT/VPST block -- `vaddt.i32 q0,q1,q2'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: syntax error -- `vaddeq.i32 q0,q1,q2'
+[^:]*:21: Error: instruction missing MVE vector predication code -- `vadd.i32 q0,q1,q2'
+[^:]*:23: Error: syntax error -- `vaddeq.i32 q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vaddt.i32 q0,q1,q2'
+[^:]*:33: Error: bad instruction `addt r0,r0,r1'
+[^:]*:37: Error: instruction not allowed in IT block -- `add r0,r0,r1'
+[^:]*:40: Error: thumb conditional instruction should be in IT block -- `addeq r0,r0,r1'
+[^:]*:43: Error: bad instruction `addt r0,r0,r1'
+[^:]*:47: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:49: Error: thumb conditional instruction should be in IT block -- `addeq r0,r0,r1'
+[^:]*:51: Error: bad instruction `addt r0,r0,r1'
+[^:]*:55: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:62: Error: incorrect condition in VPT/VPST block -- `vaddt.i32 q0,q1,q2'
+[^:]*:65: Error: syntax error -- `vaddeq.i32 q0,q1,q2'
+[^:]*:68: Warning: section '.text' finished with an open VPT/VPST block.
diff --git a/gas/testsuite/gas/arm/mve-vpst-bad.s b/gas/testsuite/gas/arm/mve-vpst-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..f41d66bfccb136cf042a7d82a13f8b639b7cc556
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpst-bad.s
@@ -0,0 +1,68 @@
+.syntax unified
+.text
+.thumb
+@ Case 1
+it eq
+vpsteq
+@ Case 2
+it eq
+vaddt.i32 q0, q1, q2
+@ Case 3
+it eq
+vadd.i32 q0, q1, q2
+@ Case 4
+vpst
+vaddeq.i32 q0, q1, q2
+@ Case 5
+vpst
+vaddt.i32 q0, q1, q2
+@ Case 6
+vpst
+vadd.i32 q0, q1, q2
+@ Case 7
+vaddeq.i32 q0, q1, q2
+@ Case 8
+vaddt.i32 q0, q1, q2
+@ Case 9
+vadd.i32 q0, q1, q2
+@ Case 10
+it eq
+addeq r0, r0, r1
+@ Case 11
+it eq
+addt r0, r0, r1
+addeq r0, r0, r1
+@ Case 12
+it eq
+add r0, r0, r1
+@ Case 13
+vpst
+addeq r0, r0, r1
+@ Case 14
+vpst
+addt r0, r0, r1
+vaddt.i32 q0, q0, q1
+@ Case 15
+vpst
+add r0, r0, r1
+@ Case 16
+addeq r0, r0, r1
+@ Case 17
+addt r0, r0, r1
+@ Case 18
+add r0, r0, r1
+it le
+vpstete
+vaddt.i32 q0, q1, q2
+vadde.i32 q0, q1, q2
+vaddt.i32 q0, q1, q2
+vadde.i32 q0, q1, q2
+vpste
+vaddt.i32 q0, q1, q2
+vaddt.i32 q0, q1, q2
+vpste
+vaddt.i32 q0, q1, q2
+vaddeq.i32 q0, q1, q2
+vpstet
+vaddt.i32 q0, q1, q2
+vadde.i32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/neon-ldst-es-bad.l b/gas/testsuite/gas/arm/neon-ldst-es-bad.l
index b0c854eee715cb15b14c418a157d0b5c6874b92f..84758c6b2b338be20160e63586b01b7fca4ef35b 100644
--- a/gas/testsuite/gas/arm/neon-ldst-es-bad.l
+++ b/gas/testsuite/gas/arm/neon-ldst-es-bad.l
@@ -1,12 +1,12 @@
 [^:]*: Assembler messages:
-[^:]*:2: Error: bad type in Neon instruction -- `vld1\.64 {d0\[1\]},\[r0\]'
-[^:]*:3: Error: bad type in Neon instruction -- `vld1\.64 {d0\[\]},\[r0\]'
-[^:]*:4: Error: bad type in Neon instruction -- `vld2\.64 {d0\[1\]},\[r0\]'
-[^:]*:5: Error: bad type in Neon instruction -- `vld2\.64 {d0\[\]},\[r0\]'
+[^:]*:2: Error: bad type in SIMD instruction -- `vld1\.64 {d0\[1\]},\[r0\]'
+[^:]*:3: Error: bad type in SIMD instruction -- `vld1\.64 {d0\[\]},\[r0\]'
+[^:]*:4: Error: bad type in SIMD instruction -- `vld2\.64 {d0\[1\]},\[r0\]'
+[^:]*:5: Error: bad type in SIMD instruction -- `vld2\.64 {d0\[\]},\[r0\]'
 [^:]*:6: Error: bad element type for instruction -- `vld2\.64 {d0-d1},\[r0\]'
-[^:]*:7: Error: bad type in Neon instruction -- `vld3\.64 {d0\[1\]},\[r0\]'
-[^:]*:8: Error: bad type in Neon instruction -- `vld3\.64 {d0\[\]},\[r0\]'
+[^:]*:7: Error: bad type in SIMD instruction -- `vld3\.64 {d0\[1\]},\[r0\]'
+[^:]*:8: Error: bad type in SIMD instruction -- `vld3\.64 {d0\[\]},\[r0\]'
 [^:]*:9: Error: bad element type for instruction -- `vld3\.64 {d0-d2},\[r0\]'
-[^:]*:10: Error: bad type in Neon instruction -- `vld4\.64 {d0\[1\]},\[r0\]'
-[^:]*:11: Error: bad type in Neon instruction -- `vld4\.64 {d0\[\]},\[r0\]'
+[^:]*:10: Error: bad type in SIMD instruction -- `vld4\.64 {d0\[1\]},\[r0\]'
+[^:]*:11: Error: bad type in SIMD instruction -- `vld4\.64 {d0\[\]},\[r0\]'
 [^:]*:12: Error: bad element type for instruction -- `vld4\.64 {d0-d3},\[r0\]'

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 3/57][Arm][GAS] Add support for MVE instructions: vabs and vneg
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
  2019-05-01 16:53 ` [PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp Andre Vieira (lists)
  2019-05-01 16:55 ` [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd Andre Vieira (lists)
@ 2019-05-01 16:56 ` Andre Vieira (lists)
  2019-05-01 16:57 ` [PATCH 4/57][Arm][GAS] Add support for MVE instructions: vabav, vmladav and vmlsdav Andre Vieira (lists)
                   ` (57 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:56 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 591 bytes --]

Hi,

This patch adds support for MVE instructions VABS and VNEG.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_neon_abs_neg): Make it accept MVE variant.
         (insns): Change vabs and vneg entries to accept MVE variants.
	* testsuite/gas/arm/mve-vabsneg-bad-1.d: New test.
	* testsuite/gas/arm/mve-vabsneg-bad-1.l: New test.
	* testsuite/gas/arm/mve-vabsneg-bad-1.s: New test.
	* testsuite/gas/arm/mve-vabsneg-bad-2.d: New test.
	* testsuite/gas/arm/mve-vabsneg-bad-2.l: New test.
	* testsuite/gas/arm/mve-vabsneg-bad-2.s: New test.

[-- Attachment #2: 3.patch --]
[-- Type: text/x-patch, Size: 8906 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 90caa4e3c93eeee753a69d18d13cfd0257a91cc9..848b339f3137b4acff61bfca88f4c83aa3f73970 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15950,12 +15950,13 @@ do_neon_abs_neg (void)
   if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
     return;
 
-  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
-    return;
-
   rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
   et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
 
+  if (check_simd_pred_availability (et.type == NT_float,
+				    NEON_CHECK_ARCH | NEON_CHECK_CC))
+    return;
+
   inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
   inst.instruction |= HI1 (inst.operands[0].reg) << 22;
   inst.instruction |= LOW4 (inst.operands[1].reg);
@@ -21896,9 +21897,6 @@ static const struct asm_opcode insns[] =
  nCEF(vmla,     _vmla,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
  nCEF(vmls,     _vmls,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
 
- NCEF(vabs,     1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
- NCEF(vneg,     1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
-
  NCE(vldm,      c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
  NCE(vldmia,    c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
  NCE(vldmdb,    d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
@@ -22630,6 +22628,9 @@ static const struct asm_opcode insns[] =
  mnCEF(vadd,     _vadd,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
  mnCEF(vsub,     _vsub,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
 
+ MNCEF(vabs,  1b10300,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
+ MNCEF(vneg,  1b10380,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
+
 #undef ARM_VARIANT
 #define ARM_VARIANT & fpu_neon_ext_v1
  mnUF(vabd,      _vabd,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-1.d b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..493583356033700df415498c55f17a6e9c0be42f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.d
@@ -0,0 +1,6 @@
+#name: bad MVE VABS and VNEG instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vabsneg-bad-1.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-1.l b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..46fda8b53f72aac4da99f02e88e5c7d95fdc1716
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.l
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vabs.p8 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vabs.p16 q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vabs.u8 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vabs.u16 q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vabs.u32 q0,q1'
+[^:]*:18: Error: selected FPU does not support instruction -- `vabs.f16 q0,q1'
+[^:]*:19: Error: selected FPU does not support instruction -- `vabs.f32 q0,q1'
+[^:]*:20: Error: bad type in SIMD instruction -- `vabs.s64 q0,q1'
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Error: bad type in SIMD instruction -- `vneg.p8 q0,q1'
+[^:]*:23: Error: bad type in SIMD instruction -- `vneg.p16 q0,q1'
+[^:]*:24: Error: bad type in SIMD instruction -- `vneg.u8 q0,q1'
+[^:]*:25: Error: bad type in SIMD instruction -- `vneg.u16 q0,q1'
+[^:]*:26: Error: bad type in SIMD instruction -- `vneg.u32 q0,q1'
+[^:]*:27: Error: selected FPU does not support instruction -- `vneg.f16 q0,q1'
+[^:]*:28: Error: selected FPU does not support instruction -- `vneg.f32 q0,q1'
+[^:]*:29: Error: bad type in SIMD instruction -- `vneg.s64 q0,q1'
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:30: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:32: Error: syntax error -- `vnegeq.s32 q0,q1'
+[^:]*:33: Error: syntax error -- `vnegeq.s32 q0,q1'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vneg.s32 q0,q1'
+[^:]*:36: Error: vector predicated instruction should be in VPT/VPST block -- `vnegt.s32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-1.s b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..cda955ccc486300cc2e33bc50f5eee0517d9bdad
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-1.s
@@ -0,0 +1,37 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 q0, q1
+.endr
+.endm
+
+
+
+.syntax unified
+.text
+.thumb
+vabs.p8 q0, q1
+vabs.p16 q0, q1
+vabs.u8 q0, q1
+vabs.u16 q0, q1
+vabs.u32 q0, q1
+vabs.f16 q0, q1
+vabs.f32 q0, q1
+vabs.s64 q0, q1
+cond vabs
+vneg.p8 q0, q1
+vneg.p16 q0, q1
+vneg.u8 q0, q1
+vneg.u16 q0, q1
+vneg.u32 q0, q1
+vneg.f16 q0, q1
+vneg.f32 q0, q1
+vneg.s64 q0, q1
+cond vneg
+it eq
+vnegeq.s32 q0, q1
+vnegeq.s32 q0, q1
+vpst
+vneg.s32 q0, q1
+vnegt.s32 q0, q1
+
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-2.d b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..14d0137fd0b3188a255f885ffe8a810f81c15c7a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.d
@@ -0,0 +1,6 @@
+#name: bad MVE FP VABS and VNEG instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vabsneg-bad-2.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-2.l b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..26bd0f49c9f7603d310e3300405a96beec79943f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.l
@@ -0,0 +1,29 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vabs.p8 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vabs.p16 q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vabs.u8 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vabs.u16 q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vabs.u32 q0,q1'
+[^:]*:18: Error: bad type in SIMD instruction -- `vabs.s64 q0,q1'
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Error: bad type in SIMD instruction -- `vneg.p8 q0,q1'
+[^:]*:21: Error: bad type in SIMD instruction -- `vneg.p16 q0,q1'
+[^:]*:22: Error: bad type in SIMD instruction -- `vneg.u8 q0,q1'
+[^:]*:23: Error: bad type in SIMD instruction -- `vneg.u16 q0,q1'
+[^:]*:24: Error: bad type in SIMD instruction -- `vneg.u32 q0,q1'
+[^:]*:25: Error: bad type in SIMD instruction -- `vneg.s64 q0,q1'
+[^:]*: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
+[^:]*:28: Error: syntax error -- `vnegeq.f32 q0,q1'
+[^:]*:29: Error: syntax error -- `vnegeq.f32 q0,q1'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vneg.f32 q0,q1'
+[^:]*:32: Error: vector predicated instruction should be in VPT/VPST block -- `vnegt.f32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vabsneg-bad-2.s b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..aff2e410ab0b934ea520b9ea63c84701f607a510
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabsneg-bad-2.s
@@ -0,0 +1,32 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 q0, q1
+.endr
+.endm
+
+
+
+.syntax unified
+.text
+.thumb
+vabs.p8 q0, q1
+vabs.p16 q0, q1
+vabs.u8 q0, q1
+vabs.u16 q0, q1
+vabs.u32 q0, q1
+vabs.s64 q0, q1
+cond vabs
+vneg.p8 q0, q1
+vneg.p16 q0, q1
+vneg.u8 q0, q1
+vneg.u16 q0, q1
+vneg.u32 q0, q1
+vneg.s64 q0, q1
+cond vneg
+it eq
+vnegeq.f32 q0, q1
+vnegeq.f32 q0, q1
+vpst
+vneg.f32 q0, q1
+vnegt.f32 q0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 4/57][Arm][GAS] Add support for MVE instructions: vabav, vmladav and vmlsdav
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (2 preceding siblings ...)
  2019-05-01 16:56 ` [PATCH 3/57][Arm][GAS] Add support for MVE instructions: vabs and vneg Andre Vieira (lists)
@ 2019-05-01 16:57 ` Andre Vieira (lists)
  2019-05-01 16:59 ` [PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t} Andre Vieira (lists)
                   ` (56 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:57 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1506 bytes --]

Hi,

This patch adds support for VABAV, VMLADAV and VMLSDAV. These are the 
first MVE-only mnemonics, so this patch shows how we deal with such 
instructions.

We define M_MNEM_<insn> MACROs to be able to encode and reference a 
particular instruction.

Cheers,
Andre

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (struct asm_opcode): Make avalue a full int.
	(BAD_ODD, BAD_EVEN, BAD_SIMD_TYPE): New errors.
	(enum operand_parse_code): Handle new operands.
	(parse_operands):
	(M_MNEM_vabav, M_MNEM_vmladav, M_MNEM_vmladava, M_MNEM_vmladavx,
         M_MNEM_vmladavax, M_MNEM_vmlsdav, M_MNEM_vmlsdava, M_MNEM_vmlsdavx,
         M_MNEM_vmlsdavax): Define new encodings.
	(NEON_SHAPE_DEF): Add new shape.
	(neon_check_type): Use BAD_SIMD_TYPE.
	(mve_encode_rqq): New encoding helper function.
	(do_mve_vabav, do_mve_vmladav): New encoding functions.
	(mCEF): New MACRO.
	* testsuite/gas/arm/mve-vabav-bad.d: New test.
	* testsuite/gas/arm/mve-vabav-bad.l: New test.
	* testsuite/gas/arm/mve-vabav-bad.s: New test.
	* testsuite/gas/arm/mve-vmladav-bad.d: New test.
	* testsuite/gas/arm/mve-vmladav-bad.l: New test.
	* testsuite/gas/arm/mve-vmladav-bad.s: New test.
	* testsuite/gas/arm/mve-vmlav-bad.d: New test.
	* testsuite/gas/arm/mve-vmlav-bad.l: New test.
	* testsuite/gas/arm/mve-vmlav-bad.s: New test.
	* testsuite/gas/arm/mve-vmlsdav-bad.d: New test.
	* testsuite/gas/arm/mve-vmlsdav-bad.l: New test.
	* testsuite/gas/arm/mve-vmlsdav-bad.s: New test.

[-- Attachment #2: 4.patch --]
[-- Type: text/x-patch, Size: 24652 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index fa095ad676dae1bede1281bd62b0b5acdc91b828..7ec71815eebb9d09d12b1660e8ecd1f8f3cb0e98 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -711,7 +711,7 @@ struct asm_opcode
   unsigned int tag : 4;
 
   /* Basic instruction code.  */
-  unsigned int avalue : 28;
+  unsigned int avalue;
 
   /* Thumb-format instruction code.  */
   unsigned int tvalue;
@@ -854,6 +854,8 @@ struct asm_opcode
 #define BAD_ARGS	_("bad arguments to instruction")
 #define BAD_SP          _("r13 not allowed here")
 #define BAD_PC		_("r15 not allowed here")
+#define BAD_ODD		_("Odd register not allowed here")
+#define BAD_EVEN	_("Even register not allowed here")
 #define BAD_COND	_("instruction cannot be conditional")
 #define BAD_OVERLAP	_("registers may not be the same")
 #define BAD_HIREG	_("lo register required")
@@ -887,6 +889,7 @@ struct asm_opcode
 			  " operand")
 #define MVE_BAD_SP	_("Warning: instruction is UNPREDICTABLE with SP" \
 			  " operand")
+#define BAD_SIMD_TYPE	_("bad type in SIMD instruction")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -6716,8 +6719,12 @@ enum operand_parse_code
 		 */
   OP_RNSDQMQR,	/* Neon single, double or quad register, MVE vector register or
 		   GPR (no SP/SP)  */
+  OP_RMQ,	/* MVE vector register.  */
+
   /* New operands for Armv8.1-M Mainline.  */
   OP_LR,	/* ARM LR register */
+  OP_RRe,	/* ARM register, only even numbered.  */
+  OP_RRo,	/* ARM register, only odd numbered, not r13 or r15.  */
   OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
 
   OP_REGLST,	/* ARM register list */
@@ -6974,6 +6981,8 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_RRnpc:
 	case OP_RRnpcsp:
 	case OP_oRR:
+	case OP_RRe:
+	case OP_RRo:
 	case OP_LR:
 	case OP_oLR:
 	case OP_RR:    po_reg_or_fail (REG_TYPE_RN);	  break;
@@ -7038,6 +7047,9 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_reg_or_fail (REG_TYPE_NSDQ);
 	  inst.error = 0;
 	  break;
+	case OP_RMQ:
+	  po_reg_or_fail (REG_TYPE_MQ);
+	  break;
 	/* Neon scalar. Using an element size of 8 means that some invalid
 	   scalars are accepted here, so deal with those in later code.  */
 	case OP_RNSC:  po_scalar_or_goto (8, failure);    break;
@@ -7558,6 +7570,24 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    inst.error = _("operand must be LR register");
 	  break;
 
+	case OP_RRe:
+	  if (inst.operands[i].isreg
+	      && (inst.operands[i].reg & 0x00000001) != 0)
+	    inst.error = BAD_ODD;
+	  break;
+
+	case OP_RRo:
+	  if (inst.operands[i].isreg)
+	    {
+	      if ((inst.operands[i].reg & 0x00000001) != 1)
+		inst.error = BAD_EVEN;
+	      else if (inst.operands[i].reg == REG_SP)
+		as_tsktsk (MVE_BAD_SP);
+	      else if (inst.operands[i].reg == REG_PC)
+		inst.error = BAD_PC;
+	    }
+	  break;
+
 	default:
 	  break;
 	}
@@ -13793,6 +13823,17 @@ do_t_loloop (void)
     }
 }
 
+/* MVE instruction encoder helpers.  */
+#define M_MNEM_vabav	0xee800f01
+#define M_MNEM_vmladav	  0xeef00e00
+#define M_MNEM_vmladava	  0xeef00e20
+#define M_MNEM_vmladavx	  0xeef01e00
+#define M_MNEM_vmladavax  0xeef01e20
+#define M_MNEM_vmlsdav	  0xeef00e01
+#define M_MNEM_vmlsdava	  0xeef00e21
+#define M_MNEM_vmlsdavx	  0xeef01e01
+#define M_MNEM_vmlsdavax  0xeef01e21
+
 /* Neon instruction encoder helpers.  */
 
 /* Encodings for the different types for various Neon opcodes.  */
@@ -13956,6 +13997,7 @@ NEON_ENC_TAB
      - a table used to drive neon_select_shape.  */
 
 #define NEON_SHAPE_DEF			\
+  X(3, (R, Q, Q), QUAD),		\
   X(3, (D, D, D), DOUBLE),		\
   X(3, (Q, Q, Q), QUAD),		\
   X(3, (D, D, I), DOUBLE),		\
@@ -14683,7 +14725,7 @@ neon_check_type (unsigned els, enum neon_shape ns, ...)
 
 		  if ((given_type & types_allowed) == 0)
 		    {
-		      first_error (_("bad type in SIMD instruction"));
+		      first_error (BAD_SIMD_TYPE);
 		      return badtype;
 		    }
 		}
@@ -15165,6 +15207,19 @@ mve_encode_qqr(int size, int fp)
   inst.is_neon = 1;
 }
 
+static void
+mve_encode_rqq (unsigned bit28, unsigned size)
+{
+  inst.instruction |= bit28 << 28;
+  inst.instruction |= neon_logbits (size) << 20;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[2].reg);
+  inst.is_neon = 1;
+}
+
 /* Encode insns with bit pattern:
 
   |28/24|23|22 |21 20|19 16|15 12|11    8|7|6|5|4|3  0|
@@ -15883,6 +15938,65 @@ do_neon_qdmulh (void)
     }
 }
 
+static void
+do_mve_vabav (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
+
+  if (rs == NS_NULL)
+    return;
+
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    return;
+
+  struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
+					    | N_S16 | N_S32 | N_U8 | N_U16
+					    | N_U32);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_rqq (et.type == NT_unsigned, et.size);
+}
+
+static void
+do_mve_vmladav (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
+  struct neon_type_el et = neon_check_type (3, rs,
+					    N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
+  if (et.type == NT_unsigned
+      && (inst.instruction == M_MNEM_vmladavx
+	  || inst.instruction == M_MNEM_vmladavax
+	  || inst.instruction == M_MNEM_vmlsdav
+	  || inst.instruction == M_MNEM_vmlsdava
+	  || inst.instruction == M_MNEM_vmlsdavx
+	  || inst.instruction == M_MNEM_vmlsdavax))
+    first_error (BAD_SIMD_TYPE);
+
+  constraint (inst.operands[2].reg > 14,
+	      _("MVE vector register in the range [Q0..Q7] expected"));
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (inst.instruction == M_MNEM_vmlsdav
+      || inst.instruction == M_MNEM_vmlsdava
+      || inst.instruction == M_MNEM_vmlsdavx
+      || inst.instruction == M_MNEM_vmlsdavax)
+    inst.instruction |= (et.size == 8) << 28;
+  else
+    inst.instruction |= (et.size == 8) << 8;
+
+  mve_encode_rqq (et.type == NT_unsigned, 64);
+  inst.instruction |= (et.size == 32) << 16;
+}
+
 static void
 do_neon_qrdmlah (void)
 {
@@ -20565,7 +20679,7 @@ static struct asm_barrier_opt barrier_opt_names[] =
 
 /*   */
 #define mCEF(mnem, op, nops, ops, enc)				\
-  { #mnem, OPS##nops ops, OT_csuffixF, 0, M_MNEM##op,		\
+  { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op,	\
     ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
 
 
@@ -22625,6 +22739,19 @@ static const struct asm_opcode insns[] =
  ToC("vpsteet",	fe716f4d, 0, (), mve_vpt),
  ToC("vpsteee",	fe712f4d, 0, (), mve_vpt),
 
+ /* MVE and MVE FP only.  */
+ mCEF(vabav,	_vabav,	    3, (RRnpcsp, RMQ, RMQ),		  mve_vabav),
+ mCEF(vmladav,	  _vmladav,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmladava,	  _vmladava,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmladavx,	  _vmladavx,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmladavax,  _vmladavax,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlav,	  _vmladav,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlava,	  _vmladava,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlsdav,	  _vmlsdav,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlsdava,	  _vmlsdava,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlsdavx,	  _vmlsdavx,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+ mCEF(vmlsdavax,  _vmlsdavax,	3, (RRe, RMQ, RMQ),		mve_vmladav),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT    & fpu_vfp_ext_v1xd
 #undef  THUMB_VARIANT
diff --git a/gas/testsuite/gas/arm/mve-vabav-bad.d b/gas/testsuite/gas/arm/mve-vabav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..42c9dad6336cd2a610652bd6bb8798f15ebb8fcf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabav-bad.d
@@ -0,0 +1,6 @@
+#name: bad MVE VABAV instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vabav-bad.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vabav-bad.l b/gas/testsuite/gas/arm/mve-vabav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..40d44832bddb84bae35f488e9656fa615ac81a6e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabav-bad.l
@@ -0,0 +1,18 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vabav.s64 r0,q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vabav.f16 r0,q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vabav.f32 r0,q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vabav.p8 r0,q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vabav.p16 r0,q0,q1'
+[^:]*:18: Error: r13 not allowed here -- `vabav.s32 r13,q0,q1'
+[^:]*:19: Error: r15 not allowed here -- `vabav.s32 r15,q0,q1'
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Error: syntax error -- `vabaveq.s32 r0,q0,q1'
+[^:]*:23: Error: syntax error -- `vabaveq.s32 r0,q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vabavt.s32 r0,q0,q1'
+[^:]*:26: Error: vector predicated instruction should be in VPT/VPST block -- `vabavt.s32 r0,q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vabav-bad.s b/gas/testsuite/gas/arm/mve-vabav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..dfb8dee3965f6ddd7fa35afd97e1334834d34cf3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vabav-bad.s
@@ -0,0 +1,26 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 r0, q0, q1
+.endr
+.endm
+
+
+
+.syntax unified
+.text
+.thumb
+vabav.s64 r0, q0, q1
+vabav.f16 r0, q0, q1
+vabav.f32 r0, q0, q1
+vabav.p8 r0, q0, q1
+vabav.p16 r0, q0, q1
+vabav.s32 r13, q0, q1
+vabav.s32 r15, q0, q1
+cond vabav
+vpst
+vabaveq.s32 r0, q0, q1
+vabaveq.s32 r0, q0, q1
+it eq
+vabavt.s32 r0, q0, q1
+vabavt.s32 r0, q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vmladav-bad.d b/gas/testsuite/gas/arm/mve-vmladav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..eb82d47ffc9cc19291101d2709140e5e561d702a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmladav-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLADAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmladav-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmladav-bad.l b/gas/testsuite/gas/arm/mve-vmladav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..fae770cc362bf384ed03fdf75bd7c757764c3584
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmladav-bad.l
@@ -0,0 +1,55 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Error: bad type in SIMD instruction -- `vmladav.s64 r0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmladav.f32 r0,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vmladava.s64 r0,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vmladava.f32 r0,q1,q2'
+[^:]*:18: Error: bad type in SIMD instruction -- `vmladavx.s64 r0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vmladavx.f32 r0,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vmladavax.s64 r0,q1,q2'
+[^:]*:21: Error: bad type in SIMD instruction -- `vmladavax.f32 r0,q1,q2'
+[^:]*:22: Error: bad type in SIMD instruction -- `vmladavx.u32 r0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vmladavax.u16 r0,q1,q2'
+[^:]*:25: Error: syntax error -- `vmladaveq.s32 r0,q1,q2'
+[^:]*:26: Error: syntax error -- `vmladaveq.s32 r0,q1,q2'
+[^:]*:28: Error: syntax error -- `vmladaveq.s32 r0,q1,q2'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vmladavt.s32 r0,q1,q2'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vmladav.s32 r0,q1,q2'
+[^:]*:33: Error: syntax error -- `vmladavaeq.s32 r0,q1,q2'
+[^:]*:34: Error: syntax error -- `vmladavaeq.s32 r0,q1,q2'
+[^:]*:36: Error: syntax error -- `vmladavaeq.s32 r0,q1,q2'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vmladavat.s32 r0,q1,q2'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vmladava.s32 r0,q1,q2'
+[^:]*:41: Error: syntax error -- `vmladavxeq.s32 r0,q1,q2'
+[^:]*:42: Error: syntax error -- `vmladavxeq.s32 r0,q1,q2'
+[^:]*:44: Error: syntax error -- `vmladavxeq.s32 r0,q1,q2'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vmladavxt.s32 r0,q1,q2'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vmladavx.s32 r0,q1,q2'
+[^:]*:49: Error: syntax error -- `vmladavaxeq.s32 r0,q1,q2'
+[^:]*:50: Error: syntax error -- `vmladavaxeq.s32 r0,q1,q2'
+[^:]*:52: Error: syntax error -- `vmladavaxeq.s32 r0,q1,q2'
+[^:]*:53: Error: vector predicated instruction should be in VPT/VPST block -- `vmladavaxt.s32 r0,q1,q2'
+[^:]*:55: Error: instruction missing MVE vector predication code -- `vmladavax.s32 r0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmladav-bad.s b/gas/testsuite/gas/arm/mve-vmladav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..6621372d287d3617c1bba07f7645336a99d9f8f3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmladav-bad.s
@@ -0,0 +1,55 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond vmladav
+cond vmladava
+cond vmladavx
+cond vmladavax
+vmladav.s64 r0, q1, q2
+vmladav.f32 r0, q1, q2
+vmladava.s64 r0, q1, q2
+vmladava.f32 r0, q1, q2
+vmladavx.s64 r0, q1, q2
+vmladavx.f32 r0, q1, q2
+vmladavax.s64 r0, q1, q2
+vmladavax.f32 r0, q1, q2
+vmladavx.u32 r0, q1, q2
+vmladavax.u16 r0, q1, q2
+it eq
+vmladaveq.s32 r0, q1, q2
+vmladaveq.s32 r0, q1, q2
+vpst
+vmladaveq.s32 r0, q1, q2
+vmladavt.s32 r0, q1, q2
+vpst
+vmladav.s32 r0, q1, q2
+it eq
+vmladavaeq.s32 r0, q1, q2
+vmladavaeq.s32 r0, q1, q2
+vpst
+vmladavaeq.s32 r0, q1, q2
+vmladavat.s32 r0, q1, q2
+vpst
+vmladava.s32 r0, q1, q2
+it eq
+vmladavxeq.s32 r0, q1, q2
+vmladavxeq.s32 r0, q1, q2
+vpst
+vmladavxeq.s32 r0, q1, q2
+vmladavxt.s32 r0, q1, q2
+vpst
+vmladavx.s32 r0, q1, q2
+it eq
+vmladavaxeq.s32 r0, q1, q2
+vmladavaxeq.s32 r0, q1, q2
+vpst
+vmladavaxeq.s32 r0, q1, q2
+vmladavaxt.s32 r0, q1, q2
+vpst
+vmladavax.s32 r0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmlav-bad.d b/gas/testsuite/gas/arm/mve-vmlav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6b6af1b44d666d084df33b2f745353d17ee9f780
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlav-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlav-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlav-bad.l b/gas/testsuite/gas/arm/mve-vmlav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..018a8fb5a5d1a0ee528ee8d3eca5491c813d3b5d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlav-bad.l
@@ -0,0 +1,29 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Error: bad type in SIMD instruction -- `vmlav.s64 r0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vmlav.f32 r0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmlava.s64 r0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmlava.f32 r0,q1,q2'
+[^:]*:16: Error: bad instruction `vmlavx.s32 r0,q1,q2'
+[^:]*:17: Error: bad instruction `vmlavax.s32 r0,q1,q2'
+[^:]*:19: Error: syntax error -- `vmlaveq.s32 r0,q1,q2'
+[^:]*:20: Error: syntax error -- `vmlaveq.s32 r0,q1,q2'
+[^:]*:22: Error: syntax error -- `vmlaveq.s32 r0,q1,q2'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vmlavt.s32 r0,q1,q2'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vmlav.s32 r0,q1,q2'
+[^:]*:27: Error: syntax error -- `vmlavaeq.s32 r0,q1,q2'
+[^:]*:28: Error: syntax error -- `vmlavaeq.s32 r0,q1,q2'
+[^:]*:30: Error: syntax error -- `vmlavaeq.s32 r0,q1,q2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vmlavat.s32 r0,q1,q2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vmlava.s32 r0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmlav-bad.s b/gas/testsuite/gas/arm/mve-vmlav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..1359636440bbb931d4103e9b52ad83c9df0102ca
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlav-bad.s
@@ -0,0 +1,33 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond vmlav
+cond vmlava
+vmlav.s64 r0, q1, q2
+vmlav.f32 r0, q1, q2
+vmlava.s64 r0, q1, q2
+vmlava.f32 r0, q1, q2
+vmlavx.s32 r0, q1, q2
+vmlavax.s32 r0, q1, q2
+it eq
+vmlaveq.s32 r0, q1, q2
+vmlaveq.s32 r0, q1, q2
+vpst
+vmlaveq.s32 r0, q1, q2
+vmlavt.s32 r0, q1, q2
+vpst
+vmlav.s32 r0, q1, q2
+it eq
+vmlavaeq.s32 r0, q1, q2
+vmlavaeq.s32 r0, q1, q2
+vpst
+vmlavaeq.s32 r0, q1, q2
+vmlavat.s32 r0, q1, q2
+vpst
+vmlava.s32 r0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmlsdav-bad.d b/gas/testsuite/gas/arm/mve-vmlsdav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..cdcaae982ea6a4b9c571ff4c0ecfd41d117c18e9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsdav-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLSDAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlsdav-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlsdav-bad.l b/gas/testsuite/gas/arm/mve-vmlsdav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..f6270538cdc9289a0bfa8791aa3169caa77b0f2e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsdav-bad.l
@@ -0,0 +1,47 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: Odd register not allowed here -- `vmlsdav.s16 r1,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmlsdav.u16 r0,q1,q2'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vmlsdaveq.s16 r0,q1,q2'
+[^:]*:18: Error: syntax error -- `vmlsdaveq.s16 r0,q1,q2'
+[^:]*:20: Error: syntax error -- `vmlsdaveq.s16 r0,q1,q2'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsdavt.s16 r0,q1,q2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vmlsdav.s16 r0,q1,q2'
+[^:]*:25: Error: syntax error -- `vmlsdavaeq.s16 r0,q1,q2'
+[^:]*:26: Error: syntax error -- `vmlsdavaeq.s16 r0,q1,q2'
+[^:]*:28: Error: syntax error -- `vmlsdavaeq.s16 r0,q1,q2'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsdavat.s16 r0,q1,q2'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vmlsdava.s16 r0,q1,q2'
+[^:]*:33: Error: syntax error -- `vmlsdavxeq.s16 r0,q1,q2'
+[^:]*:34: Error: syntax error -- `vmlsdavxeq.s16 r0,q1,q2'
+[^:]*:36: Error: syntax error -- `vmlsdavxeq.s16 r0,q1,q2'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsdavxt.s16 r0,q1,q2'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vmlsdavx.s16 r0,q1,q2'
+[^:]*:41: Error: syntax error -- `vmlsdavaxeq.s16 r0,q1,q2'
+[^:]*:42: Error: syntax error -- `vmlsdavaxeq.s16 r0,q1,q2'
+[^:]*:44: Error: syntax error -- `vmlsdavaxeq.s16 r0,q1,q2'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsdavaxt.s16 r0,q1,q2'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vmlsdavax.s16 r0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmlsdav-bad.s b/gas/testsuite/gas/arm/mve-vmlsdav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..c955a0db46f91fb06877b56a98435b3e8787a36d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsdav-bad.s
@@ -0,0 +1,47 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmlsdav.s16 r1, q1, q2
+vmlsdav.u16 r0, q1, q2
+cond vmlsdav
+cond vmlsdava
+cond vmlsdavx
+cond vmlsdavax
+it eq
+vmlsdaveq.s16 r0, q1, q2
+vmlsdaveq.s16 r0, q1, q2
+vpst
+vmlsdaveq.s16 r0, q1, q2
+vmlsdavt.s16 r0, q1, q2
+vpst
+vmlsdav.s16 r0, q1, q2
+it eq
+vmlsdavaeq.s16 r0, q1, q2
+vmlsdavaeq.s16 r0, q1, q2
+vpst
+vmlsdavaeq.s16 r0, q1, q2
+vmlsdavat.s16 r0, q1, q2
+vpst
+vmlsdava.s16 r0, q1, q2
+it eq
+vmlsdavxeq.s16 r0, q1, q2
+vmlsdavxeq.s16 r0, q1, q2
+vpst
+vmlsdavxeq.s16 r0, q1, q2
+vmlsdavxt.s16 r0, q1, q2
+vpst
+vmlsdavx.s16 r0, q1, q2
+it eq
+vmlsdavaxeq.s16 r0, q1, q2
+vmlsdavaxeq.s16 r0, q1, q2
+vpst
+vmlsdavaxeq.s16 r0, q1, q2
+vmlsdavaxt.s16 r0, q1, q2
+vpst
+vmlsdavax.s16 r0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t}
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (3 preceding siblings ...)
  2019-05-01 16:57 ` [PATCH 4/57][Arm][GAS] Add support for MVE instructions: vabav, vmladav and vmlsdav Andre Vieira (lists)
@ 2019-05-01 16:59 ` Andre Vieira (lists)
  2019-05-01 17:00 ` [PATCH 6/57][Arm][GAS] Add support for MVE instructions: vst/vld{2,4} Andre Vieira (lists)
                   ` (55 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 16:59 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

Hi,

This patch implements support for the MVE VMULL[BT] instruction.  This 
instruction presents a new challenge to the implementation of GAS as 
depending on architecture the same mnemonic can be split in different 
ways because of condition codes. In a NEON context 'vmullt' should be 
parsed as a 'vmul' instruction with 'lt' condition code, whereas in a 
MVE context this same mnemonic should be parsed as a 'vmullt' instruction.

The way we implement this is to catch any 'vmullt' in 'do_mve_vmull' and 
if we detect we are dealing with a NEON context, we set the correct 
condition code, encoding, and call the neon encoding function.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (BAD_MVE_AUTO): New error message.
	(BAD_MVE_SRCDEST): Likewise.
	(mark_feature_used): Diagnose MVE only instructions
         when in auto-detection mode or -march=all.
	(enum operand_parse_code): Define new operand.
	(parse_operands): Handle new operand.
	(M_MNEM_vmullt, M_MNEM_vmullb): New encodings.
	(mve_encode_qqq): New encoding helper function.
	(do_mve_vmull): New encoding function.
	(insns):
	* testsuite/gas/arm/mve-vmullbt-bad.d: New test.
	* testsuite/gas/arm/mve-vmullbt-bad.l: New test.
	* testsuite/gas/arm/mve-vmullbt-bad.s: New test.

[-- Attachment #2: 5.patch --]
[-- Type: text/x-patch, Size: 9756 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1984cf23b7dc2b32dae1958bfac54eebb55584a0..4db934c8594f6660baff7e21c925d4b819e4ccf5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -890,6 +890,11 @@ struct asm_opcode
 #define MVE_BAD_SP	_("Warning: instruction is UNPREDICTABLE with SP" \
 			  " operand")
 #define BAD_SIMD_TYPE	_("bad type in SIMD instruction")
+#define BAD_MVE_AUTO	\
+  _("GAS auto-detection mode and -march=all is deprecated for MVE, please" \
+    " use a valid -march or -mcpu option.")
+#define BAD_MVE_SRCDEST	_("Warning: 32-bit element size and same destination "\
+			  "and source operands makes instruction UNPREDICTABLE")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -1541,6 +1546,15 @@ record_feature_use (const arm_feature_set *feature)
 static bfd_boolean
 mark_feature_used (const arm_feature_set *feature)
 {
+
+  /* Do not support the use of MVE only instructions when in auto-detection or
+     -march=all.  */
+  if (((feature == &mve_ext) || (feature == &mve_fp_ext))
+      && ARM_CPU_IS_ANY (cpu_variant))
+    {
+      first_error (BAD_MVE_AUTO);
+      return FALSE;
+    }
   /* Ensure the option is valid on the current architecture.  */
   if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
     return FALSE;
@@ -6743,6 +6757,8 @@ enum operand_parse_code
   OP_RR_RNSC,   /* ARM reg or Neon scalar.  */
   OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar.  */
   OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar.  */
+  OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
+		     */
   OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar.  */
   OP_RND_RNSC,  /* Neon D reg, or Neon scalar.  */
   OP_VMOV,      /* Neon VMOV operands.  */
@@ -7094,6 +7110,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  }
 	  break;
 
+	case OP_RNSDQ_RNSC_MQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
+	  break;
+	try_rnsdq_rnsc:
 	case OP_RNSDQ_RNSC:
 	  {
 	    po_scalar_or_goto (8, try_nsdq);
@@ -13836,6 +13856,8 @@ do_t_loloop (void)
 #define M_MNEM_vmlsdava	  0xeef00e21
 #define M_MNEM_vmlsdavx	  0xeef01e01
 #define M_MNEM_vmlsdavax  0xeef01e21
+#define M_MNEM_vmullt	0xee011e00
+#define M_MNEM_vmullb	0xee010e00
 
 /* Neon instruction encoder helpers.  */
 
@@ -15223,6 +15245,23 @@ mve_encode_rqq (unsigned bit28, unsigned size)
   inst.is_neon = 1;
 }
 
+static void
+mve_encode_qqq (int ubit, int size)
+{
+
+  inst.instruction |= (ubit != 0) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= neon_logbits (size) << 20;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[2].reg);
+
+  inst.is_neon = 1;
+}
+
+
 /* Encode insns with bit pattern:
 
   |28/24|23|22 |21 20|19 16|15 12|11    8|7|6|5|4|3  0|
@@ -15941,6 +15980,61 @@ do_neon_qdmulh (void)
     }
 }
 
+static void
+do_mve_vmull (void)
+{
+
+  enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
+					  NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+      && inst.cond == COND_ALWAYS
+      && ((unsigned)inst.instruction) == M_MNEM_vmullt)
+    {
+      if (rs == NS_QQQ)
+	{
+
+	  struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
+						    N_SUF_32 | N_F64 | N_P8
+						    | N_P16 | N_I_MVE | N_KEY);
+	  if (((et.type == NT_poly) && et.size == 8
+	       && ARM_CPU_IS_ANY (cpu_variant))
+	      || (et.type == NT_integer) || (et.type == NT_float))
+	    goto neon_vmul;
+	}
+      else
+	goto neon_vmul;
+    }
+
+  constraint (rs != NS_QQQ, BAD_FPU);
+  struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
+					    N_SU_32 | N_P8 | N_P16 | N_KEY);
+
+  /* We are dealing with MVE's vmullt.  */
+  if (et.size == 32
+      && (inst.operands[0].reg == inst.operands[1].reg
+	  || inst.operands[0].reg == inst.operands[2].reg))
+    as_tsktsk (BAD_MVE_SRCDEST);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (et.type == NT_poly)
+    mve_encode_qqq (neon_logbits (et.size), 64);
+  else
+    mve_encode_qqq (et.type == NT_unsigned, et.size);
+
+  return;
+
+neon_vmul:
+  inst.instruction = N_MNEM_vmul;
+  inst.cond = 0xb;
+  if (thumb_mode)
+    inst.pred_insn_type = INSIDE_IT_INSN;
+  do_neon_mul ();
+}
+
 static void
 do_mve_vabav (void)
 {
@@ -22751,6 +22845,7 @@ static const struct asm_opcode insns[] =
  ToC("vpsteee",	fe712f4d, 0, (), mve_vpt),
 
  /* MVE and MVE FP only.  */
+ mCEF(vmullb,	_vmullb,    3, (RMQ, RMQ, RMQ),			  mve_vmull),
  mCEF(vabav,	_vabav,	    3, (RRnpcsp, RMQ, RMQ),		  mve_vabav),
  mCEF(vmladav,	  _vmladav,	3, (RRe, RMQ, RMQ),		mve_vmladav),
  mCEF(vmladava,	  _vmladava,	3, (RRe, RMQ, RMQ),		mve_vmladav),
@@ -22768,8 +22863,9 @@ static const struct asm_opcode insns[] =
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_v6t2
 
- mnCEF(vadd,     _vadd,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
- mnCEF(vsub,     _vsub,    3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
+ mCEF(vmullt, _vmullt,	3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ),	mve_vmull),
+ mnCEF(vadd,  _vadd,	3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR),	neon_addsub_if_i),
+ mnCEF(vsub,  _vsub,	3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR),	neon_addsub_if_i),
 
  MNCEF(vabs,  1b10300,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
  MNCEF(vneg,  1b10380,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
diff --git a/gas/testsuite/gas/arm/mve-vmullbt-bad.d b/gas/testsuite/gas/arm/mve-vmullbt-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..91cbb1c1b71570595bb64b664489024da0f0722e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmullbt-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMULL instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmullbt-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmullbt-bad.l b/gas/testsuite/gas/arm/mve-vmullbt-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..19f99dcc2ea3b04d1ce7ac656c47c1d08718ef26
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmullbt-bad.l
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vmullb.s64 q0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmullb.f16 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmullb.f32 q0,q1,q2'
+[^:]*:16: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:17: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: bad type in SIMD instruction -- `vmullt.s64 q0,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vmullt.f16 q0,q1,q2'
+[^:]*:21: Error: bad type in SIMD instruction -- `vmullt.f32 q0,q1,q2'
+[^:]*:22: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:23: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:26: Error: syntax error -- `vmullbeq.s32 q0,q1,q2'
+[^:]*:27: Error: syntax error -- `vmullbeq.s32 q0,q1,q2'
+[^:]*:29: Error: syntax error -- `vmullbeq.s32 q0,q1,q2'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vmullb.s32 q0,q1,q2'
+[^:]*:32: Error: vector predicated instruction should be in VPT/VPST block -- `vmullbt.s32 q0,q1,q2'
+[^:]*:34: Error: syntax error -- `vmullteq.s32 q0,q1,q2'
+[^:]*:35: Error: syntax error -- `vmullteq.s32 q0,q1,q2'
+[^:]*:37: Error: syntax error -- `vmullteq.s32 q0,q1,q2'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vmullt.s32 q0,q1,q2'
+[^:]*:40: Error: vector predicated instruction should be in VPT/VPST block -- `vmulltt.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmullbt-bad.s b/gas/testsuite/gas/arm/mve-vmullbt-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..e48269492b65990812abd1e6ab3766dd35723759
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmullbt-bad.s
@@ -0,0 +1,40 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 q0, q1, q2
+.endr
+.endm
+
+
+
+.syntax unified
+.text
+.thumb
+vmullb.s64 q0, q1, q2
+vmullb.f16 q0, q1, q2
+vmullb.f32 q0, q1, q2
+vmullb.s32  q1, q1, q2
+vmullb.s32  q2, q1, q2
+cond vmullb
+vmullt.s64 q0, q1, q2
+vmullt.f16 q0, q1, q2
+vmullt.f32 q0, q1, q2
+vmullt.u32  q1, q1, q2
+vmullt.u32  q2, q1, q2
+cond vmullt
+it eq
+vmullbeq.s32 q0, q1, q2
+vmullbeq.s32 q0, q1, q2
+vpst
+vmullbeq.s32 q0, q1, q2
+vpst
+vmullb.s32 q0, q1, q2
+vmullbt.s32 q0, q1, q2
+it eq
+vmullteq.s32 q0, q1, q2
+vmullteq.s32 q0, q1, q2
+vpst
+vmullteq.s32 q0, q1, q2
+vpst
+vmullt.s32 q0, q1, q2
+vmulltt.s32 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 6/57][Arm][GAS] Add support for MVE instructions: vst/vld{2,4}
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (4 preceding siblings ...)
  2019-05-01 16:59 ` [PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t} Andre Vieira (lists)
@ 2019-05-01 17:00 ` Andre Vieira (lists)
  2019-05-01 17:01 ` [PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr Andre Vieira (lists)
                   ` (54 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:00 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1098 bytes --]

Hi,

This patch adds support for the MVE VLD/VST2[01] and VLD/VST4[0-3] 
instructions.  It reuses NEON's vector list parsing infrastructure with 
some modifications.


gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum it_instruction_type): Add MVE_UNPREDICABLE_INSN.
	(BAD_EL_TYPE): New error message.
	(parse_neon_el_struct_list): Adapt to be able to accept MVE variant.
	(parse_address_main): Likewise.
         (group_reloc_type): Add GROUP_MVE.
	(enum operand_parse_code): Add new operands.
	(parse_operands): Handle new operands.
	(M_MNEM_vst20, M_MNEM_vst21, M_MNEM_vst40, M_MNEM_vst41, M_MNEM_vst42,
         M_MNEM_vst43, M_MNEM_vld20, M_MNEM_vld21, M_MNEM_vld40, 
M_MNEM_vld41,
         M_MNEM_vld42, M_MNEM_vld43): New encodings.
	(do_mve_vst_vld): New encoding function.
	(do_neon_ld_st_interleave): Use BAD_EL_TYPE.
	(it_fsm_pre_encode): Handle new it_instruction_type
	(handle_pred_state):
	* testsuite/gas/arm/mve-vstld-bad.d: New test.
	* testsuite/gas/arm/mve-vstld-bad.l: New test.
	* testsuite/gas/arm/mve-vstld-bad.s: New test.

[-- Attachment #2: 6.patch --]
[-- Type: text/x-patch, Size: 34149 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 4db934c8594f6660baff7e21c925d4b819e4ccf5..2ce9131957617a8279aec9003e44dabe01c90342 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -465,8 +465,9 @@ enum pred_instruction_type
 			      i.e. BKPT and NOP.  */
    IT_INSN,		   /* The IT insn has been parsed.  */
    VPT_INSN,		   /* The VPT/VPST insn has been parsed.  */
-   MVE_OUTSIDE_PRED_INSN   /* Instruction to indicate a MVE instruction without
+   MVE_OUTSIDE_PRED_INSN , /* Instruction to indicate a MVE instruction without
 			      a predication code.  */
+   MVE_UNPREDICABLE_INSN   /* MVE instruction that is non-predicable.  */
 };
 
 /* The maximum number of operands we need.  */
@@ -860,7 +861,7 @@ struct asm_opcode
 #define BAD_OVERLAP	_("registers may not be the same")
 #define BAD_HIREG	_("lo register required")
 #define BAD_THUMB32	_("instruction not supported in Thumb16 mode")
-#define BAD_ADDR_MODE   _("instruction does not accept this addressing mode");
+#define BAD_ADDR_MODE   _("instruction does not accept this addressing mode")
 #define BAD_BRANCH	_("branch must be last instruction in IT block")
 #define BAD_BRANCH_OFF	_("branch out of range or not a multiple of 2")
 #define BAD_NOT_IT	_("instruction not allowed in IT block")
@@ -895,6 +896,7 @@ struct asm_opcode
     " use a valid -march or -mcpu option.")
 #define BAD_MVE_SRCDEST	_("Warning: 32-bit element size and same destination "\
 			  "and source operands makes instruction UNPREDICTABLE")
+#define BAD_EL_TYPE	_("bad element type for instruction")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -2214,6 +2216,7 @@ neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
 
 static int
 parse_neon_el_struct_list (char **str, unsigned *pbase,
+			   int mve,
 			   struct neon_type_el *eltype)
 {
   char *ptr = *str;
@@ -2223,7 +2226,8 @@ parse_neon_el_struct_list (char **str, unsigned *pbase,
   int lane = -1;
   int leading_brace = 0;
   enum arm_reg_type rtype = REG_TYPE_NDQ;
-  const char *const incr_error = _("register stride must be 1 or 2");
+  const char *const incr_error = mve ? _("register stride must be 1") :
+    _("register stride must be 1 or 2");
   const char *const type_error = _("mismatched element/structure types in list");
   struct neon_typed_alias firsttype;
   firsttype.defined = 0;
@@ -2237,6 +2241,8 @@ parse_neon_el_struct_list (char **str, unsigned *pbase,
   do
     {
       struct neon_typed_alias atype;
+      if (mve)
+	rtype = REG_TYPE_MQ;
       int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
 
       if (getreg == FAIL)
@@ -2344,7 +2350,7 @@ parse_neon_el_struct_list (char **str, unsigned *pbase,
     lane = NEON_INTERLEAVE_LANES;
 
   /* Sanity check.  */
-  if (lane == -1 || base_reg == -1 || count < 1 || count > 4
+  if (lane == -1 || base_reg == -1 || count < 1 || (!mve && count > 4)
       || (count > 1 && reg_incr == -1))
     {
       first_error (_("error parsing element/structure list"));
@@ -5489,7 +5495,8 @@ typedef enum
 
   GROUP_LDR,
   GROUP_LDRS,
-  GROUP_LDC
+  GROUP_LDC,
+  GROUP_MVE
 } group_reloc_type;
 
 static struct group_reloc_table_entry group_reloc_table[] =
@@ -5742,7 +5749,10 @@ parse_address_main (char **str, int i, int group_relocations,
 
   if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
     {
-      inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
+      if (group_type == GROUP_MVE)
+	inst.error = BAD_ADDR_MODE;
+      else
+	inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
       return PARSE_OPERAND_FAIL;
     }
   inst.operands[i].reg = reg;
@@ -6750,6 +6760,8 @@ enum operand_parse_code
   OP_NRDLST,    /* Neon double-precision register list (d0-d31, qN aliases) */
   OP_NSTRLST,   /* Neon element/structure list */
   OP_VRSDVLST,  /* VFP single or double-precision register list and VPR */
+  OP_MSTRLST2,	/* MVE vector list with two elements.  */
+  OP_MSTRLST4,	/* MVE vector list with four elements.  */
 
   OP_RNDQ_I0,   /* Neon D or Q reg, or immediate zero.  */
   OP_RVSD_I0,	/* VFP S or D reg, or immediate zero.  */
@@ -6790,6 +6802,7 @@ enum operand_parse_code
   OP_SH,	/* shifter operand */
   OP_SHG,	/* shifter operand with possible group relocation */
   OP_ADDR,	/* Memory address expression (any mode) */
+  OP_ADDRMVE,	/* Memory address expression for MVE's VSTR/VLDR.  */
   OP_ADDRGLDR,	/* Mem addr expr (any mode) with possible LDR group reloc */
   OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
   OP_ADDRGLDC,  /* Mem addr expr (any mode) with possible LDC group reloc */
@@ -7473,12 +7486,23 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 				    REGLIST_NEON_D, &partial_match);
 	  break;
 
+	case OP_MSTRLST4:
+	case OP_MSTRLST2:
+	  val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
+					   1, &inst.operands[i].vectype);
+	  if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
+	    goto failure;
+	  break;
 	case OP_NSTRLST:
 	  val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
-					   &inst.operands[i].vectype);
+					   0, &inst.operands[i].vectype);
 	  break;
 
 	  /* Addressing modes */
+	case OP_ADDRMVE:
+	  po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
+	  break;
+
 	case OP_ADDR:
 	  po_misc_or_fail (parse_address (&str, i));
 	  break;
@@ -7581,6 +7605,8 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_VRSDVLST:
 	case OP_NRDLST:
 	case OP_NSTRLST:
+	case OP_MSTRLST2:
+	case OP_MSTRLST4:
 	  if (val == FAIL)
 	    goto failure;
 	  inst.operands[i].imm = val;
@@ -13858,6 +13884,18 @@ do_t_loloop (void)
 #define M_MNEM_vmlsdavax  0xeef01e21
 #define M_MNEM_vmullt	0xee011e00
 #define M_MNEM_vmullb	0xee010e00
+#define M_MNEM_vst20	0xfc801e00
+#define M_MNEM_vst21	0xfc801e20
+#define M_MNEM_vst40	0xfc801e01
+#define M_MNEM_vst41	0xfc801e21
+#define M_MNEM_vst42	0xfc801e41
+#define M_MNEM_vst43	0xfc801e61
+#define M_MNEM_vld20	0xfc901e00
+#define M_MNEM_vld21	0xfc901e20
+#define M_MNEM_vld40	0xfc901e01
+#define M_MNEM_vld41	0xfc901e21
+#define M_MNEM_vld42	0xfc901e41
+#define M_MNEM_vld43	0xfc901e61
 
 /* Neon instruction encoder helpers.  */
 
@@ -15705,6 +15743,44 @@ check_simd_pred_availability (int fp, unsigned check)
   return 0;
 }
 
+static void
+do_mve_vst_vld (void)
+{
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    return;
+
+  constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
+	      || inst.relocs[0].exp.X_add_number != 0
+	      || inst.operands[1].immisreg != 0,
+	      BAD_ADDR_MODE);
+  constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
+  if (inst.operands[1].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+  else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
+    as_tsktsk (MVE_BAD_SP);
+
+
+  /* These instructions are one of the "exceptions" mentioned in
+     handle_pred_state.  They are MVE instructions that are not VPT compatible
+     and do not accept a VPT code, thus appending such a code is a syntax
+     error.  */
+  if (inst.cond > COND_ALWAYS)
+    first_error (BAD_SYNTAX);
+  /* If we append a scalar condition code we can set this to
+     MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error.  */
+  else if (inst.cond < COND_ALWAYS)
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+  else
+    inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
+
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= inst.operands[1].writeback << 21;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
+  inst.is_neon = 1;
+}
+
 static void
 do_neon_dyadic_if_su (void)
 {
@@ -18011,7 +18087,7 @@ do_neon_ld_st_interleave (void)
 
   constraint (typebits == -1, _("bad list type for instruction"));
   constraint (((inst.instruction >> 8) & 3) && et.size == 64,
-	      _("bad element type for instruction"));
+	      BAD_EL_TYPE);
 
   inst.instruction &= ~0xf00;
   inst.instruction |= typebits << 8;
@@ -19374,7 +19450,7 @@ it_fsm_pre_encode (void)
    Specifications say that any non-MVE instruction inside a VPT block is
    UNPREDICTABLE, with the exception of the BKPT instruction.  Whereas most MVE
    instructions are deemed to be UNPREDICTABLE if inside an IT block.  For the
-   few exceptions this will be handled at their respective handler functions.
+   few exceptions we have MVE_UNPREDICABLE_INSN.
    The error messages provided depending on the different combinations possible
    are described in the cases below:
    For 'most' MVE instructions:
@@ -19411,6 +19487,7 @@ handle_pred_state (void)
     case OUTSIDE_PRED_BLOCK:
       switch (inst.pred_insn_type)
 	{
+	case MVE_UNPREDICABLE_INSN:
 	case MVE_OUTSIDE_PRED_INSN:
 	  if (inst.cond < COND_ALWAYS)
 	    {
@@ -19510,6 +19587,7 @@ handle_pred_state (void)
 	{
 	case INSIDE_VPT_INSN:
 	case VPT_INSN:
+	case MVE_UNPREDICABLE_INSN:
 	case MVE_OUTSIDE_PRED_INSN:
 	  gas_assert (0);
 	case OUTSIDE_PRED_INSN:
@@ -19659,6 +19737,9 @@ handle_pred_state (void)
 		    gas_assert (0);
 		  }
 	      }
+	  case MVE_UNPREDICABLE_INSN:
+	    as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
+	    return SUCCESS;
 	  case INSIDE_IT_INSN:
 	    if (inst.cond > COND_ALWAYS)
 	      {
@@ -22858,6 +22939,19 @@ static const struct asm_opcode insns[] =
  mCEF(vmlsdavx,	  _vmlsdavx,	3, (RRe, RMQ, RMQ),		mve_vmladav),
  mCEF(vmlsdavax,  _vmlsdavax,	3, (RRe, RMQ, RMQ),		mve_vmladav),
 
+ mCEF(vst20,	_vst20,	    2, (MSTRLST2, ADDRMVE),		mve_vst_vld),
+ mCEF(vst21,	_vst21,	    2, (MSTRLST2, ADDRMVE),		mve_vst_vld),
+ mCEF(vst40,	_vst40,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vst41,	_vst41,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vst42,	_vst42,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vst43,	_vst43,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vld20,	_vld20,	    2, (MSTRLST2, ADDRMVE),		mve_vst_vld),
+ mCEF(vld21,	_vld21,	    2, (MSTRLST2, ADDRMVE),		mve_vst_vld),
+ mCEF(vld40,	_vld40,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vld41,	_vld41,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vld42,	_vld42,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vld43,	_vld43,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT    & fpu_vfp_ext_v1xd
 #undef  THUMB_VARIANT
diff --git a/gas/testsuite/gas/arm/mve-vstld-bad.d b/gas/testsuite/gas/arm/mve-vstld-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..92b9c929ba0f15e8954cd6b2743d1805b4e14fd7
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstld-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VST2/4 VLD2/4 instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vstld-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vstld-bad.l b/gas/testsuite/gas/arm/mve-vstld-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..3ea47d52728b2e932c601659a3dbd9d7c8d0725f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstld-bad.l
@@ -0,0 +1,249 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: register stride must be 1 -- `vst20.8 {q0,q2},\[r0\]'
+[^:]*:4: Error: syntax error -- `vst20.8 {q0,q1,q2},\[r0\]'
+[^:]*:5: Error: syntax error -- `vst20.8 {q0},\[r0\]'
+[^:]*:6: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:7: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:8: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:9: Error: register stride must be 1 -- `vst20.8 {q3,q2},\[r0\]'
+[^:]*:10: Error: bad element type for instruction -- `vst20.64 {q0,q1},\[r0\]'
+[^:]*:11: Error: register stride must be 1 -- `vst21.8 {q0,q2},\[r0\]'
+[^:]*:12: Error: syntax error -- `vst21.8 {q0,q1,q2},\[r0\]'
+[^:]*:13: Error: syntax error -- `vst21.8 {q0},\[r0\]'
+[^:]*:14: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:15: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:16: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Error: register stride must be 1 -- `vst21.8 {q3,q2},\[r0\]'
+[^:]*:18: Error: bad element type for instruction -- `vst21.64 {q0,q1},\[r0\]'
+[^:]*:19: Error: register stride must be 1 -- `vst40.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:20: Error: register stride must be 1 -- `vst40.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:21: Error: register stride must be 1 -- `vst40.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:22: Error: register stride must be 1 -- `vst40.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:23: Error: syntax error -- `vst40.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:24: Error: syntax error -- `vst40.8 {q0,q1,q2},\[r0\]'
+[^:]*:25: Error: syntax error -- `vst40.8 {q0,q1},\[r0\]'
+[^:]*:26: Error: syntax error -- `vst40.8 {q0},\[r0\]'
+[^:]*:27: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:28: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:29: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:30: Error: bad element type for instruction -- `vst40.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:31: Error: register stride must be 1 -- `vst41.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:32: Error: register stride must be 1 -- `vst41.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:33: Error: register stride must be 1 -- `vst41.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:34: Error: register stride must be 1 -- `vst41.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:35: Error: syntax error -- `vst41.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:36: Error: syntax error -- `vst41.8 {q0,q1,q2},\[r0\]'
+[^:]*:37: Error: syntax error -- `vst41.8 {q0,q1},\[r0\]'
+[^:]*:38: Error: syntax error -- `vst41.8 {q0},\[r0\]'
+[^:]*:39: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:40: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:41: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:42: Error: bad element type for instruction -- `vst41.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:43: Error: register stride must be 1 -- `vst42.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:44: Error: register stride must be 1 -- `vst42.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:45: Error: register stride must be 1 -- `vst42.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:46: Error: register stride must be 1 -- `vst42.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:47: Error: syntax error -- `vst42.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:48: Error: syntax error -- `vst42.8 {q0,q1,q2},\[r0\]'
+[^:]*:49: Error: syntax error -- `vst42.8 {q0,q1},\[r0\]'
+[^:]*:50: Error: syntax error -- `vst42.8 {q0},\[r0\]'
+[^:]*:51: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:52: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:53: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:54: Error: bad element type for instruction -- `vst42.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:55: Error: register stride must be 1 -- `vst43.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:56: Error: register stride must be 1 -- `vst43.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:57: Error: register stride must be 1 -- `vst43.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:58: Error: register stride must be 1 -- `vst43.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:59: Error: syntax error -- `vst43.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:60: Error: syntax error -- `vst43.8 {q0,q1,q2},\[r0\]'
+[^:]*:61: Error: syntax error -- `vst43.8 {q0,q1},\[r0\]'
+[^:]*:62: Error: syntax error -- `vst43.8 {q0},\[r0\]'
+[^:]*:63: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:64: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:65: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:66: Error: bad element type for instruction -- `vst43.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:67: Error: selected processor does not support `vst1.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:68: Error: selected processor does not support `vst2.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:69: Error: selected processor does not support `vst3.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:70: Error: selected processor does not support `vst4.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:71: Error: bad instruction `vst23.32 {q0,q1},\[r0\]'
+[^:]*:72: Error: bad instruction `vst44.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:73: Error: register stride must be 1 -- `vld20.8 {q0,q2},\[r0\]'
+[^:]*:74: Error: syntax error -- `vld20.8 {q0,q1,q2},\[r0\]'
+[^:]*:75: Error: syntax error -- `vld20.8 {q0},\[r0\]'
+[^:]*:76: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:77: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:78: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:79: Error: register stride must be 1 -- `vld20.8 {q3,q2},\[r0\]'
+[^:]*:80: Error: bad element type for instruction -- `vld20.64 {q0,q1},\[r0\]'
+[^:]*:81: Error: register stride must be 1 -- `vld21.8 {q0,q2},\[r0\]'
+[^:]*:82: Error: syntax error -- `vld21.8 {q0,q1,q2},\[r0\]'
+[^:]*:83: Error: syntax error -- `vld21.8 {q0},\[r0\]'
+[^:]*:84: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:85: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:86: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:87: Error: register stride must be 1 -- `vld21.8 {q3,q2},\[r0\]'
+[^:]*:88: Error: bad element type for instruction -- `vld21.64 {q0,q1},\[r0\]'
+[^:]*:89: Error: register stride must be 1 -- `vld40.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:90: Error: register stride must be 1 -- `vld40.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:91: Error: register stride must be 1 -- `vld40.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:92: Error: register stride must be 1 -- `vld40.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:93: Error: syntax error -- `vld40.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:94: Error: syntax error -- `vld40.8 {q0,q1,q2},\[r0\]'
+[^:]*:95: Error: syntax error -- `vld40.8 {q0,q1},\[r0\]'
+[^:]*:96: Error: syntax error -- `vld40.8 {q0},\[r0\]'
+[^:]*:97: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:98: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:99: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:100: Error: bad element type for instruction -- `vld40.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:101: Error: register stride must be 1 -- `vld41.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:102: Error: register stride must be 1 -- `vld41.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:103: Error: register stride must be 1 -- `vld41.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:104: Error: register stride must be 1 -- `vld41.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:105: Error: syntax error -- `vld41.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:106: Error: syntax error -- `vld41.8 {q0,q1,q2},\[r0\]'
+[^:]*:107: Error: syntax error -- `vld41.8 {q0,q1},\[r0\]'
+[^:]*:108: Error: syntax error -- `vld41.8 {q0},\[r0\]'
+[^:]*:109: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:110: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:111: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:112: Error: bad element type for instruction -- `vld41.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:113: Error: register stride must be 1 -- `vld42.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:114: Error: register stride must be 1 -- `vld42.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:115: Error: register stride must be 1 -- `vld42.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:116: Error: register stride must be 1 -- `vld42.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:117: Error: syntax error -- `vld42.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:118: Error: syntax error -- `vld42.8 {q0,q1,q2},\[r0\]'
+[^:]*:119: Error: syntax error -- `vld42.8 {q0,q1},\[r0\]'
+[^:]*:120: Error: syntax error -- `vld42.8 {q0},\[r0\]'
+[^:]*:121: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:122: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:123: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:124: Error: bad element type for instruction -- `vld42.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:125: Error: register stride must be 1 -- `vld43.8 {q0,q2,q3,q4},\[r0\]'
+[^:]*:126: Error: register stride must be 1 -- `vld43.8 {q0,q1,q3,q4},\[r0\]'
+[^:]*:127: Error: register stride must be 1 -- `vld43.8 {q0,q1,q2,q4},\[r0\]'
+[^:]*:128: Error: register stride must be 1 -- `vld43.8 {q3,q1,q2,q3},\[r0\]'
+[^:]*:129: Error: syntax error -- `vld43.8 {q0,q1,q2,q3,q4},\[r0\]'
+[^:]*:130: Error: syntax error -- `vld43.8 {q0,q1,q2},\[r0\]'
+[^:]*:131: Error: syntax error -- `vld43.8 {q0,q1},\[r0\]'
+[^:]*:132: Error: syntax error -- `vld43.8 {q0},\[r0\]'
+[^:]*:133: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:134: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:135: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:136: Error: bad element type for instruction -- `vld43.64 {q0,q1,q2,q3},\[r0\]'
+[^:]*:137: Error: selected processor does not support `vld1.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:138: Error: selected processor does not support `vld2.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:139: Error: selected processor does not support `vld3.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:140: Error: selected processor does not support `vld4.8 {q0,q1},\[r0\]' in Thumb mode
+[^:]*:141: Error: bad instruction `vld23.32 {q0,q1},\[r0\]'
+[^:]*:142: Error: bad instruction `vld44.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:160: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:161: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:162: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:163: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:164: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:165: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:167: Error: syntax error -- `vst20t.32 {q0,q1},\[r0\]'
+[^:]*:168: Error: syntax error -- `vst20e.32 {q0,q1},\[r0\]'
+[^:]*:170: Error: syntax error -- `vst21t.32 {q0,q1},\[r0\]'
+[^:]*:171: Error: syntax error -- `vst21e.32 {q0,q1},\[r0\]'
+[^:]*:173: Error: syntax error -- `vst40t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:174: Error: syntax error -- `vst40e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:176: Error: syntax error -- `vst41t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:177: Error: syntax error -- `vst41e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:179: Error: syntax error -- `vst42t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:180: Error: syntax error -- `vst42e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:182: Error: syntax error -- `vst43t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:183: Error: syntax error -- `vst43e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:186: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:188: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:190: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:192: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:194: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:196: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:198: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:199: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:200: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:201: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:202: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:203: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:205: Error: syntax error -- `vld20t.32 {q0,q1},\[r0\]'
+[^:]*:206: Error: syntax error -- `vld20e.32 {q0,q1},\[r0\]'
+[^:]*:208: Error: syntax error -- `vld21t.32 {q0,q1},\[r0\]'
+[^:]*:209: Error: syntax error -- `vld21e.32 {q0,q1},\[r0\]'
+[^:]*:211: Error: syntax error -- `vld40t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:212: Error: syntax error -- `vld40e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:214: Error: syntax error -- `vld41t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:215: Error: syntax error -- `vld41e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:217: Error: syntax error -- `vld42t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:218: Error: syntax error -- `vld42e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:220: Error: syntax error -- `vld43t.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:221: Error: syntax error -- `vld43e.32 {q0,q1,q2,q3},\[r0\]'
+[^:]*:224: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:226: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:228: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:230: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:232: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:234: Warning: instruction is UNPREDICTABLE in a VPT block
diff --git a/gas/testsuite/gas/arm/mve-vstld-bad.s b/gas/testsuite/gas/arm/mve-vstld-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..1a8b0b11f08e150369c918ddf91e1dec7721f1c8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstld-bad.s
@@ -0,0 +1,234 @@
+.syntax unified
+.thumb
+vst20.8 {q0, q2}, [r0]
+vst20.8 {q0, q1, q2}, [r0]
+vst20.8 {q0}, [r0]
+vst20.8 {q0, q1}, [pc]
+vst20.8 {q0, q1}, [pc]!
+vst20.8 {q0, q1}, [sp]!
+vst20.8 {q3, q2}, [r0]
+vst20.64 {q0, q1}, [r0]
+vst21.8 {q0, q2}, [r0]
+vst21.8 {q0, q1, q2}, [r0]
+vst21.8 {q0}, [r0]
+vst21.8 {q0, q1}, [pc]
+vst21.8 {q0, q1}, [pc]!
+vst21.8 {q0, q1}, [sp]!
+vst21.8 {q3, q2}, [r0]
+vst21.64 {q0, q1}, [r0]
+vst40.8 {q0, q2, q3, q4}, [r0]
+vst40.8 {q0, q1, q3, q4}, [r0]
+vst40.8 {q0, q1, q2, q4}, [r0]
+vst40.8 {q3, q1, q2, q3}, [r0]
+vst40.8 {q0, q1, q2, q3, q4}, [r0]
+vst40.8 {q0, q1, q2}, [r0]
+vst40.8 {q0, q1}, [r0]
+vst40.8 {q0}, [r0]
+vst40.8 {q0, q1, q2, q3}, [pc]
+vst40.8 {q0, q1, q2, q3}, [pc]!
+vst40.8 {q0, q1, q2, q3}, [sp]!
+vst40.64 {q0, q1, q2, q3}, [r0]
+vst41.8 {q0, q2, q3, q4}, [r0]
+vst41.8 {q0, q1, q3, q4}, [r0]
+vst41.8 {q0, q1, q2, q4}, [r0]
+vst41.8 {q3, q1, q2, q3}, [r0]
+vst41.8 {q0, q1, q2, q3, q4}, [r0]
+vst41.8 {q0, q1, q2}, [r0]
+vst41.8 {q0, q1}, [r0]
+vst41.8 {q0}, [r0]
+vst41.8 {q0, q1, q2, q3}, [pc]
+vst41.8 {q0, q1, q2, q3}, [pc]!
+vst41.8 {q0, q1, q2, q3}, [sp]!
+vst41.64 {q0, q1, q2, q3}, [r0]
+vst42.8 {q0, q2, q3, q4}, [r0]
+vst42.8 {q0, q1, q3, q4}, [r0]
+vst42.8 {q0, q1, q2, q4}, [r0]
+vst42.8 {q3, q1, q2, q3}, [r0]
+vst42.8 {q0, q1, q2, q3, q4}, [r0]
+vst42.8 {q0, q1, q2}, [r0]
+vst42.8 {q0, q1}, [r0]
+vst42.8 {q0}, [r0]
+vst42.8 {q0, q1, q2, q3}, [pc]
+vst42.8 {q0, q1, q2, q3}, [pc]!
+vst42.8 {q0, q1, q2, q3}, [sp]!
+vst42.64 {q0, q1, q2, q3}, [r0]
+vst43.8 {q0, q2, q3, q4}, [r0]
+vst43.8 {q0, q1, q3, q4}, [r0]
+vst43.8 {q0, q1, q2, q4}, [r0]
+vst43.8 {q3, q1, q2, q3}, [r0]
+vst43.8 {q0, q1, q2, q3, q4}, [r0]
+vst43.8 {q0, q1, q2}, [r0]
+vst43.8 {q0, q1}, [r0]
+vst43.8 {q0}, [r0]
+vst43.8 {q0, q1, q2, q3}, [pc]
+vst43.8 {q0, q1, q2, q3}, [pc]!
+vst43.8 {q0, q1, q2, q3}, [sp]!
+vst43.64 {q0, q1, q2, q3}, [r0]
+vst1.8 {q0, q1}, [r0]
+vst2.8 {q0, q1}, [r0]
+vst3.8 {q0, q1}, [r0]
+vst4.8 {q0, q1}, [r0]
+vst23.32 {q0, q1}, [r0]
+vst44.32 {q0, q1, q2, q3}, [r0]
+vld20.8 {q0, q2}, [r0]
+vld20.8 {q0, q1, q2}, [r0]
+vld20.8 {q0}, [r0]
+vld20.8 {q0, q1}, [pc]
+vld20.8 {q0, q1}, [pc]!
+vld20.8 {q0, q1}, [sp]!
+vld20.8 {q3, q2}, [r0]
+vld20.64 {q0, q1}, [r0]
+vld21.8 {q0, q2}, [r0]
+vld21.8 {q0, q1, q2}, [r0]
+vld21.8 {q0}, [r0]
+vld21.8 {q0, q1}, [pc]
+vld21.8 {q0, q1}, [pc]!
+vld21.8 {q0, q1}, [sp]!
+vld21.8 {q3, q2}, [r0]
+vld21.64 {q0, q1}, [r0]
+vld40.8 {q0, q2, q3, q4}, [r0]
+vld40.8 {q0, q1, q3, q4}, [r0]
+vld40.8 {q0, q1, q2, q4}, [r0]
+vld40.8 {q3, q1, q2, q3}, [r0]
+vld40.8 {q0, q1, q2, q3, q4}, [r0]
+vld40.8 {q0, q1, q2}, [r0]
+vld40.8 {q0, q1}, [r0]
+vld40.8 {q0}, [r0]
+vld40.8 {q0, q1, q2, q3}, [pc]
+vld40.8 {q0, q1, q2, q3}, [pc]!
+vld40.8 {q0, q1, q2, q3}, [sp]!
+vld40.64 {q0, q1, q2, q3}, [r0]
+vld41.8 {q0, q2, q3, q4}, [r0]
+vld41.8 {q0, q1, q3, q4}, [r0]
+vld41.8 {q0, q1, q2, q4}, [r0]
+vld41.8 {q3, q1, q2, q3}, [r0]
+vld41.8 {q0, q1, q2, q3, q4}, [r0]
+vld41.8 {q0, q1, q2}, [r0]
+vld41.8 {q0, q1}, [r0]
+vld41.8 {q0}, [r0]
+vld41.8 {q0, q1, q2, q3}, [pc]
+vld41.8 {q0, q1, q2, q3}, [pc]!
+vld41.8 {q0, q1, q2, q3}, [sp]!
+vld41.64 {q0, q1, q2, q3}, [r0]
+vld42.8 {q0, q2, q3, q4}, [r0]
+vld42.8 {q0, q1, q3, q4}, [r0]
+vld42.8 {q0, q1, q2, q4}, [r0]
+vld42.8 {q3, q1, q2, q3}, [r0]
+vld42.8 {q0, q1, q2, q3, q4}, [r0]
+vld42.8 {q0, q1, q2}, [r0]
+vld42.8 {q0, q1}, [r0]
+vld42.8 {q0}, [r0]
+vld42.8 {q0, q1, q2, q3}, [pc]
+vld42.8 {q0, q1, q2, q3}, [pc]!
+vld42.8 {q0, q1, q2, q3}, [sp]!
+vld42.64 {q0, q1, q2, q3}, [r0]
+vld43.8 {q0, q2, q3, q4}, [r0]
+vld43.8 {q0, q1, q3, q4}, [r0]
+vld43.8 {q0, q1, q2, q4}, [r0]
+vld43.8 {q3, q1, q2, q3}, [r0]
+vld43.8 {q0, q1, q2, q3, q4}, [r0]
+vld43.8 {q0, q1, q2}, [r0]
+vld43.8 {q0, q1}, [r0]
+vld43.8 {q0}, [r0]
+vld43.8 {q0, q1, q2, q3}, [pc]
+vld43.8 {q0, q1, q2, q3}, [pc]!
+vld43.8 {q0, q1, q2, q3}, [sp]!
+vld43.64 {q0, q1, q2, q3}, [r0]
+vld1.8 {q0, q1}, [r0]
+vld2.8 {q0, q1}, [r0]
+vld3.8 {q0, q1}, [r0]
+vld4.8 {q0, q1}, [r0]
+vld23.32 {q0, q1}, [r0]
+vld44.32 {q0, q1, q2, q3}, [r0]
+
+.macro cond2 op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().32  {q0, q1}, [r0]
+.endr
+.endm
+
+
+
+.macro cond4 op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().32 {q0, q1, q2, q3}, [r0]
+.endr
+.endm
+
+cond2 vst20
+cond2 vst21
+cond4 vst40
+cond4 vst41
+cond4 vst42
+cond4 vst43
+vpste
+vst20t.32 {q0, q1}, [r0]
+vst20e.32 {q0, q1}, [r0]
+vpste
+vst21t.32 {q0, q1}, [r0]
+vst21e.32 {q0, q1}, [r0]
+vpste
+vst40t.32 {q0, q1, q2, q3}, [r0]
+vst40e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vst41t.32 {q0, q1, q2, q3}, [r0]
+vst41e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vst42t.32 {q0, q1, q2, q3}, [r0]
+vst42e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vst43t.32 {q0, q1, q2, q3}, [r0]
+vst43e.32 {q0, q1, q2, q3}, [r0]
+
+vpst
+vst20.32 {q0, q1}, [r0]
+vpst
+vst21.32 {q0, q1}, [r0]
+vpst
+vst40.32 {q0, q1, q2, q3}, [r0]
+vpst
+vst41.32 {q0, q1, q2, q3}, [r0]
+vpst
+vst42.32 {q0, q1, q2, q3}, [r0]
+vpst
+vst43.32 {q0, q1, q2, q3}, [r0]
+
+cond2 vld20
+cond2 vld21
+cond4 vld40
+cond4 vld41
+cond4 vld42
+cond4 vld43
+vpste
+vld20t.32 {q0, q1}, [r0]
+vld20e.32 {q0, q1}, [r0]
+vpste
+vld21t.32 {q0, q1}, [r0]
+vld21e.32 {q0, q1}, [r0]
+vpste
+vld40t.32 {q0, q1, q2, q3}, [r0]
+vld40e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vld41t.32 {q0, q1, q2, q3}, [r0]
+vld41e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vld42t.32 {q0, q1, q2, q3}, [r0]
+vld42e.32 {q0, q1, q2, q3}, [r0]
+vpste
+vld43t.32 {q0, q1, q2, q3}, [r0]
+vld43e.32 {q0, q1, q2, q3}, [r0]
+
+vpst
+vld20.32 {q0, q1}, [r0]
+vpst
+vld21.32 {q0, q1}, [r0]
+vpst
+vld40.32 {q0, q1, q2, q3}, [r0]
+vpst
+vld41.32 {q0, q1, q2, q3}, [r0]
+vpst
+vld42.32 {q0, q1, q2, q3}, [r0]
+vpst
+vld43.32 {q0, q1, q2, q3}, [r0]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (5 preceding siblings ...)
  2019-05-01 17:00 ` [PATCH 6/57][Arm][GAS] Add support for MVE instructions: vst/vld{2,4} Andre Vieira (lists)
@ 2019-05-01 17:01 ` Andre Vieira (lists)
  2019-05-01 17:02 ` [PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt Andre Vieira (lists)
                   ` (53 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:01 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1689 bytes --]

Hi,

This patch implements support for all vldr/vstr MVE variants, including 
the gather loads and scatter stores.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (struct arm_it): Make immisreg
         field larger to hold type of register.
	(enum shift_kind): Add SHIFT_UXTW shift kind.
	(enum parse_shift_mode): Add SHIFT_UXTW_IMMEDIATE
         shift mode.
	(parse_shift): Handle new shift type.
	(parse_address_main): Accept new addressing modes.
	(M_MNEM_vstrb, M_MNEM_vstrh, M_MNEM_vstrw, M_MNEM_vstrd,
         M_MNEM_vldrb, M_MNEM_vldrh, M_MNEM_vldrw, M_MNEM_vldrd):
         New instruction encodings.
	(do_mve_vstr_vldr_QI): New encoding functions.
	(do_mve_vstr_vldr_RQ): Likewise.
	(do_mve_vstr_vldr_RI): Likewise.
	(do_mve_vstr_vldr): Likewise.
	* testsuite/gas/arm/mve-vldr-bad-1.d: New test.
	* testsuite/gas/arm/mve-vldr-bad-1.l: New test.
	* testsuite/gas/arm/mve-vldr-bad-1.s: New test.
	* testsuite/gas/arm/mve-vldr-bad-2.d: New test.
	* testsuite/gas/arm/mve-vldr-bad-2.l: New test.
	* testsuite/gas/arm/mve-vldr-bad-2.s: New test.
	* testsuite/gas/arm/mve-vldr-bad-3.d: New test.
	* testsuite/gas/arm/mve-vldr-bad-3.l: New test.
	* testsuite/gas/arm/mve-vldr-bad-3.s: New test.
	* testsuite/gas/arm/mve-vstr-bad-1.d: New test.
	* testsuite/gas/arm/mve-vstr-bad-1.l: New test.
	* testsuite/gas/arm/mve-vstr-bad-1.s: New test.
	* testsuite/gas/arm/mve-vstr-bad-2.d: New test.
	* testsuite/gas/arm/mve-vstr-bad-2.l: New test.
	* testsuite/gas/arm/mve-vstr-bad-2.s: New test.
	* testsuite/gas/arm/mve-vstr-bad-3.d: New test.
	* testsuite/gas/arm/mve-vstr-bad-3.l: New test.
	* testsuite/gas/arm/mve-vstr-bad-3.s: New test.

[-- Attachment #2: 7.patch --]
[-- Type: text/x-patch, Size: 77820 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 9cd32e674fce72ed0688c926a24aa728e0061b47..43de8df18357bbdd46a419d31d43b46de1ed52be 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -508,7 +508,8 @@ struct arm_it
     struct neon_type_el vectype;
     unsigned present	: 1;  /* Operand present.  */
     unsigned isreg	: 1;  /* Operand was a register.  */
-    unsigned immisreg	: 1;  /* .imm field is a second register.  */
+    unsigned immisreg	: 2;  /* .imm field is a second register.
+				 0: imm, 1: gpr, 2: MVE Q-register.  */
     unsigned isscalar   : 1;  /* Operand is a (Neon) scalar.  */
     unsigned immisalign : 1;  /* Immediate is an alignment specifier.  */
     unsigned immisfloat : 1;  /* Immediate was parsed as a float.  */
@@ -5292,7 +5293,7 @@ parse_qfloat_immediate (char **ccp, int *immed)
 /* Shift operands.  */
 enum shift_kind
 {
-  SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
+  SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
 };
 
 struct asm_shift_name
@@ -5309,6 +5310,7 @@ enum parse_shift_mode
   SHIFT_LSL_OR_ASR_IMMEDIATE,	/* Shift must be LSL or ASR immediate.	*/
   SHIFT_ASR_IMMEDIATE,		/* Shift must be ASR immediate.	 */
   SHIFT_LSL_IMMEDIATE,		/* Shift must be LSL immediate.	 */
+  SHIFT_UXTW_IMMEDIATE		/* Shift must be UXTW immediate.  */
 };
 
 /* Parse a <shift> specifier on an ARM data processing instruction.
@@ -5353,7 +5355,13 @@ parse_shift (char **str, int i, enum parse_shift_mode mode)
   switch (mode)
     {
     case NO_SHIFT_RESTRICT:
-    case SHIFT_IMMEDIATE:   break;
+    case SHIFT_IMMEDIATE:
+      if (shift == SHIFT_UXTW)
+	{
+	  inst.error = _("'UXTW' not allowed here");
+	  return FAIL;
+	}
+      break;
 
     case SHIFT_LSL_OR_ASR_IMMEDIATE:
       if (shift != SHIFT_LSL && shift != SHIFT_ASR)
@@ -5378,6 +5386,13 @@ parse_shift (char **str, int i, enum parse_shift_mode mode)
 	  return FAIL;
 	}
       break;
+    case SHIFT_UXTW_IMMEDIATE:
+      if (shift != SHIFT_UXTW)
+	{
+	  inst.error = _("'UXTW' required");
+	  return FAIL;
+	}
+      break;
 
     default: abort ();
     }
@@ -5747,7 +5762,21 @@ parse_address_main (char **str, int i, int group_relocations,
   /* PR gas/14887: Allow for whitespace after the opening bracket.  */
   skip_whitespace (p);
 
-  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+  if (group_type == GROUP_MVE)
+    {
+      enum arm_reg_type rtype = REG_TYPE_MQ;
+      struct neon_type_el et;
+      if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
+	{
+	  inst.operands[i].isquad = 1;
+	}
+      else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+	{
+	  inst.error = BAD_ADDR_MODE;
+	  return PARSE_OPERAND_FAIL;
+	}
+    }
+  else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
     {
       if (group_type == GROUP_MVE)
 	inst.error = BAD_ADDR_MODE;
@@ -5765,7 +5794,26 @@ parse_address_main (char **str, int i, int group_relocations,
       if (*p == '+') p++;
       else if (*p == '-') p++, inst.operands[i].negative = 1;
 
-      if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
+      enum arm_reg_type rtype = REG_TYPE_MQ;
+      struct neon_type_el et;
+      if (group_type == GROUP_MVE
+	  && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
+	{
+	  inst.operands[i].immisreg = 2;
+	  inst.operands[i].imm = reg;
+
+	  if (skip_past_comma (&p) == SUCCESS)
+	    {
+	      if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
+		{
+		  inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
+		  inst.relocs[0].exp.X_add_number = 0;
+		}
+	      else
+		return PARSE_OPERAND_FAIL;
+	    }
+	}
+      else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
 	{
 	  inst.operands[i].imm = reg;
 	  inst.operands[i].immisreg = 1;
@@ -5922,7 +5970,15 @@ parse_address_main (char **str, int i, int group_relocations,
 	  if (*p == '+') p++;
 	  else if (*p == '-') p++, inst.operands[i].negative = 1;
 
-	  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
+	  enum arm_reg_type rtype = REG_TYPE_MQ;
+	  struct neon_type_el et;
+	  if (group_type == GROUP_MVE
+	      && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
+	    {
+	      inst.operands[i].immisreg = 2;
+	      inst.operands[i].imm = reg;
+	    }
+	  else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
 	    {
 	      /* We might be using the immediate for alignment already. If we
 		 are, OR the register number into the low-order bits.  */
@@ -13896,6 +13952,14 @@ do_t_loloop (void)
 #define M_MNEM_vld41	0xfc901e21
 #define M_MNEM_vld42	0xfc901e41
 #define M_MNEM_vld43	0xfc901e61
+#define M_MNEM_vstrb	0xec000e00
+#define M_MNEM_vstrh	0xec000e10
+#define M_MNEM_vstrw	0xec000e40
+#define M_MNEM_vstrd	0xec000e50
+#define M_MNEM_vldrb	0xec100e00
+#define M_MNEM_vldrh	0xec100e10
+#define M_MNEM_vldrw	0xec100e40
+#define M_MNEM_vldrd	0xec100e50
 
 /* Neon instruction encoder helpers.  */
 
@@ -15743,6 +15807,247 @@ check_simd_pred_availability (int fp, unsigned check)
   return 0;
 }
 
+static void
+do_mve_vstr_vldr_QI (int size, int elsize, int load)
+{
+  constraint (size < 32, BAD_ADDR_MODE);
+  constraint (size != elsize, BAD_EL_TYPE);
+  constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
+  constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
+  constraint (load && inst.operands[0].reg == inst.operands[1].reg,
+	      _("destination register and offset register may not be the"
+		" same"));
+
+  int imm = inst.relocs[0].exp.X_add_number;
+  int add = 1;
+  if (imm < 0)
+    {
+      add = 0;
+      imm = -imm;
+    }
+  constraint ((imm % (size / 8) != 0)
+	      || imm > (0x7f << neon_logbits (size)),
+	      (size == 32) ? _("immediate must be a multiple of 4 in the"
+			       " range of +/-[0,508]")
+			   : _("immediate must be a multiple of 8 in the"
+			       " range of +/-[0,1016]"));
+  inst.instruction |= 0x11 << 24;
+  inst.instruction |= add << 23;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= inst.operands[1].writeback << 21;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= 1 << 12;
+  inst.instruction |= (size == 64) << 8;
+  inst.instruction &= 0xffffff00;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= imm >> neon_logbits (size);
+}
+
+static void
+do_mve_vstr_vldr_RQ (int size, int elsize, int load)
+{
+    unsigned os = inst.operands[1].imm >> 5;
+    constraint (os != 0 && size == 8,
+		_("can not shift offsets when accessing less than half-word"));
+    constraint (os && os != neon_logbits (size),
+		_("shift immediate must be 1, 2 or 3 for half-word, word"
+		  " or double-word accesses respectively"));
+    if (inst.operands[1].reg == REG_PC)
+      as_tsktsk (MVE_BAD_PC);
+
+    switch (size)
+      {
+      case 8:
+	constraint (elsize >= 64, BAD_EL_TYPE);
+	break;
+      case 16:
+	constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
+	break;
+      case 32:
+      case 64:
+	constraint (elsize != size, BAD_EL_TYPE);
+	break;
+      default:
+	break;
+      }
+    constraint (inst.operands[1].writeback || !inst.operands[1].preind,
+		BAD_ADDR_MODE);
+    if (load)
+      {
+	constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
+		    _("destination register and offset register may not be"
+		    " the same"));
+	constraint (size == elsize && inst.vectype.el[0].type != NT_unsigned,
+		    BAD_EL_TYPE);
+	constraint (inst.vectype.el[0].type != NT_unsigned
+		    && inst.vectype.el[0].type != NT_signed, BAD_EL_TYPE);
+	inst.instruction |= (inst.vectype.el[0].type == NT_unsigned) << 28;
+      }
+    else
+      {
+	constraint (inst.vectype.el[0].type != NT_untyped, BAD_EL_TYPE);
+      }
+
+    inst.instruction |= 1 << 23;
+    inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+    inst.instruction |= inst.operands[1].reg << 16;
+    inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+    inst.instruction |= neon_logbits (elsize) << 7;
+    inst.instruction |= HI1 (inst.operands[1].imm) << 5;
+    inst.instruction |= LOW4 (inst.operands[1].imm);
+    inst.instruction |= !!os;
+}
+
+static void
+do_mve_vstr_vldr_RI (int size, int elsize, int load)
+{
+  enum neon_el_type type = inst.vectype.el[0].type;
+
+  constraint (size >= 64, BAD_ADDR_MODE);
+  switch (size)
+    {
+    case 16:
+      constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
+      break;
+    case 32:
+      constraint (elsize != size, BAD_EL_TYPE);
+      break;
+    default:
+      break;
+    }
+  if (load)
+    {
+      constraint (elsize != size && type != NT_unsigned
+		  && type != NT_signed, BAD_EL_TYPE);
+    }
+  else
+    {
+      constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
+    }
+
+  int imm = inst.relocs[0].exp.X_add_number;
+  int add = 1;
+  if (imm < 0)
+    {
+      add = 0;
+      imm = -imm;
+    }
+
+  if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
+    {
+      switch (size)
+	{
+	case 8:
+	  constraint (1, _("immediate must be in the range of +/-[0,127]"));
+	  break;
+	case 16:
+	  constraint (1, _("immediate must be a multiple of 2 in the"
+			   " range of +/-[0,254]"));
+	  break;
+	case 32:
+	  constraint (1, _("immediate must be a multiple of 4 in the"
+			   " range of +/-[0,508]"));
+	  break;
+	}
+    }
+
+  if (size != elsize)
+    {
+      constraint (inst.operands[1].reg > 7, BAD_HIREG);
+      constraint (inst.operands[0].reg > 14,
+		  _("MVE vector register in the range [Q0..Q7] expected"));
+      inst.instruction |= (load && type == NT_unsigned) << 28;
+      inst.instruction |= (size == 16) << 19;
+      inst.instruction |= neon_logbits (elsize) << 7;
+    }
+  else
+    {
+      if (inst.operands[1].reg == REG_PC)
+	as_tsktsk (MVE_BAD_PC);
+      else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
+	as_tsktsk (MVE_BAD_SP);
+      inst.instruction |= 1 << 12;
+      inst.instruction |= neon_logbits (size) << 7;
+    }
+  inst.instruction |= inst.operands[1].preind << 24;
+  inst.instruction |= add << 23;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= inst.operands[1].writeback << 21;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction &= 0xffffff80;
+  inst.instruction |= imm >> neon_logbits (size);
+
+}
+
+static void
+do_mve_vstr_vldr (void)
+{
+  unsigned size;
+  int load = 0;
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  switch (inst.instruction)
+    {
+    default:
+      gas_assert (0);
+      break;
+    case M_MNEM_vldrb:
+      load = 1;
+      /* fall through.  */
+    case M_MNEM_vstrb:
+      size = 8;
+      break;
+    case M_MNEM_vldrh:
+      load = 1;
+      /* fall through.  */
+    case M_MNEM_vstrh:
+      size = 16;
+      break;
+    case M_MNEM_vldrw:
+      load = 1;
+      /* fall through.  */
+    case M_MNEM_vstrw:
+      size = 32;
+      break;
+    case M_MNEM_vldrd:
+      load = 1;
+      /* fall through.  */
+    case M_MNEM_vstrd:
+      size = 64;
+      break;
+    }
+  unsigned elsize = inst.vectype.el[0].size;
+
+  if (inst.operands[1].isquad)
+    {
+      /* We are dealing with [Q, imm]{!} cases.  */
+      do_mve_vstr_vldr_QI (size, elsize, load);
+    }
+  else
+    {
+      if (inst.operands[1].immisreg == 2)
+	{
+	  /* We are dealing with [R, Q, {UXTW #os}] cases.  */
+	  do_mve_vstr_vldr_RQ (size, elsize, load);
+	}
+      else if (!inst.operands[1].immisreg)
+	{
+	  /* We are dealing with [R, Imm]{!}/[R], Imm cases.  */
+	  do_mve_vstr_vldr_RI (size, elsize, load);
+	}
+      else
+	constraint (1, BAD_ADDR_MODE);
+    }
+
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vst_vld (void)
 {
@@ -20580,7 +20885,8 @@ static const struct asm_shift_name shift_names [] =
   { "lsr", SHIFT_LSR },	 { "LSR", SHIFT_LSR },
   { "asr", SHIFT_ASR },	 { "ASR", SHIFT_ASR },
   { "ror", SHIFT_ROR },	 { "ROR", SHIFT_ROR },
-  { "rrx", SHIFT_RRX },	 { "RRX", SHIFT_RRX }
+  { "rrx", SHIFT_RRX },	 { "RRX", SHIFT_RRX },
+  { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
 };
 
 /* Table of all explicit relocation names.  */
@@ -22950,6 +23256,14 @@ static const struct asm_opcode insns[] =
  mCEF(vld41,	_vld41,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
  mCEF(vld42,	_vld42,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
  mCEF(vld43,	_vld43,	    2, (MSTRLST4, ADDRMVE),		mve_vst_vld),
+ mCEF(vstrb,	_vstrb,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vstrh,	_vstrh,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vstrw,	_vstrw,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vstrd,	_vstrd,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vldrb,	_vldrb,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vldrh,	_vldrh,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vldrw,	_vldrw,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
+ mCEF(vldrd,	_vldrd,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT    & fpu_vfp_ext_v1xd
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-1.d b/gas/testsuite/gas/arm/mve-vldr-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..7c651eb3c40fda796a5cee8a66572e41ee0bd02e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VLDR with [R, Q] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vldr-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-1.l b/gas/testsuite/gas/arm/mve-vldr-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..9f1ba4d9562211239005db857934855ac87439a2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-1.l
@@ -0,0 +1,98 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad element type for instruction -- `vldrb.16 q0,\[r0,q1\]'
+[^:]*:11: Error: bad element type for instruction -- `vldrb.p16 q0,\[r0,q1\]'
+[^:]*:12: Error: bad element type for instruction -- `vldrb.f16 q0,\[r0,q1\]'
+[^:]*:13: Error: bad element type for instruction -- `vldrb.32 q0,\[r0,q1\]'
+[^:]*:14: Error: bad element type for instruction -- `vldrb.f32 q0,\[r0,q1\]'
+[^:]*:15: Error: bad element type for instruction -- `vldrb.64 q0,\[r0,q1\]'
+[^:]*:16: Error: bad element type for instruction -- `vldrb.u64 q0,\[r0,q1\]'
+[^:]*:17: Error: bad element type for instruction -- `vldrb.s64 q0,\[r0,q1\]'
+[^:]*:18: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:19: Error: destination register and offset register may not be the same -- `vldrb.u32 q0,\[r0,q0\]'
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Error: syntax error -- `vldrbeq.u32 q0,\[r0,q1\]'
+[^:]*:23: Error: syntax error -- `vldrbeq.u32 q0,\[r0,q1\]'
+[^:]*:25: Error: syntax error -- `vldrbeq.u32 q0,\[r0,q1\]'
+[^:]*:26: Error: vector predicated instruction should be in VPT/VPST block -- `vldrbt.u32 q0,\[r0,q1\]'
+[^:]*:28: Error: instruction missing MVE vector predication code -- `vldrb.u32 q0,\[r0,q1\]'
+[^:]*:30: Error: bad element type for instruction -- `vldrh.32 q0,\[r0,q1\]'
+[^:]*:31: Error: bad element type for instruction -- `vldrh.f32 q0,\[r0,q1\]'
+[^:]*:32: Error: bad element type for instruction -- `vldrh.64 q0,\[r0,q1\]'
+[^:]*:33: Error: bad element type for instruction -- `vldrh.u64 q0,\[r0,q1\]'
+[^:]*:34: Error: bad element type for instruction -- `vldrh.s64 q0,\[r0,q1\]'
+[^:]*:35: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:36: Error: destination register and offset register may not be the same -- `vldrh.u32 q0,\[r0,q0\]'
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Error: syntax error -- `vldrheq.u32 q0,\[r0,q1\]'
+[^:]*:40: Error: syntax error -- `vldrheq.u32 q0,\[r0,q1\]'
+[^:]*:42: Error: syntax error -- `vldrheq.u32 q0,\[r0,q1\]'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vldrht.u32 q0,\[r0,q1\]'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vldrh.u32 q0,\[r0,q1\]'
+[^:]*:47: Error: bad element type for instruction -- `vldrw.64 q0,\[r0,q1\]'
+[^:]*:48: Error: bad element type for instruction -- `vldrw.u64 q0,\[r0,q1\]'
+[^:]*:49: Error: bad element type for instruction -- `vldrw.s64 q0,\[r0,q1\]'
+[^:]*:50: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:51: Error: destination register and offset register may not be the same -- `vldrw.u32 q0,\[r0,q0\]'
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:52: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:54: Error: syntax error -- `vldrweq.u32 q0,\[r0,q1\]'
+[^:]*:55: Error: syntax error -- `vldrweq.u32 q0,\[r0,q1\]'
+[^:]*:57: Error: syntax error -- `vldrweq.u32 q0,\[r0,q1\]'
+[^:]*:58: Error: vector predicated instruction should be in VPT/VPST block -- `vldrwt.u32 q0,\[r0,q1\]'
+[^:]*:60: Error: instruction missing MVE vector predication code -- `vldrw.u32 q0,\[r0,q1\]'
+[^:]*:69: Error: bad element type for instruction -- `vldrd.8 q0,\[r0,q1\]'
+[^:]*:70: Error: bad element type for instruction -- `vldrd.u8 q0,\[r0,q1\]'
+[^:]*:71: Error: bad element type for instruction -- `vldrd.s8 q0,\[r0,q1\]'
+[^:]*:72: Error: bad element type for instruction -- `vldrd.p8 q0,\[r0,q1\]'
+[^:]*:73: Error: bad element type for instruction -- `vldrd.16 q0,\[r0,q1\]'
+[^:]*:74: Error: bad element type for instruction -- `vldrd.u16 q0,\[r0,q1\]'
+[^:]*:75: Error: bad element type for instruction -- `vldrd.s16 q0,\[r0,q1\]'
+[^:]*:76: Error: bad element type for instruction -- `vldrd.p16 q0,\[r0,q1\]'
+[^:]*:77: Error: bad element type for instruction -- `vldrd.f16 q0,\[r0,q1\]'
+[^:]*:78: Error: bad element type for instruction -- `vldrd.32 q0,\[r0,q1\]'
+[^:]*:79: Error: bad element type for instruction -- `vldrd.u32 q0,\[r0,q1\]'
+[^:]*:80: Error: bad element type for instruction -- `vldrd.s32 q0,\[r0,q1\]'
+[^:]*:81: Error: bad element type for instruction -- `vldrd.f32 q0,\[r0,q1\]'
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:84: Error: syntax error -- `vldrdeq.u64 q0,\[r0,q1\]'
+[^:]*:85: Error: syntax error -- `vldrdeq.u64 q0,\[r0,q1\]'
+[^:]*:87: Error: syntax error -- `vldrdeq.u64 q0,\[r0,q1\]'
+[^:]*:88: Error: vector predicated instruction should be in VPT/VPST block -- `vldrdt.u64 q0,\[r0,q1\]'
+[^:]*:90: Error: instruction missing MVE vector predication code -- `vldrd.u64 q0,\[r0,q1\]'
+[^:]*:92: Error: shift expression expected -- `vldrb.u8 q0,\[r0,q1,#0\]'
+[^:]*:93: Error: can not shift offsets when accessing less than half-word -- `vldrb.u8 q0,\[r0,q1,UXTW#1\]'
+[^:]*:94: Error: can not shift offsets when accessing less than half-word -- `vldrb.u16 q0,\[r0,q1,UXTW#1\]'
+[^:]*:95: Error: can not shift offsets when accessing less than half-word -- `vldrb.u32 q0,\[r0,q1,UXTW#1\]'
+[^:]*:96: Error: shift expression expected -- `vldrh.u16 q0,\[r0,q1,#1\]'
+[^:]*:97: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrh.u16 q0,\[r0,q1,UXTW#2\]'
+[^:]*:98: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrh.u32 q0,\[r0,q1,UXTW#2\]'
+[^:]*:99: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrh.u16 q0,\[r0,q1,UXTW#3\]'
+[^:]*:100: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrh.u32 q0,\[r0,q1,UXTW#3\]'
+[^:]*:101: Error: shift expression expected -- `vldrw.u32 q0,\[r0,q1,#2\]'
+[^:]*:102: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrw.u32 q0,\[r0,q1,UXTW#1\]'
+[^:]*:103: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrw.u32 q0,\[r0,q1,UXTW#3\]'
+[^:]*:104: Error: shift expression expected -- `vldrd.u64 q0,\[r0,q1,#3\]'
+[^:]*:105: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrd.u64 q0,\[r0,q1,UXTW#1\]'
+[^:]*:106: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrd.u64 q0,\[r0,q1,UXTW#2\]'
+[^:]*:107: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vldrd.u64 q0,\[r0,q1,UXTW#4\]'
+
+
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-1.s b/gas/testsuite/gas/arm/mve-vldr-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..09218cc35cc565bdb0b62eec24f7755e8cdf511a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-1.s
@@ -0,0 +1,107 @@
+.macro cond mnem
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().u32 q0, [r0, q1]
+.endr
+.endm
+
+.syntax unified
+.thumb
+vldrb.16 q0, [r0, q1]
+vldrb.p16 q0, [r0, q1]
+vldrb.f16 q0, [r0, q1]
+vldrb.32 q0, [r0, q1]
+vldrb.f32 q0, [r0, q1]
+vldrb.64 q0, [r0, q1]
+vldrb.u64 q0, [r0, q1]
+vldrb.s64 q0, [r0, q1]
+vldrb.u32 q0, [pc, q1]
+vldrb.u32 q0, [r0, q0]
+cond vldrb
+it eq
+vldrbeq.u32 q0, [r0, q1]
+vldrbeq.u32 q0, [r0, q1]
+vpst
+vldrbeq.u32 q0, [r0, q1]
+vldrbt.u32 q0, [r0, q1]
+vpst
+vldrb.u32 q0, [r0, q1]
+
+vldrh.32 q0, [r0, q1]
+vldrh.f32 q0, [r0, q1]
+vldrh.64 q0, [r0, q1]
+vldrh.u64 q0, [r0, q1]
+vldrh.s64 q0, [r0, q1]
+vldrh.u32 q0, [pc, q1]
+vldrh.u32 q0, [r0, q0]
+cond vldrh
+it eq
+vldrheq.u32 q0, [r0, q1]
+vldrheq.u32 q0, [r0, q1]
+vpst
+vldrheq.u32 q0, [r0, q1]
+vldrht.u32 q0, [r0, q1]
+vpst
+vldrh.u32 q0, [r0, q1]
+
+vldrw.64 q0, [r0, q1]
+vldrw.u64 q0, [r0, q1]
+vldrw.s64 q0, [r0, q1]
+vldrw.u32 q0, [pc, q1]
+vldrw.u32 q0, [r0, q0]
+cond vldrw
+it eq
+vldrweq.u32 q0, [r0, q1]
+vldrweq.u32 q0, [r0, q1]
+vpst
+vldrweq.u32 q0, [r0, q1]
+vldrwt.u32 q0, [r0, q1]
+vpst
+vldrw.u32 q0, [r0, q1]
+
+.macro cond64
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vldrd.u64 q0, [r0, q1]
+.endr
+.endm
+
+vldrd.8 q0, [r0, q1]
+vldrd.u8 q0, [r0, q1]
+vldrd.s8 q0, [r0, q1]
+vldrd.p8 q0, [r0, q1]
+vldrd.16 q0, [r0, q1]
+vldrd.u16 q0, [r0, q1]
+vldrd.s16 q0, [r0, q1]
+vldrd.p16 q0, [r0, q1]
+vldrd.f16 q0, [r0, q1]
+vldrd.32 q0, [r0, q1]
+vldrd.u32 q0, [r0, q1]
+vldrd.s32 q0, [r0, q1]
+vldrd.f32 q0, [r0, q1]
+cond64
+it eq
+vldrdeq.u64 q0, [r0, q1]
+vldrdeq.u64 q0, [r0, q1]
+vpst
+vldrdeq.u64 q0, [r0, q1]
+vldrdt.u64 q0, [r0, q1]
+vpst
+vldrd.u64 q0, [r0, q1]
+
+vldrb.u8 q0, [r0, q1, #0]
+vldrb.u8 q0, [r0, q1, UXTW #1]
+vldrb.u16 q0, [r0, q1, UXTW #1]
+vldrb.u32 q0, [r0, q1, UXTW #1]
+vldrh.u16 q0, [r0, q1, #1]
+vldrh.u16 q0, [r0, q1, UXTW #2]
+vldrh.u32 q0, [r0, q1, UXTW #2]
+vldrh.u16 q0, [r0, q1, UXTW #3]
+vldrh.u32 q0, [r0, q1, UXTW #3]
+vldrw.u32 q0, [r0, q1, #2]
+vldrw.u32 q0, [r0, q1, UXTW #1]
+vldrw.u32 q0, [r0, q1, UXTW #3]
+vldrd.u64 q0, [r0, q1, #3]
+vldrd.u64 q0, [r0, q1, UXTW #1]
+vldrd.u64 q0, [r0, q1, UXTW #2]
+vldrd.u64 q0, [r0, q1, UXTW #4]
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-2.d b/gas/testsuite/gas/arm/mve-vldr-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..9dc3fd898f062295cc223d1fbe1ed57918ece8ca
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE VLDR with [Q, #imm] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vldr-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-2.l b/gas/testsuite/gas/arm/mve-vldr-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..eb3f537deb2e7690e14edbcd359c54312696b9c5
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-2.l
@@ -0,0 +1,41 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad element type for instruction -- `vldrw.u16 q0,\[q1,#4\]'
+[^:]*:11: Error: bad element type for instruction -- `vldrw.u64 q0,\[q1,#-4\]'
+[^:]*:12: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.u32 q0,\[q1,#1\]'
+[^:]*:13: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.u32 q0,\[q1,#2\]'
+[^:]*:14: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.u32 q0,\[q1,#231\]'
+[^:]*:15: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.u32 q0,\[q1,#516\]'
+[^:]*:16: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.u32 q0,\[q1,#-516\]'
+[^:]*:17: Error: destination register and offset register may not be the same -- `vldrw.u32 q0,\[q0,#4\]'
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Error: syntax error -- `vldrweq.u32 q0,\[q1\]'
+[^:]*:21: Error: syntax error -- `vldrweq.u32 q0,\[q1\]'
+[^:]*:23: Error: syntax error -- `vldrweq.u32 q0,\[q1\]'
+[^:]*:24: Error: vector predicated instruction should be in VPT/VPST block -- `vldrwt.u32 q0,\[q1\]'
+[^:]*:26: Error: instruction missing MVE vector predication code -- `vldrw.u32 q0,\[q1\]'
+[^:]*:27: Error: bad element type for instruction -- `vldrd.u16 q0,\[q1,#8\]'
+[^:]*:28: Error: bad element type for instruction -- `vldrd.u32 q0,\[q1,#-8\]'
+[^:]*:29: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#1\]'
+[^:]*:30: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#4\]'
+[^:]*:31: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#7\]'
+[^:]*:32: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#228\]'
+[^:]*:33: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#1024\]'
+[^:]*:34: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vldrd.u64 q0,\[q1,#-1024\]'
+[^:]*:35: Error: destination register and offset register may not be the same -- `vldrd.u64 q0,\[q0,#8\]'
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Error: syntax error -- `vldrdeq.u64 q0,\[q1\]'
+[^:]*:39: Error: syntax error -- `vldrdeq.u64 q0,\[q1\]'
+[^:]*:41: Error: syntax error -- `vldrdeq.u64 q0,\[q1\]'
+[^:]*:42: Error: vector predicated instruction should be in VPT/VPST block -- `vldrdt.u64 q0,\[q1\]'
+[^:]*:44: Error: instruction missing MVE vector predication code -- `vldrd.u64 q0,\[q1\]'
+
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-2.s b/gas/testsuite/gas/arm/mve-vldr-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..d0c4e77e711d5257c55b2fe30ca45065f35eaff2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-2.s
@@ -0,0 +1,44 @@
+.macro cond mnem, size
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().u\size q0, [q1, #8]
+.endr
+.endm
+
+.syntax unified
+.thumb
+vldrw.u16 q0, [q1, #4]
+vldrw.u64 q0, [q1, #-4]
+vldrw.u32 q0, [q1, #1]
+vldrw.u32 q0, [q1, #2]
+vldrw.u32 q0, [q1, #231]
+vldrw.u32 q0, [q1, #516]
+vldrw.u32 q0, [q1, #-516]
+vldrw.u32 q0, [q0, #4]
+cond vldrw, 32
+it eq
+vldrweq.u32 q0, [q1]
+vldrweq.u32 q0, [q1]
+vpst
+vldrweq.u32 q0, [q1]
+vldrwt.u32 q0, [q1]
+vpst
+vldrw.u32 q0, [q1]
+vldrd.u16 q0, [q1, #8]
+vldrd.u32 q0, [q1, #-8]
+vldrd.u64 q0, [q1, #1]
+vldrd.u64 q0, [q1, #4]
+vldrd.u64 q0, [q1, #7]
+vldrd.u64 q0, [q1, #228]
+vldrd.u64 q0, [q1, #1024]
+vldrd.u64 q0, [q1, #-1024]
+vldrd.u64 q0, [q0, #8]
+cond vldrd, 64
+it eq
+vldrdeq.u64 q0, [q1]
+vldrdeq.u64 q0, [q1]
+vpst
+vldrdeq.u64 q0, [q1]
+vldrdt.u64 q0, [q1]
+vpst
+vldrd.u64 q0, [q1]
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-3.d b/gas/testsuite/gas/arm/mve-vldr-bad-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..2f5e230249b0e91064992febb46a66fe2a53548e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-3.d
@@ -0,0 +1,5 @@
+#name: bad MVE VLDR with [R, #imm] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vldr-bad-3.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-3.l b/gas/testsuite/gas/arm/mve-vldr-bad-3.l
new file mode 100644
index 0000000000000000000000000000000000000000..024822ded3e66ba41b52fa20b13f2e5a3f20069a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-3.l
@@ -0,0 +1,135 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0,#128\]'
+[^:]*:11: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0,#-128\]'
+[^:]*:12: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0,#128\]'
+[^:]*:13: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0,#-128\]'
+[^:]*:14: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0,#128\]'
+[^:]*:15: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0,#-128\]'
+[^:]*:16: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0,#128\]!'
+[^:]*:17: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0,#-128\]!'
+[^:]*:18: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0,#128\]!'
+[^:]*:19: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0,#-128\]!'
+[^:]*:20: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0,#128\]!'
+[^:]*:21: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0,#-128\]!'
+[^:]*:22: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0\],#128'
+[^:]*:23: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.8 q0,\[r0\],#-128'
+[^:]*:24: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0\],#128'
+[^:]*:25: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u16 q0,\[r0\],#-128'
+[^:]*:26: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0\],#128'
+[^:]*:27: Error: immediate must be in the range of \+/-\[0,127\] -- `vldrb.u32 q0,\[r0\],#-128'
+[^:]*:28: Error: lo register required -- `vldrb.u16 q0,\[r10,#2\]'
+[^:]*:29: Error: lo register required -- `vldrb.u16 q0,\[r10,#2\]!'
+[^:]*:30: Error: lo register required -- `vldrb.u16 q0,\[r10\],#2'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:32: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Error: bad element type for instruction -- `vldrb.16 q0,\[r0\]'
+[^:]*:36: Error: bad element type for instruction -- `vldrb.f16 q0,\[r0\]'
+[^:]*:37: Error: bad element type for instruction -- `vldrb.p16 q0,\[r0\]'
+[^:]*:38: Error: bad element type for instruction -- `vldrb.32 q0,\[r0\]'
+[^:]*:39: Error: bad element type for instruction -- `vldrb.f32 q0,\[r0\]'
+[^:]*:40: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#1\]'
+[^:]*:41: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#17\]'
+[^:]*:42: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#-17\]'
+[^:]*:43: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#256\]'
+[^:]*:44: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#-256\]'
+[^:]*:45: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0,#1\]'
+[^:]*:46: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0,#17\]'
+[^:]*:47: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0,#-17\]'
+[^:]*:48: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0,#256\]'
+[^:]*:49: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0,#-256\]'
+[^:]*:50: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#1\]!'
+[^:]*:51: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#17\]!'
+[^:]*:52: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#-17\]!'
+[^:]*:53: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#256\]!'
+[^:]*:54: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0,#-256\]!'
+[^:]*:55: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.s32 q0,\[r0,#1\]!'
+[^:]*:56: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.s32 q0,\[r0,#17\]!'
+[^:]*:57: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.s32 q0,\[r0,#-17\]!'
+[^:]*:58: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.s32 q0,\[r0,#256\]!'
+[^:]*:59: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.s32 q0,\[r0,#-256\]!'
+[^:]*:60: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0\],#1'
+[^:]*:61: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0\],#17'
+[^:]*:62: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0\],#-17'
+[^:]*:63: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0\],#256'
+[^:]*:64: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.16 q0,\[r0\],#-256'
+[^:]*:65: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0\],#1'
+[^:]*:66: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0\],#17'
+[^:]*:67: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0\],#-17'
+[^:]*:68: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0\],#256'
+[^:]*:69: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vldrh.u32 q0,\[r0\],#-256'
+[^:]*:70: Error: lo register required -- `vldrh.u32 q0,\[r10,#4\]'
+[^:]*:71: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:72: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:73: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Error: bad element type for instruction -- `vldrh.8 q0,\[r0\]'
+[^:]*:76: Error: bad element type for instruction -- `vldrh.u8 q0,\[r0\]'
+[^:]*:77: Error: bad element type for instruction -- `vldrh.s8 q0,\[r0\]'
+[^:]*:78: Error: bad element type for instruction -- `vldrh.p8 q0,\[r0\]'
+[^:]*:79: Error: bad element type for instruction -- `vldrh.32 q0,\[r0\]'
+[^:]*:80: Error: bad element type for instruction -- `vldrh.f32 q0,\[r0\]'
+[^:]*:81: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#3\]'
+[^:]*:82: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-3\]'
+[^:]*:83: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#514\]'
+[^:]*:84: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-258\]'
+[^:]*:85: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#258\]'
+[^:]*:86: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#516\]'
+[^:]*:87: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-516\]'
+[^:]*:88: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#3\]!'
+[^:]*:89: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-3\]!'
+[^:]*:90: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#514\]!'
+[^:]*:91: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-258\]!'
+[^:]*:92: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#258\]!'
+[^:]*:93: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#516\]!'
+[^:]*:94: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0,#-516\]!'
+[^:]*:95: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#3'
+[^:]*:96: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#-3'
+[^:]*:97: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#514'
+[^:]*:98: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#-258'
+[^:]*:99: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#258'
+[^:]*:100: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#516'
+[^:]*:101: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vldrw.32 q0,\[r0\],#-516'
+[^:]*:102: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:103: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:104: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:105: Error: bad element type for instruction -- `vldrw.8 q0,\[r0\]'
+[^:]*:106: Error: bad element type for instruction -- `vldrw.u8 q0,\[r0\]'
+[^:]*:107: Error: bad element type for instruction -- `vldrw.s8 q0,\[r0\]'
+[^:]*:108: Error: bad element type for instruction -- `vldrw.p8 q0,\[r0\]'
+[^:]*:109: Error: bad element type for instruction -- `vldrw.16 q0,\[r0\]'
+[^:]*:110: Error: bad element type for instruction -- `vldrw.u16 q0,\[r0\]'
+[^:]*:111: Error: bad element type for instruction -- `vldrw.s16 q0,\[r0\]'
+[^:]*:112: Error: bad element type for instruction -- `vldrw.f16 q0,\[r0\]'
+[^:]*:113: Error: bad element type for instruction -- `vldrw.p16 q0,\[r0\]'
+[^:]*:115: Error: syntax error -- `vldrbeq.8 q0,\[r0\]'
+[^:]*:116: Error: syntax error -- `vldrbeq.8 q0,\[r0\]'
+[^:]*:118: Error: syntax error -- `vldrbeq.8 q0,\[r0\]'
+[^:]*:119: Error: vector predicated instruction should be in VPT/VPST block -- `vldrbt.8 q0,\[r0\]'
+[^:]*:121: Error: instruction missing MVE vector predication code -- `vldrb.8 q0,\[r0\]'
+[^:]*:123: Error: syntax error -- `vldrheq.16 q0,\[r0\]'
+[^:]*:124: Error: syntax error -- `vldrheq.16 q0,\[r0\]'
+[^:]*:126: Error: syntax error -- `vldrheq.16 q0,\[r0\]'
+[^:]*:127: Error: vector predicated instruction should be in VPT/VPST block -- `vldrht.16 q0,\[r0\]'
+[^:]*:129: Error: instruction missing MVE vector predication code -- `vldrh.16 q0,\[r0\]'
+[^:]*:131: Error: syntax error -- `vldrweq.32 q0,\[r0\]'
+[^:]*:132: Error: syntax error -- `vldrweq.32 q0,\[r0\]'
+[^:]*:134: Error: syntax error -- `vldrweq.32 q0,\[r0\]'
+[^:]*:135: Error: vector predicated instruction should be in VPT/VPST block -- `vldrwt.32 q0,\[r0\]'
+[^:]*:137: Error: instruction missing MVE vector predication code -- `vldrw.32 q0,\[r0\]'
diff --git a/gas/testsuite/gas/arm/mve-vldr-bad-3.s b/gas/testsuite/gas/arm/mve-vldr-bad-3.s
new file mode 100644
index 0000000000000000000000000000000000000000..3b3fd61007457896b9086c4591029670b4ec34b3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vldr-bad-3.s
@@ -0,0 +1,138 @@
+.macro cond mnem
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().u32 q0, [r0]
+.endr
+.endm
+
+.syntax unified
+.thumb
+vldrb.8 q0, [r0, #128]
+vldrb.8 q0, [r0, #-128]
+vldrb.u16 q0, [r0, #128]
+vldrb.u16 q0, [r0, #-128]
+vldrb.u32 q0, [r0, #128]
+vldrb.u32 q0, [r0, #-128]
+vldrb.8 q0, [r0, #128]!
+vldrb.8 q0, [r0, #-128]!
+vldrb.u16 q0, [r0, #128]!
+vldrb.u16 q0, [r0, #-128]!
+vldrb.u32 q0, [r0, #128]!
+vldrb.u32 q0, [r0, #-128]!
+vldrb.8 q0, [r0], #128
+vldrb.8 q0, [r0], #-128
+vldrb.u16 q0, [r0], #128
+vldrb.u16 q0, [r0], #-128
+vldrb.u32 q0, [r0], #128
+vldrb.u32 q0, [r0], #-128
+vldrb.u16 q0, [r10, #2]
+vldrb.u16 q0, [r10, #2]!
+vldrb.u16 q0, [r10], #2
+vldrb.8 q0, [sp, #2]!
+vldrb.8 q0, [sp], #2
+vldrb.8 q0, [pc, #2]
+cond vldrb
+vldrb.16 q0, [r0]
+vldrb.f16 q0, [r0]
+vldrb.p16 q0, [r0]
+vldrb.32 q0, [r0]
+vldrb.f32 q0, [r0]
+vldrh.16 q0, [r0, #1]
+vldrh.16 q0, [r0, #17]
+vldrh.16 q0, [r0, #-17]
+vldrh.16 q0, [r0, #256]
+vldrh.16 q0, [r0, #-256]
+vldrh.u32 q0, [r0, #1]
+vldrh.u32 q0, [r0, #17]
+vldrh.u32 q0, [r0, #-17]
+vldrh.u32 q0, [r0, #256]
+vldrh.u32 q0, [r0, #-256]
+vldrh.16 q0, [r0, #1]!
+vldrh.16 q0, [r0, #17]!
+vldrh.16 q0, [r0, #-17]!
+vldrh.16 q0, [r0, #256]!
+vldrh.16 q0, [r0, #-256]!
+vldrh.s32 q0, [r0, #1]!
+vldrh.s32 q0, [r0, #17]!
+vldrh.s32 q0, [r0, #-17]!
+vldrh.s32 q0, [r0, #256]!
+vldrh.s32 q0, [r0, #-256]!
+vldrh.16 q0, [r0], #1
+vldrh.16 q0, [r0], #17
+vldrh.16 q0, [r0], #-17
+vldrh.16 q0, [r0], #256
+vldrh.16 q0, [r0], #-256
+vldrh.u32 q0, [r0], #1
+vldrh.u32 q0, [r0], #17
+vldrh.u32 q0, [r0], #-17
+vldrh.u32 q0, [r0], #256
+vldrh.u32 q0, [r0], #-256
+vldrh.u32 q0, [r10, #4]
+vldrh.16 q0, [sp, #2]!
+vldrh.16 q0, [sp], #2
+vldrh.16 q0, [pc, #2]
+cond vldrh
+vldrh.8 q0, [r0]
+vldrh.u8 q0, [r0]
+vldrh.s8 q0, [r0]
+vldrh.p8 q0, [r0]
+vldrh.32 q0, [r0]
+vldrh.f32 q0, [r0]
+vldrw.32 q0, [r0, #3]
+vldrw.32 q0, [r0, #-3]
+vldrw.32 q0, [r0, #514]
+vldrw.32 q0, [r0, #-258]
+vldrw.32 q0, [r0, #258]
+vldrw.32 q0, [r0, #516]
+vldrw.32 q0, [r0, #-516]
+vldrw.32 q0, [r0, #3]!
+vldrw.32 q0, [r0, #-3]!
+vldrw.32 q0, [r0, #514]!
+vldrw.32 q0, [r0, #-258]!
+vldrw.32 q0, [r0, #258]!
+vldrw.32 q0, [r0, #516]!
+vldrw.32 q0, [r0, #-516]!
+vldrw.32 q0, [r0], #3
+vldrw.32 q0, [r0], #-3
+vldrw.32 q0, [r0], #514
+vldrw.32 q0, [r0], #-258
+vldrw.32 q0, [r0], #258
+vldrw.32 q0, [r0], #516
+vldrw.32 q0, [r0], #-516
+vldrw.32 q0, [sp, #4]!
+vldrw.32 q0, [pc, #4]
+cond vldrw
+vldrw.8 q0, [r0]
+vldrw.u8 q0, [r0]
+vldrw.s8 q0, [r0]
+vldrw.p8 q0, [r0]
+vldrw.16 q0, [r0]
+vldrw.u16 q0, [r0]
+vldrw.s16 q0, [r0]
+vldrw.f16 q0, [r0]
+vldrw.p16 q0, [r0]
+it eq
+vldrbeq.8 q0, [r0]
+vldrbeq.8 q0, [r0]
+vpst
+vldrbeq.8 q0, [r0]
+vldrbt.8 q0, [r0]
+vpst
+vldrb.8 q0, [r0]
+it eq
+vldrheq.16 q0, [r0]
+vldrheq.16 q0, [r0]
+vpst
+vldrheq.16 q0, [r0]
+vldrht.16 q0, [r0]
+vpst
+vldrh.16 q0, [r0]
+it eq
+vldrweq.32 q0, [r0]
+vldrweq.32 q0, [r0]
+vpst
+vldrweq.32 q0, [r0]
+vldrwt.32 q0, [r0]
+vpst
+vldrw.32 q0, [r0]
+
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-1.d b/gas/testsuite/gas/arm/mve-vstr-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..05e95e341750c4ec36d50306974e8f82081d422c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSTR with [R, Q] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vstr-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-1.l b/gas/testsuite/gas/arm/mve-vstr-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..8fb6b06d869c9e2a220e3eb729cf0d12f7dd6e56
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-1.l
@@ -0,0 +1,105 @@
+[^:]*: Assembler messages:
+[^:]*:12: Error: bad element type for instruction -- `vstrb.s8 q0,\[r0,q1\]'
+[^:]*:13: Error: bad element type for instruction -- `vstrb.u8 q0,\[r0,q1\]'
+[^:]*:14: Error: bad element type for instruction -- `vstrb.s16 q0,\[r0,q1\]'
+[^:]*:15: Error: bad element type for instruction -- `vstrb.u16 q0,\[r0,q1\]'
+[^:]*:16: Error: bad element type for instruction -- `vstrb.f16 q0,\[r0,q1\]'
+[^:]*:17: Error: bad element type for instruction -- `vstrb.u32 q0,\[r0,q1\]'
+[^:]*:18: Error: bad element type for instruction -- `vstrb.s32 q0,\[r0,q1\]'
+[^:]*:19: Error: bad element type for instruction -- `vstrb.f32 q0,\[r0,q1\]'
+[^:]*:20: Error: bad element type for instruction -- `vstrb.64 q0,\[r0,q1\]'
+[^:]*:21: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Error: bad element type for instruction -- `vstrh.8 q0,\[r0,q1\]'
+[^:]*:26: Error: bad element type for instruction -- `vstrh.s8 q0,\[r0,q1\]'
+[^:]*:27: Error: bad element type for instruction -- `vstrh.u8 q0,\[r0,q1\]'
+[^:]*:28: Error: bad element type for instruction -- `vstrh.s16 q0,\[r0,q1\]'
+[^:]*:29: Error: bad element type for instruction -- `vstrh.u16 q0,\[r0,q1\]'
+[^:]*:30: Error: bad element type for instruction -- `vstrh.f16 q0,\[r0,q1\]'
+[^:]*:31: Error: bad element type for instruction -- `vstrh.u32 q0,\[r0,q1\]'
+[^:]*:32: Error: bad element type for instruction -- `vstrh.s32 q0,\[r0,q1\]'
+[^:]*:33: Error: bad element type for instruction -- `vstrh.f32 q0,\[r0,q1\]'
+[^:]*:34: Error: bad element type for instruction -- `vstrh.64 q0,\[r0,q1\]'
+[^:]*:35: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Error: shift expression expected -- `vstrh.16 q0,\[r0,q1,#1\]'
+[^:]*:40: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrh.16 q0,\[r0,q1,UXTW#2\]'
+[^:]*:41: Error: bad element type for instruction -- `vstrw.8 q0,\[r0,q1\]'
+[^:]*:42: Error: bad element type for instruction -- `vstrw.u8 q0,\[r0,q1\]'
+[^:]*:43: Error: bad element type for instruction -- `vstrw.s8 q0,\[r0,q1\]'
+[^:]*:44: Error: bad element type for instruction -- `vstrw.16 q0,\[r0,q1\]'
+[^:]*:45: Error: bad element type for instruction -- `vstrw.f16 q0,\[r0,q1\]'
+[^:]*:46: Error: bad element type for instruction -- `vstrw.u16 q0,\[r0,q1\]'
+[^:]*:47: Error: bad element type for instruction -- `vstrw.s16 q0,\[r0,q1\]'
+[^:]*:48: Error: bad element type for instruction -- `vstrw.u32 q0,\[r0,q1\]'
+[^:]*:49: Error: bad element type for instruction -- `vstrw.s32 q0,\[r0,q1\]'
+[^:]*:50: Error: bad element type for instruction -- `vstrw.f32 q0,\[r0,q1\]'
+[^:]*:51: Error: bad element type for instruction -- `vstrw.64 q0,\[r0,q1\]'
+[^:]*:52: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:53: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:56: Error: shift expression expected -- `vstrw.32 q0,\[r0,q1,#2\]'
+[^:]*:57: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrw.32 q0,\[r0,q1,UXTW#1\]'
+[^:]*:58: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrw.32 q0,\[r0,q1,UXTW#3\]'
+[^:]*:59: Error: bad element type for instruction -- `vstrd.8 q0,\[r0,q1\]'
+[^:]*:60: Error: bad element type for instruction -- `vstrd.u8 q0,\[r0,q1\]'
+[^:]*:61: Error: bad element type for instruction -- `vstrd.s8 q0,\[r0,q1\]'
+[^:]*:62: Error: bad element type for instruction -- `vstrd.16 q0,\[r0,q1\]'
+[^:]*:63: Error: bad element type for instruction -- `vstrd.u16 q0,\[r0,q1\]'
+[^:]*:64: Error: bad element type for instruction -- `vstrd.s16 q0,\[r0,q1\]'
+[^:]*:65: Error: bad element type for instruction -- `vstrd.f16 q0,\[r0,q1\]'
+[^:]*:66: Error: bad element type for instruction -- `vstrd.32 q0,\[r0,q1\]'
+[^:]*:67: Error: bad element type for instruction -- `vstrd.u32 q0,\[r0,q1\]'
+[^:]*:68: Error: bad element type for instruction -- `vstrd.s32 q0,\[r0,q1\]'
+[^:]*:69: Error: bad element type for instruction -- `vstrd.f32 q0,\[r0,q1\]'
+[^:]*:70: Error: bad element type for instruction -- `vstrd.f64 q0,\[r0,q1\]'
+[^:]*:71: Error: bad element type for instruction -- `vstrd.u64 q0,\[r0,q1\]'
+[^:]*:72: Error: bad element type for instruction -- `vstrd.s64 q0,\[r0,q1\]'
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:84: Error: shift expression expected -- `vstrd.64 q0,\[r0,q1,#3\]'
+[^:]*:85: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrd.64 q0,\[r0,q1,UXTW#1\]'
+[^:]*:86: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrd.64 q0,\[r0,q1,UXTW#2\]'
+[^:]*:87: Error: shift immediate must be 1, 2 or 3 for half-word, word or double-word accesses respectively -- `vstrd.64 q0,\[r0,q1,UXTW#4\]'
+[^:]*:90: Error: syntax error -- `vstrbeq.32 q0,\[r0,q1\]'
+[^:]*:91: Error: syntax error -- `vstrbeq.32 q0,\[r0,q1\]'
+[^:]*:93: Error: syntax error -- `vstrbeq.32 q0,\[r0,q1\]'
+[^:]*:95: Error: instruction missing MVE vector predication code -- `vstrb.32 q0,\[r0,q1\]'
+[^:]*:96: Error: vector predicated instruction should be in VPT/VPST block -- `vstrbt.32 q0,\[r0,q1\]'
+[^:]*:97: Error: vector predicated instruction should be in VPT/VPST block -- `vstrbe.32 q0,\[r0,q1\]'
+[^:]*:99: Error: syntax error -- `vstrheq.32 q0,\[r0,q1\]'
+[^:]*:100: Error: syntax error -- `vstrheq.32 q0,\[r0,q1\]'
+[^:]*:102: Error: syntax error -- `vstrheq.32 q0,\[r0,q1\]'
+[^:]*:104: Error: instruction missing MVE vector predication code -- `vstrh.32 q0,\[r0,q1\]'
+[^:]*:105: Error: vector predicated instruction should be in VPT/VPST block -- `vstrht.32 q0,\[r0,q1\]'
+[^:]*:106: Error: vector predicated instruction should be in VPT/VPST block -- `vstrhe.32 q0,\[r0,q1\]'
+[^:]*:108: Error: syntax error -- `vstrweq.32 q0,\[r0,q1\]'
+[^:]*:109: Error: syntax error -- `vstrweq.32 q0,\[r0,q1\]'
+[^:]*:111: Error: syntax error -- `vstrweq.32 q0,\[r0,q1\]'
+[^:]*:113: Error: instruction missing MVE vector predication code -- `vstrw.32 q0,\[r0,q1\]'
+[^:]*:114: Error: vector predicated instruction should be in VPT/VPST block -- `vstrwt.32 q0,\[r0,q1\]'
+[^:]*:115: Error: vector predicated instruction should be in VPT/VPST block -- `vstrwe.32 q0,\[r0,q1\]'
+[^:]*:117: Error: syntax error -- `vstrdeq.64 q0,\[r0,q1\]'
+[^:]*:118: Error: syntax error -- `vstrdeq.64 q0,\[r0,q1\]'
+[^:]*:120: Error: syntax error -- `vstrdeq.64 q0,\[r0,q1\]'
+[^:]*:122: Error: instruction missing MVE vector predication code -- `vstrd.64 q0,\[r0,q1\]'
+[^:]*:123: Error: vector predicated instruction should be in VPT/VPST block -- `vstrdt.64 q0,\[r0,q1\]'
+[^:]*:124: Error: vector predicated instruction should be in VPT/VPST block -- `vstrde.64 q0,\[r0,q1\]'
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-1.s b/gas/testsuite/gas/arm/mve-vstr-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..1eafc6a5f7f2ba7f5eb84dd47dfb4b85391b1795
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-1.s
@@ -0,0 +1,124 @@
+.macro cond mnem
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().32 q0, [r0, q1]
+.endr
+.endm
+
+
+
+.syntax unified
+.thumb
+vstrb.s8 q0, [r0, q1]
+vstrb.u8 q0, [r0, q1]
+vstrb.s16 q0, [r0, q1]
+vstrb.u16 q0, [r0, q1]
+vstrb.f16 q0, [r0, q1]
+vstrb.u32 q0, [r0, q1]
+vstrb.s32 q0, [r0, q1]
+vstrb.f32 q0, [r0, q1]
+vstrb.64 q0, [r0, q1]
+vstrb.16 q0, [pc, q1]
+cond vstrb
+
+
+vstrh.8 q0, [r0, q1]
+vstrh.s8 q0, [r0, q1]
+vstrh.u8 q0, [r0, q1]
+vstrh.s16 q0, [r0, q1]
+vstrh.u16 q0, [r0, q1]
+vstrh.f16 q0, [r0, q1]
+vstrh.u32 q0, [r0, q1]
+vstrh.s32 q0, [r0, q1]
+vstrh.f32 q0, [r0, q1]
+vstrh.64 q0, [r0, q1]
+vstrh.16 q0, [pc, q1]
+cond vstrh
+
+
+vstrh.16 q0, [r0, q1, #1]
+vstrh.16 q0, [r0, q1, UXTW #2]
+vstrw.8 q0, [r0, q1]
+vstrw.u8 q0, [r0, q1]
+vstrw.s8 q0, [r0, q1]
+vstrw.16 q0, [r0, q1]
+vstrw.f16 q0, [r0, q1]
+vstrw.u16 q0, [r0, q1]
+vstrw.s16 q0, [r0, q1]
+vstrw.u32 q0, [r0, q1]
+vstrw.s32 q0, [r0, q1]
+vstrw.f32 q0, [r0, q1]
+vstrw.64 q0, [r0, q1]
+vstrw.32 q0, [pc, q1]
+cond vstrw
+
+
+vstrw.32 q0, [r0, q1, #2]
+vstrw.32 q0, [r0, q1, UXTW #1]
+vstrw.32 q0, [r0, q1, UXTW #3]
+vstrd.8 q0, [r0, q1]
+vstrd.u8 q0, [r0, q1]
+vstrd.s8 q0, [r0, q1]
+vstrd.16 q0, [r0, q1]
+vstrd.u16 q0, [r0, q1]
+vstrd.s16 q0, [r0, q1]
+vstrd.f16 q0, [r0, q1]
+vstrd.32 q0, [r0, q1]
+vstrd.u32 q0, [r0, q1]
+vstrd.s32 q0, [r0, q1]
+vstrd.f32 q0, [r0, q1]
+vstrd.f64 q0, [r0, q1]
+vstrd.u64 q0, [r0, q1]
+vstrd.s64 q0, [r0, q1]
+
+.macro cond64
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vstrd\().64 q0, [r0, q1]
+.endr
+.endm
+
+
+
+cond64
+vstrd.64 q0, [r0, q1, #3]
+vstrd.64 q0, [r0, q1, UXTW #1]
+vstrd.64 q0, [r0, q1, UXTW #2]
+vstrd.64 q0, [r0, q1, UXTW #4]
+
+it eq
+vstrbeq.32 q0, [r0, q1]
+vstrbeq.32 q0, [r0, q1]
+vpst
+vstrbeq.32 q0, [r0, q1]
+vpst
+vstrb.32 q0, [r0, q1]
+vstrbt.32 q0, [r0, q1]
+vstrbe.32 q0, [r0, q1]
+it eq
+vstrheq.32 q0, [r0, q1]
+vstrheq.32 q0, [r0, q1]
+vpst
+vstrheq.32 q0, [r0, q1]
+vpst
+vstrh.32 q0, [r0, q1]
+vstrht.32 q0, [r0, q1]
+vstrhe.32 q0, [r0, q1]
+it eq
+vstrweq.32 q0, [r0, q1]
+vstrweq.32 q0, [r0, q1]
+vpst
+vstrweq.32 q0, [r0, q1]
+vpst
+vstrw.32 q0, [r0, q1]
+vstrwt.32 q0, [r0, q1]
+vstrwe.32 q0, [r0, q1]
+it eq
+vstrdeq.64 q0, [r0, q1]
+vstrdeq.64 q0, [r0, q1]
+vpst
+vstrdeq.64 q0, [r0, q1]
+vpst
+vstrd.64 q0, [r0, q1]
+vstrdt.64 q0, [r0, q1]
+vstrde.64 q0, [r0, q1]
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-2.d b/gas/testsuite/gas/arm/mve-vstr-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..e1dc5281ae8fbfd03b0b4beffa9c2329a737f4cf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSTR with [Q, #imm] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vstr-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-2.l b/gas/testsuite/gas/arm/mve-vstr-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..b4ecb2b1cd1bdab74ee8c448372473830b906a77
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-2.l
@@ -0,0 +1,38 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad element type for instruction -- `vstrw.u16 q0,\[q1,#4\]'
+[^:]*:11: Error: bad element type for instruction -- `vstrw.u64 q0,\[q1,#-4\]'
+[^:]*:12: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.u32 q0,\[q1,#1\]'
+[^:]*:13: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.u32 q0,\[q1,#2\]'
+[^:]*:14: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.u32 q0,\[q1,#231\]'
+[^:]*:15: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.u32 q0,\[q1,#516\]'
+[^:]*:16: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.u32 q0,\[q1,#-516\]'
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vstrweq.u32 q0,\[q1\]'
+[^:]*:20: Error: syntax error -- `vstrweq.u32 q0,\[q1\]'
+[^:]*:22: Error: syntax error -- `vstrweq.u32 q0,\[q1\]'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vstrwt.u32 q0,\[q1\]'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vstrw.u32 q0,\[q1\]'
+[^:]*:26: Error: bad element type for instruction -- `vstrd.u16 q0,\[q1,#8\]'
+[^:]*:27: Error: bad element type for instruction -- `vstrd.u32 q0,\[q1,#-8\]'
+[^:]*:28: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#1\]'
+[^:]*:29: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#4\]'
+[^:]*:30: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#7\]'
+[^:]*:31: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#228\]'
+[^:]*:32: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#1024\]'
+[^:]*:33: Error: immediate must be a multiple of 8 in the range of \+/-\[0,1016\] -- `vstrd.u64 q0,\[q1,#-1024\]'
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Error: syntax error -- `vstrdeq.u64 q0,\[q1\]'
+[^:]*:37: Error: syntax error -- `vstrdeq.u64 q0,\[q1\]'
+[^:]*:39: Error: syntax error -- `vstrdeq.u64 q0,\[q1\]'
+[^:]*:40: Error: vector predicated instruction should be in VPT/VPST block -- `vstrdt.u64 q0,\[q1\]'
+[^:]*:42: Error: instruction missing MVE vector predication code -- `vstrd.u64 q0,\[q1\]'
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-2.s b/gas/testsuite/gas/arm/mve-vstr-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..d6a1e8650001476190d05dd1421f42427fe1fa28
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-2.s
@@ -0,0 +1,43 @@
+.macro cond mnem, size
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().u\size q0, [q1, #8]
+.endr
+.endm
+
+.syntax unified
+.thumb
+vstrw.u16 q0, [q1, #4]
+vstrw.u64 q0, [q1, #-4]
+vstrw.u32 q0, [q1, #1]
+vstrw.u32 q0, [q1, #2]
+vstrw.u32 q0, [q1, #231]
+vstrw.u32 q0, [q1, #516]
+vstrw.u32 q0, [q1, #-516]
+cond vstrw, 32
+it eq
+vstrweq.u32 q0, [q1]
+vstrweq.u32 q0, [q1]
+vpst
+vstrweq.u32 q0, [q1]
+vstrwt.u32 q0, [q1]
+vpst
+vstrw.u32 q0, [q1]
+vstrd.u16 q0, [q1, #8]
+vstrd.u32 q0, [q1, #-8]
+vstrd.u64 q0, [q1, #1]
+vstrd.u64 q0, [q1, #4]
+vstrd.u64 q0, [q1, #7]
+vstrd.u64 q0, [q1, #228]
+vstrd.u64 q0, [q1, #1024]
+vstrd.u64 q0, [q1, #-1024]
+cond vstrd, 64
+it eq
+vstrdeq.u64 q0, [q1]
+vstrdeq.u64 q0, [q1]
+vpst
+vstrdeq.u64 q0, [q1]
+vstrdt.u64 q0, [q1]
+vpst
+vstrd.u64 q0, [q1]
+
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-3.d b/gas/testsuite/gas/arm/mve-vstr-bad-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..e4c657008fdaecd7b36b6e8e518c5f8e65f67844
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-3.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSTR with [R, #imm] addressing mode
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vstr-bad-3.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-3.l b/gas/testsuite/gas/arm/mve-vstr-bad-3.l
new file mode 100644
index 0000000000000000000000000000000000000000..71c9f58e62441432b5d7dbc74f3d32953f8821a5
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-3.l
@@ -0,0 +1,138 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0,#128\]'
+[^:]*:11: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0,#-128\]'
+[^:]*:12: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0,#128\]'
+[^:]*:13: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0,#-128\]'
+[^:]*:14: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0,#128\]'
+[^:]*:15: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0,#-128\]'
+[^:]*:16: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0,#128\]!'
+[^:]*:17: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0,#-128\]!'
+[^:]*:18: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0,#128\]!'
+[^:]*:19: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0,#-128\]!'
+[^:]*:20: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0,#128\]!'
+[^:]*:21: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0,#-128\]!'
+[^:]*:22: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0\],#128'
+[^:]*:23: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.8 q0,\[r0\],#-128'
+[^:]*:24: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0\],#128'
+[^:]*:25: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.16 q0,\[r0\],#-128'
+[^:]*:26: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0\],#128'
+[^:]*:27: Error: immediate must be in the range of \+/-\[0,127\] -- `vstrb.32 q0,\[r0\],#-128'
+[^:]*:28: Error: lo register required -- `vstrb.16 q0,\[r10,#2\]'
+[^:]*:29: Error: lo register required -- `vstrb.16 q0,\[r10,#2\]!'
+[^:]*:30: Error: lo register required -- `vstrb.16 q0,\[r10\],#2'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:32: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:34: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:35: Error: bad element type for instruction -- `vstrb.u16 q0,\[r0\]'
+[^:]*:36: Error: bad element type for instruction -- `vstrb.s16 q0,\[r0\]'
+[^:]*:37: Error: bad element type for instruction -- `vstrb.f16 q0,\[r0\]'
+[^:]*:38: Error: bad element type for instruction -- `vstrb.p16 q0,\[r0\]'
+[^:]*:39: Error: bad element type for instruction -- `vstrb.u32 q0,\[r0\]'
+[^:]*:40: Error: bad element type for instruction -- `vstrb.s32 q0,\[r0\]'
+[^:]*:41: Error: bad element type for instruction -- `vstrb.f32 q0,\[r0\]'
+[^:]*:42: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#1\]'
+[^:]*:43: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#17\]'
+[^:]*:44: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#-17\]'
+[^:]*:45: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#256\]'
+[^:]*:46: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#-256\]'
+[^:]*:47: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#1\]'
+[^:]*:48: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#17\]'
+[^:]*:49: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#-17\]'
+[^:]*:50: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#256\]'
+[^:]*:51: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#-256\]'
+[^:]*:52: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#1\]!'
+[^:]*:53: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#17\]!'
+[^:]*:54: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#-17\]!'
+[^:]*:55: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#256\]!'
+[^:]*:56: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0,#-256\]!'
+[^:]*:57: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#1\]!'
+[^:]*:58: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#17\]!'
+[^:]*:59: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#-17\]!'
+[^:]*:60: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#256\]!'
+[^:]*:61: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0,#-256\]!'
+[^:]*:62: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0\],#1'
+[^:]*:63: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0\],#17'
+[^:]*:64: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0\],#-17'
+[^:]*:65: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0\],#256'
+[^:]*:66: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.16 q0,\[r0\],#-256'
+[^:]*:67: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0\],#1'
+[^:]*:68: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0\],#17'
+[^:]*:69: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0\],#-17'
+[^:]*:70: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0\],#256'
+[^:]*:71: Error: immediate must be a multiple of 2 in the range of \+/-\[0,254\] -- `vstrh.32 q0,\[r0\],#-256'
+[^:]*:72: Error: lo register required -- `vstrh.32 q0,\[r10,#4\]'
+[^:]*:73: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:74: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:75: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Error: bad element type for instruction -- `vstrh.8 q0,\[r0\]'
+[^:]*:78: Error: bad element type for instruction -- `vstrh.u8 q0,\[r0\]'
+[^:]*:79: Error: bad element type for instruction -- `vstrh.s8 q0,\[r0\]'
+[^:]*:80: Error: bad element type for instruction -- `vstrh.p8 q0,\[r0\]'
+[^:]*:81: Error: bad element type for instruction -- `vstrh.u32 q0,\[r0\]'
+[^:]*:82: Error: bad element type for instruction -- `vstrh.s32 q0,\[r0\]'
+[^:]*:83: Error: bad element type for instruction -- `vstrh.f32 q0,\[r0\]'
+[^:]*:84: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#3\]'
+[^:]*:85: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-3\]'
+[^:]*:86: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#514\]'
+[^:]*:87: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-258\]'
+[^:]*:88: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#258\]'
+[^:]*:89: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#516\]'
+[^:]*:90: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-516\]'
+[^:]*:91: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#3\]!'
+[^:]*:92: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-3\]!'
+[^:]*:93: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#514\]!'
+[^:]*:94: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-258\]!'
+[^:]*:95: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#258\]!'
+[^:]*:96: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#516\]!'
+[^:]*:97: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0,#-516\]!'
+[^:]*:98: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#3'
+[^:]*:99: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#-3'
+[^:]*:100: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#514'
+[^:]*:101: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#-258'
+[^:]*:102: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#258'
+[^:]*:103: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#516'
+[^:]*:104: Error: immediate must be a multiple of 4 in the range of \+/-\[0,508\] -- `vstrw.32 q0,\[r0\],#-516'
+[^:]*:105: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:106: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:107: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:108: Error: bad element type for instruction -- `vstrw.8 q0,\[r0\]'
+[^:]*:109: Error: bad element type for instruction -- `vstrw.u8 q0,\[r0\]'
+[^:]*:110: Error: bad element type for instruction -- `vstrw.s8 q0,\[r0\]'
+[^:]*:111: Error: bad element type for instruction -- `vstrw.p8 q0,\[r0\]'
+[^:]*:112: Error: bad element type for instruction -- `vstrw.16 q0,\[r0\]'
+[^:]*:113: Error: bad element type for instruction -- `vstrw.u16 q0,\[r0\]'
+[^:]*:114: Error: bad element type for instruction -- `vstrw.s16 q0,\[r0\]'
+[^:]*:115: Error: bad element type for instruction -- `vstrw.f16 q0,\[r0\]'
+[^:]*:116: Error: bad element type for instruction -- `vstrw.p16 q0,\[r0\]'
+[^:]*:118: Error: syntax error -- `vstrbeq.8 q0,\[r0\]'
+[^:]*:119: Error: syntax error -- `vstrbeq.8 q0,\[r0\]'
+[^:]*:121: Error: syntax error -- `vstrbeq.8 q0,\[r0\]'
+[^:]*:122: Error: vector predicated instruction should be in VPT/VPST block -- `vstrbt.8 q0,\[r0\]'
+[^:]*:124: Error: instruction missing MVE vector predication code -- `vstrb.8 q0,\[r0\]'
+[^:]*:126: Error: syntax error -- `vstrheq.16 q0,\[r0\]'
+[^:]*:127: Error: syntax error -- `vstrheq.16 q0,\[r0\]'
+[^:]*:129: Error: syntax error -- `vstrheq.16 q0,\[r0\]'
+[^:]*:130: Error: vector predicated instruction should be in VPT/VPST block -- `vstrht.16 q0,\[r0\]'
+[^:]*:132: Error: instruction missing MVE vector predication code -- `vstrh.16 q0,\[r0\]'
+[^:]*:134: Error: syntax error -- `vstrweq.32 q0,\[r0\]'
+[^:]*:135: Error: syntax error -- `vstrweq.32 q0,\[r0\]'
+[^:]*:137: Error: syntax error -- `vstrweq.32 q0,\[r0\]'
+[^:]*:138: Error: vector predicated instruction should be in VPT/VPST block -- `vstrwt.32 q0,\[r0\]'
+[^:]*:140: Error: instruction missing MVE vector predication code -- `vstrw.32 q0,\[r0\]'
diff --git a/gas/testsuite/gas/arm/mve-vstr-bad-3.s b/gas/testsuite/gas/arm/mve-vstr-bad-3.s
new file mode 100644
index 0000000000000000000000000000000000000000..7c6a30d30ba10ac64793ca62425ebc444460fc86
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vstr-bad-3.s
@@ -0,0 +1,140 @@
+.macro cond mnem
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().32 q0, [r0]
+.endr
+.endm
+
+.syntax unified
+.thumb
+vstrb.8 q0, [r0, #128]
+vstrb.8 q0, [r0, #-128]
+vstrb.16 q0, [r0, #128]
+vstrb.16 q0, [r0, #-128]
+vstrb.32 q0, [r0, #128]
+vstrb.32 q0, [r0, #-128]
+vstrb.8 q0, [r0, #128]!
+vstrb.8 q0, [r0, #-128]!
+vstrb.16 q0, [r0, #128]!
+vstrb.16 q0, [r0, #-128]!
+vstrb.32 q0, [r0, #128]!
+vstrb.32 q0, [r0, #-128]!
+vstrb.8 q0, [r0], #128
+vstrb.8 q0, [r0], #-128
+vstrb.16 q0, [r0], #128
+vstrb.16 q0, [r0], #-128
+vstrb.32 q0, [r0], #128
+vstrb.32 q0, [r0], #-128
+vstrb.16 q0, [r10, #2]
+vstrb.16 q0, [r10, #2]!
+vstrb.16 q0, [r10], #2
+vstrb.8 q0, [sp, #2]!
+vstrb.8 q0, [sp], #2
+vstrb.8 q0, [pc, #2]
+cond vstrb
+vstrb.u16 q0, [r0]
+vstrb.s16 q0, [r0]
+vstrb.f16 q0, [r0]
+vstrb.p16 q0, [r0]
+vstrb.u32 q0, [r0]
+vstrb.s32 q0, [r0]
+vstrb.f32 q0, [r0]
+vstrh.16 q0, [r0, #1]
+vstrh.16 q0, [r0, #17]
+vstrh.16 q0, [r0, #-17]
+vstrh.16 q0, [r0, #256]
+vstrh.16 q0, [r0, #-256]
+vstrh.32 q0, [r0, #1]
+vstrh.32 q0, [r0, #17]
+vstrh.32 q0, [r0, #-17]
+vstrh.32 q0, [r0, #256]
+vstrh.32 q0, [r0, #-256]
+vstrh.16 q0, [r0, #1]!
+vstrh.16 q0, [r0, #17]!
+vstrh.16 q0, [r0, #-17]!
+vstrh.16 q0, [r0, #256]!
+vstrh.16 q0, [r0, #-256]!
+vstrh.32 q0, [r0, #1]!
+vstrh.32 q0, [r0, #17]!
+vstrh.32 q0, [r0, #-17]!
+vstrh.32 q0, [r0, #256]!
+vstrh.32 q0, [r0, #-256]!
+vstrh.16 q0, [r0], #1
+vstrh.16 q0, [r0], #17
+vstrh.16 q0, [r0], #-17
+vstrh.16 q0, [r0], #256
+vstrh.16 q0, [r0], #-256
+vstrh.32 q0, [r0], #1
+vstrh.32 q0, [r0], #17
+vstrh.32 q0, [r0], #-17
+vstrh.32 q0, [r0], #256
+vstrh.32 q0, [r0], #-256
+vstrh.32 q0, [r10, #4]
+vstrh.16 q0, [sp, #2]!
+vstrh.16 q0, [sp], #2
+vstrh.16 q0, [pc, #2]
+cond vstrh
+vstrh.8 q0, [r0]
+vstrh.u8 q0, [r0]
+vstrh.s8 q0, [r0]
+vstrh.p8 q0, [r0]
+vstrh.u32 q0, [r0]
+vstrh.s32 q0, [r0]
+vstrh.f32 q0, [r0]
+vstrw.32 q0, [r0, #3]
+vstrw.32 q0, [r0, #-3]
+vstrw.32 q0, [r0, #514]
+vstrw.32 q0, [r0, #-258]
+vstrw.32 q0, [r0, #258]
+vstrw.32 q0, [r0, #516]
+vstrw.32 q0, [r0, #-516]
+vstrw.32 q0, [r0, #3]!
+vstrw.32 q0, [r0, #-3]!
+vstrw.32 q0, [r0, #514]!
+vstrw.32 q0, [r0, #-258]!
+vstrw.32 q0, [r0, #258]!
+vstrw.32 q0, [r0, #516]!
+vstrw.32 q0, [r0, #-516]!
+vstrw.32 q0, [r0], #3
+vstrw.32 q0, [r0], #-3
+vstrw.32 q0, [r0], #514
+vstrw.32 q0, [r0], #-258
+vstrw.32 q0, [r0], #258
+vstrw.32 q0, [r0], #516
+vstrw.32 q0, [r0], #-516
+vstrw.32 q0, [sp, #4]!
+vstrw.32 q0, [pc, #4]
+cond vstrw
+vstrw.8 q0, [r0]
+vstrw.u8 q0, [r0]
+vstrw.s8 q0, [r0]
+vstrw.p8 q0, [r0]
+vstrw.16 q0, [r0]
+vstrw.u16 q0, [r0]
+vstrw.s16 q0, [r0]
+vstrw.f16 q0, [r0]
+vstrw.p16 q0, [r0]
+it eq
+vstrbeq.8 q0, [r0]
+vstrbeq.8 q0, [r0]
+vpst
+vstrbeq.8 q0, [r0]
+vstrbt.8 q0, [r0]
+vpst
+vstrb.8 q0, [r0]
+it eq
+vstrheq.16 q0, [r0]
+vstrheq.16 q0, [r0]
+vpst
+vstrheq.16 q0, [r0]
+vstrht.16 q0, [r0]
+vpst
+vstrh.16 q0, [r0]
+it eq
+vstrweq.32 q0, [r0]
+vstrweq.32 q0, [r0]
+vpst
+vstrweq.32 q0, [r0]
+vstrwt.32 q0, [r0]
+vpst
+vstrw.32 q0, [r0]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (6 preceding siblings ...)
  2019-05-01 17:01 ` [PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr Andre Vieira (lists)
@ 2019-05-01 17:02 ` Andre Vieira (lists)
  2019-05-01 17:03 ` [PATCH 10/57][Arm][GAS] Add support for MVE instructions: vcmp and vpt Andre Vieira (lists)
                   ` (52 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:02 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1068 bytes --]

Hi,

This patch adds support for all MVE VCVT instructions.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): Add new operand.
	(parse_operands): Handle new operand.
	(do_neon_cvt_1): Handle MVE variants.
	(do_neon_cvttb_1): Likewise.
	(insns): Accept MVE variants.
	* testsuite/gas/arm/mve-vcvt-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcvt-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcvt-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcvt-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcvt-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcvt-bad-2.s: New test.
	* testsuite/gas/arm/mve-vcvt-bad-3.d: New test.
	* testsuite/gas/arm/mve-vcvt-bad-3.l: New test.
	* testsuite/gas/arm/mve-vcvt-bad-3.s: New test.
	* testsuite/gas/arm/mve-vcvt-bad-4.d: New test.
	* testsuite/gas/arm/mve-vcvt-bad-4.l: New test.
	* testsuite/gas/arm/mve-vcvt-bad-4.s: New test.
	* testsuite/gas/arm/mve-vcvt-bad.d: New test.
	* testsuite/gas/arm/mve-vcvt-bad.l: New test.
	* testsuite/gas/arm/mve-vcvt-bad.s: New test.

[-- Attachment #2: 8.patch --]
[-- Type: text/x-patch, Size: 44451 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 08c9cac990af2c9bace573d197b9339ff382e999..59cf887e6ba007ed2f516fa6975d66bc88579107 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6778,6 +6778,7 @@ enum operand_parse_code
   OP_RNQ,	/* Neon quad precision register */
   OP_RNQMQ,	/* Neon quad or MVE vector register */
   OP_RVSD,	/* VFP single or double precision register */
+  OP_RVSDMQ,	/* VFP single, double precision or MVE vector register.  */
   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 */
@@ -7049,7 +7050,6 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
       if (op_parse_code >= OP_FIRST_OPTIONAL)
 	{
 	  /* Remember where we are in case we need to backtrack.  */
-	  gas_assert (!backtrack_pos);
 	  backtrack_pos = str;
 	  backtrack_error = inst.error;
 	  backtrack_index = i;
@@ -7117,6 +7117,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	try_rndq:
 	case OP_oRNDQ:
 	case OP_RNDQ:  po_reg_or_fail (REG_TYPE_NDQ);     break;
+	case OP_RVSDMQ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
+	  break;
+	try_rvsd:
 	case OP_RVSD:  po_reg_or_fail (REG_TYPE_VFSD);    break;
 	case OP_oRNSDQ:
 	case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ);    break;
@@ -17031,15 +17035,64 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 
   switch (rs)
     {
-    case NS_DDI:
     case NS_QQI:
+      if (mode == neon_cvt_mode_z
+	  && (flavour == neon_cvt_flavour_f16_s16
+	      || flavour == neon_cvt_flavour_f16_u16
+	      || flavour == neon_cvt_flavour_s16_f16
+	      || flavour == neon_cvt_flavour_u16_f16
+	      || flavour == neon_cvt_flavour_f32_u32
+	      || flavour == neon_cvt_flavour_f32_s32
+	      || flavour == neon_cvt_flavour_s32_f32
+	      || flavour == neon_cvt_flavour_u32_f32))
+	{
+	  if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
+	    return;
+	}
+      else if (mode == neon_cvt_mode_n)
+	{
+	  /* We are dealing with vcvt with the 'ne' condition.  */
+	  inst.cond = 0x1;
+	  inst.instruction = N_MNEM_vcvt;
+	  do_neon_cvt_1 (neon_cvt_mode_z);
+	  return;
+	}
+      /* fall through.  */
+    case NS_DDI:
       {
 	unsigned immbits;
 	unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
 			     0x0000100, 0x1000100, 0x0, 0x1000000};
 
-	if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
-	  return;
+	if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
+	    && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+	    return;
+
+	if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
+	  {
+	    constraint (inst.operands[2].present && inst.operands[2].imm == 0,
+			_("immediate value out of range"));
+	    switch (flavour)
+	      {
+		case neon_cvt_flavour_f16_s16:
+		case neon_cvt_flavour_f16_u16:
+		case neon_cvt_flavour_s16_f16:
+		case neon_cvt_flavour_u16_f16:
+		  constraint (inst.operands[2].imm > 16,
+			      _("immediate value out of range"));
+		  break;
+		case neon_cvt_flavour_f32_u32:
+		case neon_cvt_flavour_f32_s32:
+		case neon_cvt_flavour_s32_f32:
+		case neon_cvt_flavour_u32_f32:
+		  constraint (inst.operands[2].imm > 32,
+			      _("immediate value out of range"));
+		  break;
+		default:
+		  inst.error = BAD_FPU;
+		  return;
+	      }
+	  }
 
 	/* Fixed-point conversion with #0 immediate is encoded as an
 	   integer conversion.  */
@@ -17072,14 +17125,40 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
       }
       break;
 
-    case NS_DD:
     case NS_QQ:
+      if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
+	   || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
+	  && (flavour == neon_cvt_flavour_s16_f16
+	      || flavour == neon_cvt_flavour_u16_f16
+	      || flavour == neon_cvt_flavour_s32_f32
+	      || flavour == neon_cvt_flavour_u32_f32))
+	{
+	  if (check_simd_pred_availability (1,
+					    NEON_CHECK_CC | NEON_CHECK_ARCH8))
+	    return;
+	}
+      else if (mode == neon_cvt_mode_z
+	       && (flavour == neon_cvt_flavour_f16_s16
+		   || flavour == neon_cvt_flavour_f16_u16
+		   || flavour == neon_cvt_flavour_s16_f16
+		   || flavour == neon_cvt_flavour_u16_f16
+		   || flavour == neon_cvt_flavour_f32_u32
+		   || flavour == neon_cvt_flavour_f32_s32
+		   || flavour == neon_cvt_flavour_s32_f32
+		   || flavour == neon_cvt_flavour_u32_f32))
+	{
+	  if (check_simd_pred_availability (1,
+					    NEON_CHECK_CC | NEON_CHECK_ARCH))
+	    return;
+	}
+      /* fall through.  */
+    case NS_DD:
       if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
 	{
-	  NEON_ENCODE (FLOAT, inst);
-	  set_pred_insn_type (OUTSIDE_PRED_INSN);
 
-	  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
+	  NEON_ENCODE (FLOAT, inst);
+	  if (check_simd_pred_availability (1,
+					    NEON_CHECK_CC | NEON_CHECK_ARCH8))
 	    return;
 
 	  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
@@ -17109,8 +17188,11 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 
 	    NEON_ENCODE (INTEGER, inst);
 
-	    if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
-	      return;
+	  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
+	    {
+	      if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+		return;
+	    }
 
 	    if (flavour != neon_cvt_flavour_invalid)
 	      inst.instruction |= enctab[flavour];
@@ -17229,10 +17311,51 @@ static void
 do_neon_cvttb_1 (bfd_boolean t)
 {
   enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
-					  NS_DF, NS_DH, NS_NULL);
+					  NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
 
   if (rs == NS_NULL)
     return;
+  else if (rs == NS_QQ || rs == NS_QQI)
+    {
+      int single_to_half = 0;
+      if (check_simd_pred_availability (1, NEON_CHECK_ARCH))
+	return;
+
+      enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
+
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+	  && (flavour ==  neon_cvt_flavour_u16_f16
+	      || flavour ==  neon_cvt_flavour_s16_f16
+	      || flavour ==  neon_cvt_flavour_f16_s16
+	      || flavour ==  neon_cvt_flavour_f16_u16
+	      || flavour ==  neon_cvt_flavour_u32_f32
+	      || flavour ==  neon_cvt_flavour_s32_f32
+	      || flavour ==  neon_cvt_flavour_f32_s32
+	      || flavour ==  neon_cvt_flavour_f32_u32))
+	{
+	  inst.cond = 0xf;
+	  inst.instruction = N_MNEM_vcvt;
+	  set_pred_insn_type (INSIDE_VPT_INSN);
+	  do_neon_cvt_1 (neon_cvt_mode_z);
+	  return;
+	}
+      else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
+	single_to_half = 1;
+      else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
+	{
+	  first_error (BAD_FPU);
+	  return;
+	}
+
+      inst.instruction = 0xee3f0e01;
+      inst.instruction |= single_to_half << 28;
+      inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+      inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
+      inst.instruction |= t << 12;
+      inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+      inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
+      inst.is_neon = 1;
+    }
   else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
     {
       inst.error = NULL;
@@ -21839,10 +21962,6 @@ static const struct asm_opcode insns[] =
   nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD),		vsel),
   nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ),	vmaxnm),
   nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ),	vmaxnm),
-  nUF(vcvta,  _vcvta,  2, (RNSDQ, oRNSDQ),		neon_cvta),
-  nUF(vcvtn,  _vcvta,  2, (RNSDQ, oRNSDQ),		neon_cvtn),
-  nUF(vcvtp,  _vcvta,  2, (RNSDQ, oRNSDQ),		neon_cvtp),
-  nUF(vcvtm,  _vcvta,  2, (RNSDQ, oRNSDQ),		neon_cvtm),
   nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintr),
   nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintz),
   nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintx),
@@ -22503,10 +22622,10 @@ static const struct asm_opcode insns[] =
  NCE(vstmia,    c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
  NCE(vstmdb,    d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
 
- nCEF(vcvt,     _vcvt,   3, (RNSDQ, RNSDQ, oI32z), neon_cvt),
+ mnCEF(vcvt,     _vcvt,   3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
  nCEF(vcvtr,    _vcvt,   2, (RNSDQ, RNSDQ), neon_cvtr),
- NCEF(vcvtb,	eb20a40, 2, (RVSD, RVSD), neon_cvtb),
- NCEF(vcvtt,	eb20a40, 2, (RVSD, RVSD), neon_cvtt),
+ MNCEF(vcvtb,	eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
+ MNCEF(vcvtt,	eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
 
 
   /* NOTE: All VMOV encoding is special-cased!  */
@@ -23266,7 +23385,14 @@ static const struct asm_opcode insns[] =
  MNCEF(vabs,  1b10300,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
  MNCEF(vneg,  1b10380,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
 
-#undef ARM_VARIANT
+#undef  ARM_VARIANT
+#define ARM_VARIANT    & fpu_vfp_ext_armv8xd
+ mnUF(vcvta,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvta),
+ mnUF(vcvtp,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvtp),
+ mnUF(vcvtn,  _vcvta,  3, (RNSDQMQ, oRNSDQMQ, oI32z),	neon_cvtn),
+ mnUF(vcvtm,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvtm),
+
+#undef	ARM_VARIANT
 #define ARM_VARIANT & fpu_neon_ext_v1
  mnUF(vabd,      _vabd,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
  mnUF(vabdl,     _vabdl,	  3, (RNQMQ, RNDMQ, RNDMQ),   neon_dyadic_long),
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-1.d b/gas/testsuite/gas/arm/mve-vcvt-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..15ba724a6fdd4a03e4aaa1e85e796b2aa882b338
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-1.d
@@ -0,0 +1,6 @@
+#name: bad MVE VCVT (between floating-point and fixed-point) instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcvt-bad-1.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-1.l b/gas/testsuite/gas/arm/mve-vcvt-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..4c727d305b4c5d1bf1b21dd11c28a361ea3563c7
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-1.l
@@ -0,0 +1,75 @@
+[^:]*: Assembler messages:
+[^:]*:12: Error: immediate value out of range -- `vcvt.f16.s16 q0,q1,#0'
+[^:]*:13: Error: immediate value out of range -- `vcvt.s16.f16 q0,q1,#0'
+[^:]*:14: Error: immediate value out of range -- `vcvt.f16.u16 q0,q1,#0'
+[^:]*:15: Error: immediate value out of range -- `vcvt.u16.f16 q0,q1,#0'
+[^:]*:16: Error: immediate value out of range -- `vcvt.f16.s16 q0,q1,#17'
+[^:]*:17: Error: immediate value out of range -- `vcvt.s16.f16 q0,q1,#17'
+[^:]*:18: Error: immediate value out of range -- `vcvt.f16.u16 q0,q1,#17'
+[^:]*:19: Error: immediate value out of range -- `vcvt.u16.f16 q0,q1,#17'
+[^:]*:20: Error: immediate value out of range -- `vcvt.f32.s32 q0,q1,#0'
+[^:]*:21: Error: immediate value out of range -- `vcvt.s32.f32 q0,q1,#0'
+[^:]*:22: Error: immediate value out of range -- `vcvt.f32.u32 q0,q1,#0'
+[^:]*:23: Error: immediate value out of range -- `vcvt.u32.f32 q0,q1,#0'
+[^:]*:24: Error: immediate value out of range -- `vcvt.f32.s32 q0,q1,#33'
+[^:]*:25: Error: immediate value out of range -- `vcvt.s32.f32 q0,q1,#33'
+[^:]*:26: Error: immediate value out of range -- `vcvt.f32.u32 q0,q1,#33'
+[^:]*:27: Error: immediate value out of range -- `vcvt.u32.f32 q0,q1,#33'
+[^:]*: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
+[^:]*: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
+[^:]*: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
+[^:]*: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
+[^:]*: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
+[^:]*: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
+[^:]*: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
+[^:]*: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: Error: bad type in SIMD instruction -- `vcvt.f64.u64 q0,q1,#1'
+[^:]*:30: Error: bad type in SIMD instruction -- `vcvt.u64.f64 q0,q1,#1'
+[^:]*:31: Error: bad type in SIMD instruction -- `vcvt.f64.s64 q0,q1,#1'
+[^:]*:32: Error: bad type in SIMD instruction -- `vcvt.s64.f64 q0,q1,#1'
+[^:]*:34: Error: syntax error -- `vcvteq.f32.u32 q0,q1,#1'
+[^:]*:35: Error: syntax error -- `vcvteq.f32.u32 q0,q1,#1'
+[^:]*:37: Error: syntax error -- `vcvteq.f32.u32 q0,q1,#1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vcvt.f32.u32 q0,q1,#1'
+[^:]*:40: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtt.f32.u32 q0,q1,#1'
+
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-1.s b/gas/testsuite/gas/arm/mve-vcvt-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..401014ac842336c8f4535541ec06071e7d9a3cdc
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-1.s
@@ -0,0 +1,40 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .f16.s16, .s16.f16, .f16.u16, .u16.f16, .f32.s32, .s32.f32, .f32.u32, .u32.f32
+it \cond
+vcvt\size q0, q1, #1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcvt.f16.s16 q0, q1, #0
+vcvt.s16.f16 q0, q1, #0
+vcvt.f16.u16 q0, q1, #0
+vcvt.u16.f16 q0, q1, #0
+vcvt.f16.s16 q0, q1, #17
+vcvt.s16.f16 q0, q1, #17
+vcvt.f16.u16 q0, q1, #17
+vcvt.u16.f16 q0, q1, #17
+vcvt.f32.s32 q0, q1, #0
+vcvt.s32.f32 q0, q1, #0
+vcvt.f32.u32 q0, q1, #0
+vcvt.u32.f32 q0, q1, #0
+vcvt.f32.s32 q0, q1, #33
+vcvt.s32.f32 q0, q1, #33
+vcvt.f32.u32 q0, q1, #33
+vcvt.u32.f32 q0, q1, #33
+cond
+vcvt.f64.u64 q0, q1, #1
+vcvt.u64.f64 q0, q1, #1
+vcvt.f64.s64 q0, q1, #1
+vcvt.s64.f64 q0, q1, #1
+it eq
+vcvteq.f32.u32 q0, q1, #1
+vcvteq.f32.u32 q0, q1, #1
+vpst
+vcvteq.f32.u32 q0, q1, #1
+vpst
+vcvt.f32.u32 q0, q1, #1
+vcvtt.f32.u32 q0, q1, #1
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-2.d b/gas/testsuite/gas/arm/mve-vcvt-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..eb98daa7b25d38dbe52b485fca1b93e0d256ab4a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCVT (between floating-point and integer) instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcvt-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-2.l b/gas/testsuite/gas/arm/mve-vcvt-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..a608fd45ecad3fe8935bf52029e3b2e3232f16d3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-2.l
@@ -0,0 +1,58 @@
+[^:]*: Assembler messages:
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Error: bad type in SIMD instruction -- `vcvt.u64.f64 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vcvt.f64.u64 q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vcvt.s64.f64 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vcvt.f64.s64 q0,q1'
+[^:]*:18: Error: syntax error -- `vcvteq.f32.s32 q0,q1'
+[^:]*:19: Error: syntax error -- `vcvteq.f32.s32 q0,q1'
+[^:]*:21: Error: syntax error -- `vcvteq.f32.s32 q0,q1'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcvt.f32.s32 q0,q1'
+[^:]*:24: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtt.f32.s32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-2.s b/gas/testsuite/gas/arm/mve-vcvt-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..e3dc08b6faf5e364b9ebae33be830932e9ee718c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-2.s
@@ -0,0 +1,24 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .f16.s16, .s16.f16, .f16.u16, .u16.f16, .f32.s32, .s32.f32, .f32.u32, .u32.f32
+it \cond
+vcvt\size q0, q1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vcvt.u64.f64 q0, q1
+vcvt.f64.u64 q0, q1
+vcvt.s64.f64 q0, q1
+vcvt.f64.s64 q0, q1
+it eq
+vcvteq.f32.s32 q0, q1
+vcvteq.f32.s32 q0, q1
+vpst
+vcvteq.f32.s32 q0, q1
+vpst
+vcvt.f32.s32 q0, q1
+vcvtt.f32.s32 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-3.d b/gas/testsuite/gas/arm/mve-vcvt-bad-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..b85a41e015f17810c36b393820902e9e23b811f2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-3.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCVT (between single and half precision floating-point) instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcvt-bad-3.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-3.l b/gas/testsuite/gas/arm/mve-vcvt-bad-3.l
new file mode 100644
index 0000000000000000000000000000000000000000..c51fd434ea015fab4bea0a080503d789f0122287
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-3.l
@@ -0,0 +1,39 @@
+[^:]*: Assembler messages:
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: bad type in SIMD instruction -- `vcvt.f64.f16 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vcvt.f64.f32 q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vcvt.f16.f64 q0,q1'
+[^:]*:18: Error: bad type in SIMD instruction -- `vcvt.f32.f64 q0,q1'
+[^:]*:20: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:21: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:23: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:24: Error: vector predicated instruction should be in VPT/VPST block -- `vcvttt.f16.f32 q0,q1'
+[^:]*:26: Error: instruction missing MVE vector predication code -- `vcvtt.f16.f32 q0,q1'
+[^:]*:28: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:29: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:31: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:32: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtbt.f16.f32 q0,q1'
+[^:]*:34: Error: instruction missing MVE vector predication code -- `vcvtb.f16.f32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-3.s b/gas/testsuite/gas/arm/mve-vcvt-bad-3.s
new file mode 100644
index 0000000000000000000000000000000000000000..6552cd21b9ed135b0a088d7c878d86b2e792bbf9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-3.s
@@ -0,0 +1,34 @@
+.macro cond
+.irp top, t, b
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .f16.f32, .f32.f16
+it \cond
+vcvt\top\size q0, q1
+.endr
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vcvt.f64.f16 q0, q1
+vcvt.f64.f32 q0, q1
+vcvt.f16.f64 q0, q1
+vcvt.f32.f64 q0, q1
+it eq
+vcvtteq.f16.f32 q0, q1
+vcvtteq.f16.f32 q0, q1
+vpst
+vcvtteq.f16.f32 q0, q1
+vcvttt.f16.f32 q0, q1
+vpst
+vcvtt.f16.f32 q0, q1
+it eq
+vcvtbeq.f16.f32 q0, q1
+vcvtbeq.f16.f32 q0, q1
+vpst
+vcvtbeq.f16.f32 q0, q1
+vcvtbt.f16.f32 q0, q1
+vpst
+vcvtb.f16.f32 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-4.d b/gas/testsuite/gas/arm/mve-vcvt-bad-4.d
new file mode 100644
index 0000000000000000000000000000000000000000..2b46152d988a642d869e699d66be2f13958ed085
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-4.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCVT (from floating-point to integer) instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcvt-bad-4.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-4.l b/gas/testsuite/gas/arm/mve-vcvt-bad-4.l
new file mode 100644
index 0000000000000000000000000000000000000000..36d423af26d91da7f87cf3860aaadb4b47c64678
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-4.l
@@ -0,0 +1,133 @@
+[^:]*: Assembler messages:
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: bad type in SIMD instruction -- `vcvta.s64.f64 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vcvta.u64.f64 q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vcvta.f64.s64 q0,q1'
+[^:]*:18: Error: bad type in SIMD instruction -- `vcvta.f64.u64 q0,q1'
+[^:]*:19: Error: bad type in SIMD instruction -- `vcvtn.s64.f64 q0,q1'
+[^:]*:20: Error: bad type in SIMD instruction -- `vcvtn.u64.f64 q0,q1'
+[^:]*:21: Error: bad type in SIMD instruction -- `vcvtn.f64.s64 q0,q1'
+[^:]*:22: Error: bad type in SIMD instruction -- `vcvtn.f64.u64 q0,q1'
+[^:]*:23: Error: bad type in SIMD instruction -- `vcvtp.s64.f64 q0,q1'
+[^:]*:24: Error: bad type in SIMD instruction -- `vcvtp.u64.f64 q0,q1'
+[^:]*:25: Error: bad type in SIMD instruction -- `vcvtp.f64.s64 q0,q1'
+[^:]*:26: Error: bad type in SIMD instruction -- `vcvtp.f64.u64 q0,q1'
+[^:]*:27: Error: bad type in SIMD instruction -- `vcvtm.s64.f64 q0,q1'
+[^:]*:28: Error: bad type in SIMD instruction -- `vcvtm.u64.f64 q0,q1'
+[^:]*:29: Error: bad type in SIMD instruction -- `vcvtm.f64.s64 q0,q1'
+[^:]*:30: Error: bad type in SIMD instruction -- `vcvtm.f64.u64 q0,q1'
+[^:]*:32: Error: syntax error -- `vcvtaeq.s32.f32 q0,q1'
+[^:]*:33: Error: syntax error -- `vcvtaeq.s32.f32 q0,q1'
+[^:]*:35: Error: syntax error -- `vcvtaeq.s32.f32 q0,q1'
+[^:]*:36: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtat.s32.f32 q0,q1'
+[^:]*:38: Error: instruction missing MVE vector predication code -- `vcvta.s32.f32 q0,q1'
+[^:]*:40: Error: syntax error -- `vcvtneq.s32.f32 q0,q1'
+[^:]*:41: Error: syntax error -- `vcvtneq.s32.f32 q0,q1'
+[^:]*:43: Error: syntax error -- `vcvtneq.s32.f32 q0,q1'
+[^:]*:44: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtnt.s32.f32 q0,q1'
+[^:]*:46: Error: instruction missing MVE vector predication code -- `vcvtn.s32.f32 q0,q1'
+[^:]*:48: Error: syntax error -- `vcvtpeq.s32.f32 q0,q1'
+[^:]*:49: Error: syntax error -- `vcvtpeq.s32.f32 q0,q1'
+[^:]*:51: Error: syntax error -- `vcvtpeq.s32.f32 q0,q1'
+[^:]*:52: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtpt.s32.f32 q0,q1'
+[^:]*:54: Error: instruction missing MVE vector predication code -- `vcvtp.s32.f32 q0,q1'
+[^:]*:56: Error: syntax error -- `vcvtmeq.s32.f32 q0,q1'
+[^:]*:57: Error: syntax error -- `vcvtmeq.s32.f32 q0,q1'
+[^:]*:59: Error: syntax error -- `vcvtmeq.s32.f32 q0,q1'
+[^:]*:60: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtmt.s32.f32 q0,q1'
+[^:]*:62: Error: instruction missing MVE vector predication code -- `vcvtm.s32.f32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad-4.s b/gas/testsuite/gas/arm/mve-vcvt-bad-4.s
new file mode 100644
index 0000000000000000000000000000000000000000..cffb6e4076e85b002cfc8ffda811f41eb95ad1b8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad-4.s
@@ -0,0 +1,62 @@
+.macro cond
+.irp round, a, n, p, m
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .s16.f16, .u16.f16, .s32.f32, .u32.f32
+it \cond
+vcvt\round\size q0, q1
+.endr
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vcvta.s64.f64 q0, q1
+vcvta.u64.f64 q0, q1
+vcvta.f64.s64 q0, q1
+vcvta.f64.u64 q0, q1
+vcvtn.s64.f64 q0, q1
+vcvtn.u64.f64 q0, q1
+vcvtn.f64.s64 q0, q1
+vcvtn.f64.u64 q0, q1
+vcvtp.s64.f64 q0, q1
+vcvtp.u64.f64 q0, q1
+vcvtp.f64.s64 q0, q1
+vcvtp.f64.u64 q0, q1
+vcvtm.s64.f64 q0, q1
+vcvtm.u64.f64 q0, q1
+vcvtm.f64.s64 q0, q1
+vcvtm.f64.u64 q0, q1
+it eq
+vcvtaeq.s32.f32 q0, q1
+vcvtaeq.s32.f32 q0, q1
+vpst
+vcvtaeq.s32.f32 q0, q1
+vcvtat.s32.f32 q0, q1
+vpst
+vcvta.s32.f32 q0, q1
+it eq
+vcvtneq.s32.f32 q0, q1
+vcvtneq.s32.f32 q0, q1
+vpst
+vcvtneq.s32.f32 q0, q1
+vcvtnt.s32.f32 q0, q1
+vpst
+vcvtn.s32.f32 q0, q1
+it eq
+vcvtpeq.s32.f32 q0, q1
+vcvtpeq.s32.f32 q0, q1
+vpst
+vcvtpeq.s32.f32 q0, q1
+vcvtpt.s32.f32 q0, q1
+vpst
+vcvtp.s32.f32 q0, q1
+it eq
+vcvtmeq.s32.f32 q0, q1
+vcvtmeq.s32.f32 q0, q1
+vpst
+vcvtmeq.s32.f32 q0, q1
+vcvtmt.s32.f32 q0, q1
+vpst
+vcvtm.s32.f32 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad.d b/gas/testsuite/gas/arm/mve-vcvt-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..dd0ec53319b46562663ab98b42617e5657c23be6
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad.d
@@ -0,0 +1,6 @@
+#name: bad MVE VCVT instructions 
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcvt-bad.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad.l b/gas/testsuite/gas/arm/mve-vcvt-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..7c4ea69c4a8cb0916f4273ce13f117db174d11eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad.l
@@ -0,0 +1,77 @@
+[^:]*: Assembler messages:
+[^:]*:11: Error: immediate value out of range -- `vcvt.f16.s16 q0,q1,#0'
+[^:]*:12: Error: immediate value out of range -- `vcvt.f16.s16 q0,q1,#17'
+[^:]*:13: Error: immediate value out of range -- `vcvt.f16.u16 q0,q1,#0'
+[^:]*:14: Error: immediate value out of range -- `vcvt.f16.u16 q0,q1,#17'
+[^:]*:15: Error: immediate value out of range -- `vcvt.s16.f16 q0,q1,#0'
+[^:]*:16: Error: immediate value out of range -- `vcvt.s16.f16 q0,q1,#17'
+[^:]*:17: Error: immediate value out of range -- `vcvt.u16.f16 q0,q1,#0'
+[^:]*:18: Error: immediate value out of range -- `vcvt.u16.f16 q0,q1,#17'
+[^:]*:19: Error: immediate value out of range -- `vcvt.f32.s32 q0,q1,#0'
+[^:]*:20: Error: immediate value out of range -- `vcvt.f32.s32 q0,q1,#33'
+[^:]*:21: Error: immediate value out of range -- `vcvt.f32.u32 q0,q1,#0'
+[^:]*:22: Error: immediate value out of range -- `vcvt.f32.u32 q0,q1,#33'
+[^:]*:23: Error: immediate value out of range -- `vcvt.s32.f32 q0,q1,#0'
+[^:]*:24: Error: immediate value out of range -- `vcvt.s32.f32 q0,q1,#33'
+[^:]*:25: Error: immediate value out of range -- `vcvt.u32.f32 q0,q1,#0'
+[^:]*:26: Error: immediate value out of range -- `vcvt.u32.f32 q0,q1,#33'
+[^:]*:27: Error: bad type in SIMD instruction -- `vcvt.f64.s64 q0,q1,#1'
+[^:]*:28: Error: bad type in SIMD instruction -- `vcvt.f64.u64 q0,q1,#1'
+[^:]*:29: Error: bad type in SIMD instruction -- `vcvt.s64.f64 q0,q1,#1'
+[^:]*:30: Error: bad type in SIMD instruction -- `vcvt.u64.f64 q0,q1,#1'
+[^:]*: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
+[^:]*:33: Error: syntax error -- `vcvteq.f16.s16 q0,q1,#1'
+[^:]*:34: Error: syntax error -- `vcvteq.f16.s16 q0,q1,#1'
+[^:]*:36: Error: syntax error -- `vcvteq.f16.s16 q0,q1,#1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtt.f16.s16 q0,q1,#1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vcvt.f16.s16 q0,q1,#1'
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:48: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:49: Error: bad type in SIMD instruction -- `vcvt.f64.s64 q0,q1'
+[^:]*:50: Error: bad type in SIMD instruction -- `vcvt.f64.u64 q0,q1'
+[^:]*:51: Error: bad type in SIMD instruction -- `vcvt.s64.f64 q0,q1'
+[^:]*:52: Error: bad type in SIMD instruction -- `vcvt.u64.f64 q0,q1'
+[^:]*:54: Error: syntax error -- `vcvteq.u32.f32 q0,q1'
+[^:]*:55: Error: syntax error -- `vcvteq.u32.f32 q0,q1'
+[^:]*:57: Error: syntax error -- `vcvteq.u32.f32 q0,q1'
+[^:]*:58: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtt.u32.f32 q0,q1'
+[^:]*:60: Error: instruction missing MVE vector predication code -- `vcvt.u32.f32 q0,q1'
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:69: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Error: bad type in SIMD instruction -- `vcvtb.f16.f64 q0,q1'
+[^:]*:71: Error: bad type in SIMD instruction -- `vcvtb.f64.f16 q0,q1'
+[^:]*:72: Error: bad type in SIMD instruction -- `vcvtb.f32.f64 q0,q1'
+[^:]*:73: Error: bad type in SIMD instruction -- `vcvtb.f64.f32 q0,q1'
+[^:]*:75: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:76: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:78: Error: syntax error -- `vcvtbeq.f16.f32 q0,q1'
+[^:]*:79: Error: vector predicated instruction should be in VPT/VPST block -- `vcvtbt.f16.f32 q0,q1'
+[^:]*:81: Error: instruction missing MVE vector predication code -- `vcvtb.f16.f32 q0,q1'
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:82: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:83: Error: bad type in SIMD instruction -- `vcvtt.f16.f64 q0,q1'
+[^:]*:84: Error: bad type in SIMD instruction -- `vcvtt.f64.f16 q0,q1'
+[^:]*:85: Error: bad type in SIMD instruction -- `vcvtt.f32.f64 q0,q1'
+[^:]*:86: Error: bad type in SIMD instruction -- `vcvtt.f64.f32 q0,q1'
+[^:]*:88: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:89: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:91: Error: syntax error -- `vcvtteq.f16.f32 q0,q1'
+[^:]*:92: Error: vector predicated instruction should be in VPT/VPST block -- `vcvttt.f16.f32 q0,q1'
+[^:]*:94: Error: instruction missing MVE vector predication code -- `vcvtt.f16.f32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcvt-bad.s b/gas/testsuite/gas/arm/mve-vcvt-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..302fe88223c97e1d48123a5f120fbfbb5cf14fed
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcvt-bad.s
@@ -0,0 +1,94 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcvt\().f16.s16 q0, q1, #1
+.endr
+.endm
+
+.syntax unified
+.thumb
+
+vcvt.f16.s16 q0, q1, #0
+vcvt.f16.s16 q0, q1, #17
+vcvt.f16.u16 q0, q1, #0
+vcvt.f16.u16 q0, q1, #17
+vcvt.s16.f16 q0, q1, #0
+vcvt.s16.f16 q0, q1, #17
+vcvt.u16.f16 q0, q1, #0
+vcvt.u16.f16 q0, q1, #17
+vcvt.f32.s32 q0, q1, #0
+vcvt.f32.s32 q0, q1, #33
+vcvt.f32.u32 q0, q1, #0
+vcvt.f32.u32 q0, q1, #33
+vcvt.s32.f32 q0, q1, #0
+vcvt.s32.f32 q0, q1, #33
+vcvt.u32.f32 q0, q1, #0
+vcvt.u32.f32 q0, q1, #33
+vcvt.f64.s64 q0, q1, #1
+vcvt.f64.u64 q0, q1, #1
+vcvt.s64.f64 q0, q1, #1
+vcvt.u64.f64 q0, q1, #1
+cond1
+it eq
+vcvteq.f16.s16 q0, q1, #1
+vcvteq.f16.s16 q0, q1, #1
+vpst
+vcvteq.f16.s16 q0, q1, #1
+vcvtt.f16.s16 q0, q1, #1
+vpst
+vcvt.f16.s16 q0, q1, #1
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcvt\().f16.s16 q0, q1
+.endr
+.endm
+
+cond2
+vcvt.f64.s64 q0, q1
+vcvt.f64.u64 q0, q1
+vcvt.s64.f64 q0, q1
+vcvt.u64.f64 q0, q1
+it eq
+vcvteq.u32.f32 q0, q1
+vcvteq.u32.f32 q0, q1
+vpst
+vcvteq.u32.f32 q0, q1
+vcvtt.u32.f32 q0, q1
+vpst
+vcvt.u32.f32 q0, q1
+
+.macro cond3 mnem
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\mnem\().f16.f32 q0, q1
+.endr
+.endm
+
+cond3 vcvtb
+vcvtb.f16.f64 q0, q1
+vcvtb.f64.f16 q0, q1
+vcvtb.f32.f64 q0, q1
+vcvtb.f64.f32 q0, q1
+it eq
+vcvtbeq.f16.f32 q0, q1
+vcvtbeq.f16.f32 q0, q1
+vpst
+vcvtbeq.f16.f32 q0, q1
+vcvtbt.f16.f32 q0, q1
+vpst
+vcvtb.f16.f32 q0, q1
+cond3 vcvtt
+vcvtt.f16.f64 q0, q1
+vcvtt.f64.f16 q0, q1
+vcvtt.f32.f64 q0, q1
+vcvtt.f64.f32 q0, q1
+it eq
+vcvtteq.f16.f32 q0, q1
+vcvtteq.f16.f32 q0, q1
+vpst
+vcvtteq.f16.f32 q0, q1
+vcvttt.f16.f32 q0, q1
+vpst
+vcvtt.f16.f32 q0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 10/57][Arm][GAS] Add support for MVE instructions: vcmp and vpt
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (7 preceding siblings ...)
  2019-05-01 17:02 ` [PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt Andre Vieira (lists)
@ 2019-05-01 17:03 ` Andre Vieira (lists)
  2019-05-01 17:03 ` [PATCH 9/57][Arm][GAS] Add support for MVE instructions: vmov Andre Vieira (lists)
                   ` (51 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:03 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1326 bytes --]

Hi,

This patch adds support for MVE instructions VCMP and VPT. These 
instructions allow the use of the scalar ZR (zero) register, this is 
encoded as register 15.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (MVE_BAD_QREG): New error message.
	(enum operand_parse_code): Define new operand.
	(parse_operands): Handle new operand.
	(do_mve_vpt): Change for VPT blocks.
	(NEON_SHAPE_DEF): New shape.
	(neon_logbits): Moved.
	(LOW4): Moved
	(HI1): Moved
	(mve_get_vcmp_vpt_cond): New function to translate vpt
         conditions.
	(do_mve_vcmp): New encoding function.
	(do_vfp_nsyn_cmp): Changed to support MVE variants.
	(insns): Change to support MVE variants of vcmp and add
         vpt.
	* testsuite/gas/arm/mve-vcmp-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcmp-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcmp-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.s: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.d: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.l: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.s: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.d: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.l: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.s: New test.

[-- Attachment #2: 10.patch --]
[-- Type: text/x-patch, Size: 27928 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a212380c9d01bafc1326b0b10b82d2534b54efc6..b6ca4a48626f199347b7f1b2d281065198fd43ca 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -522,6 +522,7 @@ struct arm_it
     unsigned isvec      : 1;  /* Is a single, double or quad VFP/Neon reg.  */
     unsigned isquad     : 1;  /* Operand is SIMD quad register.  */
     unsigned issingle   : 1;  /* Operand is VFP single-precision register.  */
+    unsigned iszr	: 1;  /* Operand is ZR register.  */
     unsigned hasreloc	: 1;  /* Operand has relocation suffix.  */
     unsigned writeback	: 1;  /* Operand has trailing !  */
     unsigned preind	: 1;  /* Preindexed address.  */
@@ -649,6 +650,7 @@ enum arm_reg_type
   REG_TYPE_MMXWCG,
   REG_TYPE_XSCALE,
   REG_TYPE_RNB,
+  REG_TYPE_ZR
 };
 
 /* Structure for a hash table entry for a register.
@@ -901,6 +903,7 @@ struct asm_opcode
 #define BAD_MVE_SRCDEST	_("Warning: 32-bit element size and same destination "\
 			  "and source operands makes instruction UNPREDICTABLE")
 #define BAD_EL_TYPE	_("bad element type for instruction")
+#define MVE_BAD_QREG	_("MVE vector register Q[0..7] expected")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -6897,6 +6900,7 @@ enum operand_parse_code
   OP_RNQ,	/* Neon quad precision register */
   OP_RNQMQ,	/* Neon quad or MVE vector register.  */
   OP_RVSD,	/* VFP single or double precision register */
+  OP_RVSD_COND,	/* VFP single, double precision register or condition code.  */
   OP_RVSDMQ,	/* VFP single, double precision or MVE vector register.  */
   OP_RNSD,      /* Neon single or double precision register */
   OP_RNDQ,      /* Neon double or quad precision register */
@@ -6920,6 +6924,7 @@ enum operand_parse_code
   OP_RNSDQMQR,	/* Neon single, double or quad register, MVE vector register or
 		   GPR (no SP/SP)  */
   OP_RMQ,	/* MVE vector register.  */
+  OP_RMQRZ,	/* MVE vector or ARM register including ZR.  */
 
   /* New operands for Armv8.1-M Mainline.  */
   OP_LR,	/* ARM LR register */
@@ -6941,6 +6946,8 @@ enum operand_parse_code
   OP_RNDQ_I0,   /* Neon D or Q reg, or immediate zero.  */
   OP_RVSD_I0,	/* VFP S or D reg, or immediate zero.  */
   OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero.  */
+  OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
+		    zero.  */
   OP_RR_RNSC,   /* ARM reg or Neon scalar.  */
   OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar.  */
   OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar.  */
@@ -7031,6 +7038,8 @@ enum operand_parse_code
   OP_oROR,	 /* ROR 0/8/16/24 */
   OP_oBARRIER_I15, /* Option argument for a barrier instruction.  */
 
+  OP_oRMQRZ,	/* optional MVE vector or ARM register including ZR.  */
+
   /* Some pre-defined mixed (ARM/THUMB) operands.  */
   OP_RR_npcsp		= MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
   OP_RRnpc_npcsp	= MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
@@ -7080,6 +7089,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
       inst.operands[i].isvec = (rtype == REG_TYPE_VFS		\
 			     || rtype == REG_TYPE_VFD		\
 			     || rtype == REG_TYPE_NQ);		\
+      inst.operands[i].iszr = (rtype == REG_TYPE_ZR);		\
     }								\
   while (0)
 
@@ -7098,6 +7108,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
       inst.operands[i].isvec = (rtype == REG_TYPE_VFS		\
 			     || rtype == REG_TYPE_VFD		\
 			     || rtype == REG_TYPE_NQ);		\
+      inst.operands[i].iszr = (rtype == REG_TYPE_ZR);		\
     }								\
   while (0)
 
@@ -7243,6 +7254,9 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  break;
 	try_rvsd:
 	case OP_RVSD:  po_reg_or_fail (REG_TYPE_VFSD);    break;
+	case OP_RVSD_COND:
+	  po_reg_or_goto (REG_TYPE_VFSD, try_cond);
+	  break;
 	case OP_oRNSDQ:
 	case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ);    break;
 	case OP_RNSDQMQR:
@@ -7277,6 +7291,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
 	  break;
 
+	case OP_RSVDMQ_FI0:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
+	  break;
+	try_rsvd_fi0:
 	case OP_RSVD_FI0:
 	  {
 	    po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
@@ -7551,6 +7569,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_CPSF:	 val = parse_cps_flags (&str);		break;
 	case OP_ENDI:	 val = parse_endian_specifier (&str);	break;
 	case OP_oROR:	 val = parse_ror (&str);		break;
+	try_cond:
 	case OP_COND:	 val = parse_cond (&str);		break;
 	case OP_oBARRIER_I15:
 	  po_barrier_or_imm (str); break;
@@ -7724,6 +7743,17 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
 	  break;
 
+	case OP_RMQRZ:
+	case OP_oRMQRZ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
+	  break;
+	try_rr_zr:
+	  po_reg_or_goto (REG_TYPE_RN, ZR);
+	  break;
+	ZR:
+	  po_reg_or_fail (REG_TYPE_ZR);
+	  break;
+
 	default:
 	  as_fatal (_("unhandled operand code %d"), op_parse_code);
 	}
@@ -7767,10 +7797,12 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    inst.error = BAD_PC;
 	  break;
 
+	case OP_RVSD_COND:
 	case OP_VLDR:
 	  if (inst.operands[i].isreg)
 	    break;
 	/* fall through.  */
+
 	case OP_CPSF:
 	case OP_ENDI:
 	case OP_oROR:
@@ -7799,6 +7831,12 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    inst.error = _("operand must be LR register");
 	  break;
 
+	case OP_RMQRZ:
+	case OP_oRMQRZ:
+	  if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
+	    inst.error = BAD_PC;
+	  break;
+
 	case OP_RRe:
 	  if (inst.operands[i].isreg
 	      && (inst.operands[i].reg & 0x00000001) != 0)
@@ -12009,18 +12047,6 @@ do_t_it (void)
   inst.instruction |= cond << 4;
 }
 
-static void
-do_mve_vpt (void)
-{
-  /* We are dealing with a vector predicated block.  */
-  set_pred_insn_type (VPT_INSN);
-  now_pred.cc = 0;
-  now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
-		  | ((inst.instruction & 0xe000) >> 13);
-  now_pred.warn_deprecated = FALSE;
-  now_pred.type = VECTOR_PRED;
-}
-
 /* Helper function used for both push/pop and ldm/stm.  */
 static void
 encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
@@ -14279,6 +14305,8 @@ NEON_ENC_TAB
 #define NEON_SHAPE_DEF			\
   X(4, (R, R, S, S), QUAD),		\
   X(4, (S, S, R, R), QUAD),		\
+  X(3, (I, Q, Q), QUAD),		\
+  X(3, (I, Q, R), QUAD),		\
   X(3, (R, Q, Q), QUAD),		\
   X(3, (D, D, D), DOUBLE),		\
   X(3, (Q, Q, Q), QUAD),		\
@@ -15317,10 +15345,239 @@ do_vfp_nsyn_nmul (void)
 
 }
 
+/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
+   (0, 1, 2, 3).  */
+
+static unsigned
+neon_logbits (unsigned x)
+{
+  return ffs (x) - 4;
+}
+
+#define LOW4(R) ((R) & 0xf)
+#define HI1(R) (((R) >> 4) & 1)
+
+static unsigned
+mve_get_vcmp_vpt_cond (struct neon_type_el et)
+{
+  switch (et.type)
+    {
+    default:
+      first_error (BAD_EL_TYPE);
+      return 0;
+    case NT_float:
+      switch (inst.operands[0].imm)
+	{
+	default:
+	  first_error (_("invalid condition"));
+	  return 0;
+	case 0x0:
+	  /* eq.  */
+	  return 0;
+	case 0x1:
+	  /* ne.  */
+	  return 1;
+	case 0xa:
+	  /* ge/  */
+	  return 4;
+	case 0xb:
+	  /* lt.  */
+	  return 5;
+	case 0xc:
+	  /* gt.  */
+	  return 6;
+	case 0xd:
+	  /* le.  */
+	  return 7;
+	}
+    case NT_integer:
+      /* only accept eq and ne.  */
+      if (inst.operands[0].imm > 1)
+	{
+	  first_error (_("invalid condition"));
+	  return 0;
+	}
+      return inst.operands[0].imm;
+    case NT_unsigned:
+      if (inst.operands[0].imm == 0x2)
+	return 2;
+      else if (inst.operands[0].imm == 0x8)
+	return 3;
+      else
+	{
+	  first_error (_("invalid condition"));
+	  return 0;
+	}
+    case NT_signed:
+      switch (inst.operands[0].imm)
+	{
+	  default:
+	    first_error (_("invalid condition"));
+	    return 0;
+	  case 0xa:
+	    /* ge.  */
+	    return 4;
+	  case 0xb:
+	    /* lt.  */
+	    return 5;
+	  case 0xc:
+	    /* gt.  */
+	    return 6;
+	  case 0xd:
+	    /* le.  */
+	    return 7;
+	}
+    }
+  /* Should be unreachable.  */
+  abort ();
+}
+
+static void
+do_mve_vpt (void)
+{
+  /* We are dealing with a vector predicated block.  */
+  if (inst.operands[0].present)
+    {
+      enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
+      struct neon_type_el et
+	= neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
+			   N_EQK);
+
+      unsigned fcond = mve_get_vcmp_vpt_cond (et);
+
+      constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+      if (et.type == NT_invtype)
+	return;
+
+      if (et.type == NT_float)
+	{
+	  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
+		      BAD_FPU);
+	  constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
+	  inst.instruction |= (et.size == 16) << 28;
+	  inst.instruction |= 0x3 << 20;
+	}
+      else
+	{
+	  constraint (et.size != 8 && et.size != 16 && et.size != 32,
+		      BAD_EL_TYPE);
+	  inst.instruction |= 1 << 28;
+	  inst.instruction |= neon_logbits (et.size) << 20;
+	}
+
+      if (inst.operands[2].isquad)
+	{
+	  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+	  inst.instruction |= LOW4 (inst.operands[2].reg);
+	  inst.instruction |= (fcond & 0x2) >> 1;
+	}
+      else
+	{
+	  if (inst.operands[2].reg == REG_SP)
+	    as_tsktsk (MVE_BAD_SP);
+	  inst.instruction |= 1 << 6;
+	  inst.instruction |= (fcond & 0x2) << 4;
+	  inst.instruction |= inst.operands[2].reg;
+	}
+      inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+      inst.instruction |= (fcond & 0x4) << 10;
+      inst.instruction |= (fcond & 0x1) << 7;
+
+    }
+    set_pred_insn_type (VPT_INSN);
+    now_pred.cc = 0;
+    now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
+		    | ((inst.instruction & 0xe000) >> 13);
+    now_pred.warn_deprecated = FALSE;
+    now_pred.type = VECTOR_PRED;
+    inst.is_neon = 1;
+}
+
+static void
+do_mve_vcmp (void)
+{
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
+  if (!inst.operands[1].isreg || !inst.operands[1].isquad)
+    first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
+  if (!inst.operands[2].present)
+    first_error (_("MVE vector or ARM register expected"));
+  constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+  /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe.  */
+  if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
+      && inst.operands[1].isquad)
+    {
+      inst.instruction = N_MNEM_vcmp;
+      inst.cond = 0x10;
+    }
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
+		       N_EQK);
+
+  constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
+	      && !inst.operands[2].iszr, BAD_PC);
+
+  unsigned fcond = mve_get_vcmp_vpt_cond (et);
+
+  inst.instruction = 0xee010f00;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= (fcond & 0x4) << 10;
+  inst.instruction |= (fcond & 0x1) << 7;
+  if (et.type == NT_float)
+    {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
+		  BAD_FPU);
+      inst.instruction |= (et.size == 16) << 28;
+      inst.instruction |= 0x3 << 20;
+    }
+  else
+    {
+      inst.instruction |= 1 << 28;
+      inst.instruction |= neon_logbits (et.size) << 20;
+    }
+  if (inst.operands[2].isquad)
+    {
+      inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+      inst.instruction |= (fcond & 0x2) >> 1;
+      inst.instruction |= LOW4 (inst.operands[2].reg);
+    }
+  else
+    {
+      if (inst.operands[2].reg == REG_SP)
+	as_tsktsk (MVE_BAD_SP);
+      inst.instruction |= 1 << 6;
+      inst.instruction |= (fcond & 0x2) << 4;
+      inst.instruction |= inst.operands[2].reg;
+    }
+
+  inst.is_neon = 1;
+  return;
+}
+
 static void
 do_vfp_nsyn_cmp (void)
 {
   enum neon_shape rs;
+  if (!inst.operands[0].isreg)
+    {
+      do_mve_vcmp ();
+      return;
+    }
+  else
+    {
+      constraint (inst.operands[2].present, BAD_SYNTAX);
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
+		  BAD_FPU);
+    }
+
   if (inst.operands[1].isreg)
     {
       rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
@@ -15438,18 +15695,6 @@ neon_dp_fixup (struct arm_it* insn)
   insn->instruction = i;
 }
 
-/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
-   (0, 1, 2, 3).  */
-
-static unsigned
-neon_logbits (unsigned x)
-{
-  return ffs (x) - 4;
-}
-
-#define LOW4(R) ((R) & 0xf)
-#define HI1(R) (((R) >> 4) & 1)
-
 static void
 mve_encode_qqr (int size, int fp)
 {
@@ -21098,6 +21343,10 @@ static const struct reg_entry reg_names[] =
   REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
   REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
 
+  /* Defining the new Zero register from ARMv8.1-M.  */
+  REGDEF(zr,15,ZR),
+  REGDEF(ZR,15,ZR),
+
   /* Coprocessor numbers.  */
   REGSET(p, CP), REGSET(P, CP),
 
@@ -22913,8 +23162,6 @@ static const struct asm_opcode insns[] =
  nCE(vnmul,     _vnmul,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
  nCE(vnmla,     _vnmla,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
  nCE(vnmls,     _vnmls,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
- nCE(vcmp,      _vcmp,    2, (RVSD, RSVD_FI0),    vfp_nsyn_cmp),
- nCE(vcmpe,     _vcmpe,   2, (RVSD, RSVD_FI0),    vfp_nsyn_cmp),
  NCE(vpush,     0,       1, (VRSDLST),          vfp_nsyn_push),
  NCE(vpop,      0,       1, (VRSDLST),          vfp_nsyn_pop),
  NCE(vcvtz,     0,       2, (RVSD, RVSD),       vfp_nsyn_cvtz),
@@ -23630,6 +23877,23 @@ static const struct asm_opcode insns[] =
 
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT & mve_ext
+
+ ToC("vpt",	ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptt",	ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpte",	ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttt",	ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptte",	ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptet",	ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptee",	ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptttt",	ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttte",	ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttet",	ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttee",	ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptett",	ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptete",	ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpteet",	ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpteee",	ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+
  ToC("vpst",	fe710f4d, 0, (), mve_vpt),
  ToC("vpstt",	fe318f4d, 0, (), mve_vpt),
  ToC("vpste",	fe718f4d, 0, (), mve_vpt),
@@ -23709,6 +23973,9 @@ static const struct asm_opcode insns[] =
  mCEF(vmovlt, _vmovlt,	1, (VMOV),		mve_movl),
  mCEF(vmovlb, _vmovlb,	1, (VMOV),		mve_movl),
 
+ mnCE(vcmp,      _vcmp,    3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ),    vfp_nsyn_cmp),
+ mnCE(vcmpe,     _vcmpe,   3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ),    vfp_nsyn_cmp),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v2
 
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.d b/gas/testsuite/gas/arm/mve-vcmp-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..dd2706f084f9abc8e714f35289fbe7d88c142b78
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCMP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vcmp-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.l b/gas/testsuite/gas/arm/mve-vcmp-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..65db78ab61ed5439d09834671a4d40615d84fc65
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.l
@@ -0,0 +1,31 @@
+[^:]*: Assembler messages:
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Error: selected FPU does not support instruction -- `vcmp.f32 eq,q0,q1'
+[^:]*:25: Error: selected FPU does not support instruction -- `vcmp.f32 eq,q0,r1'
+[^:]*:26: Error: bad type in SIMD instruction -- `vcmp.i64 eq,q0,q1'
+[^:]*:27: Error: invalid condition -- `vcmp.s32 eq,q0,q1'
+[^:]*:28: Error: invalid condition -- `vcmp.s16 cs,q0,q1'
+[^:]*:29: Error: invalid condition -- `vcmp.u8 le,q0,q1'
+[^:]*:30: Error: condition required -- `vcmp.s16 q0,q1'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:34: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:36: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.i32 eq,q0,q1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vcmp.i32 eq,q0,q1'
+[^:]*:41: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:42: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:44: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.i32 eq,q0,r1'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vcmp.i32 eq,q0,r1'
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.s b/gas/testsuite/gas/arm/mve-vcmp-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..116e23a80979321d3e8054cc25c523e969e359d9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.s
@@ -0,0 +1,47 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.s32 gt, q0, q1
+.endr
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.i16 eq, q0, r1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+
+cond1
+cond2
+vcmp.f32 eq, q0, q1
+vcmp.f32 eq, q0, r1
+vcmp.i64 eq, q0, q1
+vcmp.s32 eq, q0, q1
+vcmp.s16 cs, q0, q1
+vcmp.u8 le, q0, q1
+vcmp.s16 q0, q1
+vcmp.i32 eq, q0, sp
+it eq
+vcmpeq.i32 eq, q0, q1
+vcmpeq.i32 eq, q0, q1
+vpst
+vcmpeq.i32 eq, q0, q1
+vcmpt.i32 eq, q0, q1
+vpst
+vcmp.i32 eq, q0, q1
+it eq
+vcmpeq.i32 eq, q0, r1
+vcmpeq.i32 eq, q0, r1
+vpst
+vcmpeq.i32 eq, q0, r1
+vcmpt.i32 eq, q0, r1
+vpst
+vcmp.i32 eq, q0, r1
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.d b/gas/testsuite/gas/arm/mve-vcmp-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..7d262517cc6324f0dbc1fca3420df29baa8f8e0c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VCMP instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcmp-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.l b/gas/testsuite/gas/arm/mve-vcmp-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..1305f0697329b108c48b9e7b55e1a064ff680a88
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.l
@@ -0,0 +1,25 @@
+[^:]*: Assembler messages:
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Error: bad type in SIMD instruction -- `vcmp.f64 eq,q0,q1'
+[^:]*:25: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:27: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:28: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:30: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.f32 eq,q0,q1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vcmp.f32 eq,q0,q1'
+[^:]*:35: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:36: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:38: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.f32 eq,q0,r1'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vcmp.f32 eq,q0,r1'
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.s b/gas/testsuite/gas/arm/mve-vcmp-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..c54b0e94043232cecb8c6496ac41643a39c778b4
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.s
@@ -0,0 +1,41 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.f32 gt, q0, q1
+.endr
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.f16 eq, q0, r1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+
+cond1
+cond2
+vcmp.f64 eq, q0, q1
+vcmp.f32 eq, q0, sp
+it eq
+vcmpeq.f32 eq, q0, q1
+vcmpeq.f32 eq, q0, q1
+vpst
+vcmpeq.f32 eq, q0, q1
+vcmpt.f32 eq, q0, q1
+vpst
+vcmp.f32 eq, q0, q1
+it eq
+vcmpeq.f32 eq, q0, r1
+vcmpeq.f32 eq, q0, r1
+vpst
+vcmpeq.f32 eq, q0, r1
+vcmpt.f32 eq, q0, r1
+vpst
+vcmp.f32 eq, q0, r1
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.d b/gas/testsuite/gas/arm/mve-vpt-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..8a4fe5371e8084afd0fcee1dd4da042192dbdedf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VPT instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vpt-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.l b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..28bd9d6047de0fc0592b7b75ee48f3b086f1f879
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
@@ -0,0 +1,23 @@
+[^:]*: Assembler messages:
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Error: bad type in SIMD instruction -- `vpt.i64 eq,q0,q1'
+[^:]*:18: Error: selected FPU does not support instruction -- `vpt.f16 eq,q0,q1'
+[^:]*:19: Error: selected FPU does not support instruction -- `vpt.f32 eq,q0,q1'
+[^:]*:20: Error: bad type in SIMD instruction -- `vpt.f64 eq,q0,q1'
+[^:]*:22: Error: syntax error -- `vpteq.i8 eq,q0,q1'
+[^:]*:23: Error: syntax error -- `vpteq.i8 eq,q0,q1'
+[^:]*:26: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:30: Warning: section '.text' finished with an open VPT/VPST block.
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.s b/gas/testsuite/gas/arm/mve-vpt-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..66d9980998f7f0d44ae036a8d7a08742aa549d61
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.s
@@ -0,0 +1,30 @@
+.macro cond1, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vpt.i8 eq, q0, \lastreg
+vaddt.i32 q0, q1, q2
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1 q1
+cond1 r1
+vpt.i8 eq, q0, sp
+vaddt.i32 q0, q1, q2
+vpt.i64 eq, q0, q1
+vpt.f16 eq, q0, q1
+vpt.f32 eq, q0, q1
+vpt.f64 eq, q0, q1
+it eq
+vpteq.i8 eq, q0, q1
+vpteq.i8 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vpst
+vptt.i8 eq, q0, q1
+vptt.i8 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vaddt.i32 q0, q0, q1
+vpt.i8 eq, q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.d b/gas/testsuite/gas/arm/mve-vpt-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..27a5171aa2e9c401a4fc974da998d8f1e984c614
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VPT instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vpt-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.l b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..678a824eef64d15a7a1add12d84157f80f1555f7
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
@@ -0,0 +1,21 @@
+[^:]*: Assembler messages:
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Error: bad type in SIMD instruction -- `vpt.f64 eq,q0,q1'
+[^:]*:19: Error: syntax error -- `vpteq.f32 eq,q0,q1'
+[^:]*:20: Error: syntax error -- `vpteq.f32 eq,q0,q1'
+[^:]*:23: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:27: Warning: section '.text' finished with an open VPT/VPST block.
+
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.s b/gas/testsuite/gas/arm/mve-vpt-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..83e9fd5b38773163161df955473f9b0961af9a26
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.s
@@ -0,0 +1,27 @@
+.macro cond1, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vpt.f16 eq, q0, \lastreg
+vaddt.i32 q0, q1, q2
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1 q1
+cond1 r1
+vpt.f16 eq, q0, sp
+vaddt.i32 q0, q1, q2
+vpt.f64 eq, q0, q1
+it eq
+vpteq.f32 eq, q0, q1
+vpteq.f32 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vpst
+vptt.f16 eq, q0, q1
+vptt.f16 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vaddt.i32 q0, q0, q1
+vpt.f32 eq, q0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 9/57][Arm][GAS] Add support for MVE instructions: vmov
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (8 preceding siblings ...)
  2019-05-01 17:03 ` [PATCH 10/57][Arm][GAS] Add support for MVE instructions: vcmp and vpt Andre Vieira (lists)
@ 2019-05-01 17:03 ` Andre Vieira (lists)
  2019-05-01 17:05 ` [PATCH 11/57][Arm][GAS] Add support for MVE instructions: vadc, vsbc and vbrsr Andre Vieira (lists)
                   ` (50 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:03 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1421 bytes --]

Hi,

This patch implements support for all MVE VMOV instructions. Including 
the widening and narrowing moves VMOVL[BT] and VMOVN[BT].

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (struct arm_it): Expand isscalar field
         to be able to distinguish between types of scalar.
	(parse_typed_reg_or_scalar): Change to accept MVE scalar
         variants.
	(parse_scalar): Likewise.
	(parse_neon_mov): Accept MVE variant.
	(po_scalar_or_goto): Make use reg_type.
	(parse_operands): Change uses of po_scalar_or_goto.
	(do_vfp_sp_monadic): Change to accept MVE variants.
	(do_vfp_reg_from_sp): Likewise.
	(do_vfp_sp_from_reg): Likewise.
	(do_vfp_dp_rd_rm): Likewise.
	(do_vfp_dp_rd_rn_rm): Likewise.
	(do_vfp_dp_rm_rd_rn): Likewise.
	(M_MNEM_vmovlt, M_MNEM_vmovlb, M_MNEM_vmovnt,
         M_MNEM_vmovnb): New instruction encodings.
	(NEON_SHAPE_DEF): New shape.
	(do_mve_mov): New encoding fuction.
	(do_mve_movn): Likewise.
	(do_mve_movl): Likewise.
	(do_neon_mov): Change to accept MVE variants.
	(mcCE): New MACRO.
         (insns): Accept new MVE variants and instructions.
	* testsuite/gas/arm/mve-vmov-bad-1.d: New test.
	* testsuite/gas/arm/mve-vmov-bad-1.l: New test.
	* testsuite/gas/arm/mve-vmov-bad-1.s: New test.
	* testsuite/gas/arm/mve-vmov-bad-2.d: New test.
	* testsuite/gas/arm/mve-vmov-bad-2.l: New test.
	* testsuite/gas/arm/mve-vmov-bad-2.s: New test.

[-- Attachment #2: 9.patch --]
[-- Type: text/x-patch, Size: 33694 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 59cf887e6ba007ed2f516fa6975d66bc88579107..ff17e9391cd9f5770bd7d4c4ad8ba7281b3e8a87 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -510,7 +510,10 @@ struct arm_it
     unsigned isreg	: 1;  /* Operand was a register.  */
     unsigned immisreg	: 2;  /* .imm field is a second register.
 				 0: imm, 1: gpr, 2: MVE Q-register.  */
-    unsigned isscalar   : 1;  /* Operand is a (Neon) scalar.  */
+    unsigned isscalar   : 2;  /* Operand is a (SIMD) scalar:
+				 0) not scalar,
+				 1) Neon scalar,
+				 2) MVE scalar.  */
     unsigned immisalign : 1;  /* Immediate is an alignment specifier.  */
     unsigned immisfloat : 1;  /* Immediate was parsed as a float.  */
     /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
@@ -1656,9 +1659,14 @@ parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
     {
       if (type != REG_TYPE_VFD
 	  && !(type == REG_TYPE_VFS
-	       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2)))
+	       && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2))
+	  && !(type == REG_TYPE_NQ
+	       && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
 	{
-	  first_error (_("only D registers may be indexed"));
+	  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	    first_error (_("only D and Q registers may be indexed"));
+	  else
+	    first_error (_("only D registers may be indexed"));
 	  return FAIL;
 	}
 
@@ -1747,27 +1755,41 @@ arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
    just do easy checks here, and do further checks later.  */
 
 static int
-parse_scalar (char **ccp, int elsize, struct neon_type_el *type)
+parse_scalar (char **ccp, int elsize, struct neon_type_el *type, enum
+	      arm_reg_type reg_type)
 {
   int reg;
   char *str = *ccp;
   struct neon_typed_alias atype;
-  enum arm_reg_type reg_type = REG_TYPE_VFD;
-
-  if (elsize == 4)
-    reg_type = REG_TYPE_VFS;
+  unsigned reg_size;
 
   reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
 
+  switch (reg_type)
+    {
+    case REG_TYPE_VFS:
+      reg_size = 32;
+      break;
+    case REG_TYPE_VFD:
+      reg_size = 64;
+      break;
+    case REG_TYPE_MQ:
+      reg_size = 128;
+      break;
+    default:
+      gas_assert (0);
+      return FAIL;
+    }
+
   if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
     return FAIL;
 
-  if (atype.index == NEON_ALL_LANES)
+  if (reg_type != REG_TYPE_MQ && atype.index == NEON_ALL_LANES)
     {
       first_error (_("scalar must have an index"));
       return FAIL;
     }
-  else if (atype.index >= 64 / elsize)
+  else if (atype.index >= reg_size / elsize)
     {
       first_error (_("scalar index out of range"));
       return FAIL;
@@ -6542,7 +6564,61 @@ parse_neon_mov (char **str, int *which_operand)
   char *ptr = *str;
   struct neon_type_el optype;
 
-  if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
+   if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
+    {
+      /* Cases 17 or 19.  */
+      inst.operands[i].reg = val;
+      inst.operands[i].isvec = 1;
+      inst.operands[i].isscalar = 2;
+      inst.operands[i].vectype = optype;
+      inst.operands[i++].present = 1;
+
+      if (skip_past_comma (&ptr) == FAIL)
+	goto wanted_comma;
+
+      if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
+	{
+	  /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt>  */
+	  inst.operands[i].reg = val;
+	  inst.operands[i].isreg = 1;
+	  inst.operands[i].present = 1;
+	}
+      else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
+	{
+	  /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>  */
+	  inst.operands[i].reg = val;
+	  inst.operands[i].isvec = 1;
+	  inst.operands[i].isscalar = 2;
+	  inst.operands[i].vectype = optype;
+	  inst.operands[i++].present = 1;
+
+	  if (skip_past_comma (&ptr) == FAIL)
+	    goto wanted_comma;
+
+	  if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
+	    goto wanted_arm;
+
+	  inst.operands[i].reg = val;
+	  inst.operands[i].isreg = 1;
+	  inst.operands[i++].present = 1;
+
+	  if (skip_past_comma (&ptr) == FAIL)
+	    goto wanted_comma;
+
+	  if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
+	    goto wanted_arm;
+
+	  inst.operands[i].reg = val;
+	  inst.operands[i].isreg = 1;
+	  inst.operands[i].present = 1;
+	}
+      else
+	{
+	  first_error (_("expected ARM or MVE vector register"));
+	  return FAIL;
+	}
+    }
+   else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
     {
       /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>.  */
       inst.operands[i].reg = val;
@@ -6560,8 +6636,10 @@ parse_neon_mov (char **str, int *which_operand)
       inst.operands[i].isreg = 1;
       inst.operands[i].present = 1;
     }
-  else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
-	   != FAIL)
+  else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
+	    != FAIL)
+	   || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
+	       != FAIL))
     {
       /* Cases 0, 1, 2, 3, 5 (D only).  */
       if (skip_past_comma (&ptr) == FAIL)
@@ -6658,7 +6736,7 @@ parse_neon_mov (char **str, int *which_operand)
     }
   else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
     {
-      /* Cases 6, 7.  */
+      /* Cases 6, 7, 16, 18.  */
       inst.operands[i].reg = val;
       inst.operands[i].isreg = 1;
       inst.operands[i++].present = 1;
@@ -6666,7 +6744,15 @@ parse_neon_mov (char **str, int *which_operand)
       if (skip_past_comma (&ptr) == FAIL)
 	goto wanted_comma;
 
-      if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
+      if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
+	{
+	  /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]>  */
+	  inst.operands[i].reg = val;
+	  inst.operands[i].isscalar = 2;
+	  inst.operands[i].present = 1;
+	  inst.operands[i].vectype = optype;
+	}
+      else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
 	{
 	  /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]>  */
 	  inst.operands[i].reg = val;
@@ -6676,7 +6762,6 @@ parse_neon_mov (char **str, int *which_operand)
 	}
       else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
 	{
-	  /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm>  */
 	  inst.operands[i].reg = val;
 	  inst.operands[i].isreg = 1;
 	  inst.operands[i++].present = 1;
@@ -6685,37 +6770,70 @@ parse_neon_mov (char **str, int *which_operand)
 	    goto wanted_comma;
 
 	  if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
-	      == FAIL)
+	      != FAIL)
 	    {
-	      first_error (_(reg_expected_msgs[REG_TYPE_VFSD]));
-	      return FAIL;
-	    }
-
-	  inst.operands[i].reg = val;
-	  inst.operands[i].isreg = 1;
-	  inst.operands[i].isvec = 1;
-	  inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
-	  inst.operands[i].vectype = optype;
-	  inst.operands[i].present = 1;
+	      /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm>  */
 
-	  if (rtype == REG_TYPE_VFS)
-	    {
-	      /* Case 14.  */
-	      i++;
-	      if (skip_past_comma (&ptr) == FAIL)
-		goto wanted_comma;
-	      if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
-					      &optype)) == FAIL)
-		{
-		  first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
-		  return FAIL;
-		}
 	      inst.operands[i].reg = val;
 	      inst.operands[i].isreg = 1;
 	      inst.operands[i].isvec = 1;
-	      inst.operands[i].issingle = 1;
+	      inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
 	      inst.operands[i].vectype = optype;
 	      inst.operands[i].present = 1;
+
+	      if (rtype == REG_TYPE_VFS)
+		{
+		  /* Case 14.  */
+		  i++;
+		  if (skip_past_comma (&ptr) == FAIL)
+		    goto wanted_comma;
+		  if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
+						  &optype)) == FAIL)
+		    {
+		      first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
+		      return FAIL;
+		    }
+		  inst.operands[i].reg = val;
+		  inst.operands[i].isreg = 1;
+		  inst.operands[i].isvec = 1;
+		  inst.operands[i].issingle = 1;
+		  inst.operands[i].vectype = optype;
+		  inst.operands[i].present = 1;
+		}
+	    }
+	  else
+	    {
+	      if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
+		       != FAIL)
+		{
+		  /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>  */
+		  inst.operands[i].reg = val;
+		  inst.operands[i].isvec = 1;
+		  inst.operands[i].isscalar = 2;
+		  inst.operands[i].vectype = optype;
+		  inst.operands[i++].present = 1;
+
+		  if (skip_past_comma (&ptr) == FAIL)
+		    goto wanted_comma;
+
+		  if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
+		      == FAIL)
+		    {
+		      first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
+		      return FAIL;
+		    }
+		  inst.operands[i].reg = val;
+		  inst.operands[i].isvec = 1;
+		  inst.operands[i].isscalar = 2;
+		  inst.operands[i].vectype = optype;
+		  inst.operands[i].present = 1;
+		}
+	      else
+		{
+		  first_error (_("VFP single, double or MVE vector register"
+			       " expected"));
+		  return FAIL;
+		}
 	    }
 	}
       else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
@@ -6990,10 +7108,11 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
     }								\
   while (0)
 
-#define po_scalar_or_goto(elsz, label)					\
+#define po_scalar_or_goto(elsz, label, reg_type)			\
   do									\
     {									\
-      val = parse_scalar (& str, elsz, & inst.operands[i].vectype);	\
+      val = parse_scalar (& str, elsz, & inst.operands[i].vectype,	\
+			  reg_type);					\
       if (val == FAIL)							\
 	goto label;							\
       inst.operands[i].reg = val;					\
@@ -7141,7 +7260,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  break;
 	/* Neon scalar. Using an element size of 8 means that some invalid
 	   scalars are accepted here, so deal with those in later code.  */
-	case OP_RNSC:  po_scalar_or_goto (8, failure);    break;
+	case OP_RNSC:  po_scalar_or_goto (8, failure, REG_TYPE_VFD);    break;
 
 	case OP_RNDQ_I0:
 	  {
@@ -7174,7 +7293,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 
 	case OP_RR_RNSC:
 	  {
-	    po_scalar_or_goto (8, try_rr);
+	    po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
 	    break;
 	    try_rr:
 	    po_reg_or_fail (REG_TYPE_RN);
@@ -7187,19 +7306,21 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	try_rnsdq_rnsc:
 	case OP_RNSDQ_RNSC:
 	  {
-	    po_scalar_or_goto (8, try_nsdq);
+	    po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
+	    inst.error = 0;
 	    break;
 	    try_nsdq:
 	    po_reg_or_fail (REG_TYPE_NSDQ);
+	    inst.error = 0;
 	  }
 	  break;
 
 	case OP_RNSD_RNSC:
 	  {
-	    po_scalar_or_goto (8, try_s_scalar);
+	    po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
 	    break;
 	    try_s_scalar:
-	    po_scalar_or_goto (4, try_nsd);
+	    po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
 	    break;
 	    try_nsd:
 	    po_reg_or_fail (REG_TYPE_NSD);
@@ -7208,7 +7329,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 
 	case OP_RNDQ_RNSC:
 	  {
-	    po_scalar_or_goto (8, try_ndq);
+	    po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
 	    break;
 	    try_ndq:
 	    po_reg_or_fail (REG_TYPE_NDQ);
@@ -7217,7 +7338,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 
 	case OP_RND_RNSC:
 	  {
-	    po_scalar_or_goto (8, try_vfd);
+	    po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
 	    break;
 	    try_vfd:
 	    po_reg_or_fail (REG_TYPE_VFD);
@@ -10170,6 +10291,10 @@ do_sxth (void)
 static void
 do_vfp_sp_monadic (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
+	      && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	      _(BAD_FPU));
+
   encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
   encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
 }
@@ -10205,6 +10330,10 @@ do_vfp_sp_dp_cvt (void)
 static void
 do_vfp_reg_from_sp (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
+	     && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	     _(BAD_FPU));
+
   inst.instruction |= inst.operands[0].reg << 12;
   encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
 }
@@ -10222,6 +10351,10 @@ do_vfp_reg2_from_sp2 (void)
 static void
 do_vfp_sp_from_reg (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
+	     && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	     _(BAD_FPU));
+
   encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
   inst.instruction |= inst.operands[1].reg << 12;
 }
@@ -10324,6 +10457,10 @@ do_vfp_xp_ldstmdb (void)
 static void
 do_vfp_dp_rd_rm (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
+	      && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	      _(BAD_FPU));
+
   encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
   encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
 }
@@ -10345,6 +10482,10 @@ do_vfp_dp_rd_rn (void)
 static void
 do_vfp_dp_rd_rn_rm (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+	      && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	      _(BAD_FPU));
+
   encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
   encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
   encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
@@ -10359,6 +10500,10 @@ do_vfp_dp_rd (void)
 static void
 do_vfp_dp_rm_rd_rn (void)
 {
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+	      && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+	      _(BAD_FPU));
+
   encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
   encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
   encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
@@ -13961,6 +14106,10 @@ do_t_loloop (void)
 #define M_MNEM_vldrh	0xec100e10
 #define M_MNEM_vldrw	0xec100e40
 #define M_MNEM_vldrd	0xec100e50
+#define M_MNEM_vmovlt	0xeea01f40
+#define M_MNEM_vmovlb	0xeea00f40
+#define M_MNEM_vmovnt	0xfe311e81
+#define M_MNEM_vmovnb	0xfe310e81
 
 /* Neon instruction encoder helpers.  */
 
@@ -14125,6 +14274,8 @@ NEON_ENC_TAB
      - a table used to drive neon_select_shape.  */
 
 #define NEON_SHAPE_DEF			\
+  X(4, (R, R, S, S), QUAD),		\
+  X(4, (S, S, R, R), QUAD),		\
   X(3, (R, Q, Q), QUAD),		\
   X(3, (D, D, D), DOUBLE),		\
   X(3, (Q, Q, Q), QUAD),		\
@@ -17853,6 +18004,67 @@ do_neon_dup (void)
     }
 }
 
+static void
+do_mve_mov (int toQ)
+{
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    return;
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
+
+  unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
+  if (toQ)
+    {
+      Q0 = 0;
+      Q1 = 1;
+      Rt = 2;
+      Rt2 = 3;
+    }
+
+  constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
+	      _("Index one must be [2,3] and index two must be two less than"
+		" index one."));
+  constraint (inst.operands[Rt].reg == inst.operands[Rt2].reg,
+	      _("General purpose registers may not be the same"));
+  constraint (inst.operands[Rt].reg == REG_SP
+	      || inst.operands[Rt2].reg == REG_SP,
+	      BAD_SP);
+  constraint (inst.operands[Rt].reg == REG_PC
+	      || inst.operands[Rt2].reg == REG_PC,
+	      BAD_PC);
+
+  inst.instruction = 0xec000f00;
+  inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
+  inst.instruction |= !!toQ << 20;
+  inst.instruction |= inst.operands[Rt2].reg << 16;
+  inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
+  inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
+  inst.instruction |= inst.operands[Rt].reg;
+}
+
+static void
+do_mve_movn (void)
+{
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    return;
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
+					    | N_KEY);
+
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= (neon_logbits (et.size) - 1) << 18;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+
+}
+
 /* VMOV has particularly many variations. It can be one of:
      0. VMOV<c><q> <Qd>, <Qm>
      1. VMOV<c><q> <Dd>, <Dm>
@@ -17882,6 +18094,10 @@ do_neon_dup (void)
    (Two ARM regs to two VFP singles.)
     15. VMOV <Sd>, <Se>, <Rn>, <Rm>
    (Two VFP singles to two ARM regs.)
+   16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
+   17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
+   18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
+   19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
 
    These cases can be disambiguated using neon_select_shape, except cases 1/9
    and 3/11 which depend on the operand type too.
@@ -17897,10 +18113,11 @@ do_neon_dup (void)
 static void
 do_neon_mov (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_RRFF, NS_FFRR, NS_DRR, NS_RRD,
-					  NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR,
-					  NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
-					  NS_HR, NS_RH, NS_HI, NS_NULL);
+  enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
+					  NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
+					  NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
+					  NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
+					  NS_NULL);
   struct neon_type_el et;
   const char *ldconst = 0;
 
@@ -17919,7 +18136,7 @@ do_neon_mov (void)
 
     case NS_QQ:  /* case 0/1.  */
       {
-	if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+	if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
 	  return;
 	/* The architecture manual I have doesn't explicitly state which
 	   value the U bit should have for register->register moves, but
@@ -17949,7 +18166,7 @@ do_neon_mov (void)
       /* fall through.  */
 
     case NS_QI:  /* case 2/3.  */
-      if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+      if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
 	return;
       inst.instruction = 0x0800010;
       neon_move_immediate ();
@@ -17976,12 +18193,31 @@ do_neon_mov (void)
 	et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
 	logsize = neon_logbits (et.size);
 
-	constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
-		    _(BAD_FPU));
-	constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
-		    && et.size != 32, _(BAD_FPU));
+	if (et.size != 32)
+	  {
+	    if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		&& vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
+	      return;
+	  }
+	else
+	  {
+	    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
+			&& !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+			_(BAD_FPU));
+	  }
+
+	if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	  {
+	    if (inst.operands[1].reg == REG_SP)
+	      as_tsktsk (MVE_BAD_SP);
+	    else if (inst.operands[1].reg == REG_PC)
+	      as_tsktsk (MVE_BAD_PC);
+	  }
+	unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
+
 	constraint (et.type == NT_invtype, _("bad type for scalar"));
-	constraint (x >= 64 / et.size, _("scalar index out of range"));
+	constraint (x >= size / et.size, _("scalar index out of range"));
+
 
 	switch (et.size)
 	  {
@@ -17991,7 +18227,7 @@ do_neon_mov (void)
 	  default: ;
 	  }
 
-	bcdebits |= x << logsize;
+	bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
 
 	inst.instruction = 0xe000b10;
 	do_vfp_cond_or_thumb ();
@@ -17999,12 +18235,14 @@ do_neon_mov (void)
 	inst.instruction |= HI1 (dn) << 7;
 	inst.instruction |= inst.operands[1].reg << 12;
 	inst.instruction |= (bcdebits & 3) << 5;
-	inst.instruction |= (bcdebits >> 2) << 21;
+	inst.instruction |= ((bcdebits >> 2) & 3) << 21;
+	inst.instruction |= (x >> (3-logsize)) << 16;
       }
       break;
 
     case NS_DRR:  /* case 5 (fmdrr).  */
-      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+		  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
 		  _(BAD_FPU));
 
       inst.instruction = 0xc400b10;
@@ -18036,12 +18274,32 @@ do_neon_mov (void)
 			      N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
 	logsize = neon_logbits (et.size);
 
-	constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
-		    _(BAD_FPU));
-	constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
-		    && et.size != 32, _(BAD_FPU));
+	if (et.size != 32)
+	  {
+	    if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+		&& vfp_or_neon_is_neon (NEON_CHECK_CC
+					| NEON_CHECK_ARCH) == FAIL)
+	      return;
+	  }
+	else
+	  {
+	    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
+			&& !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+			_(BAD_FPU));
+	  }
+
+	if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	  {
+	    if (inst.operands[0].reg == REG_SP)
+	      as_tsktsk (MVE_BAD_SP);
+	    else if (inst.operands[0].reg == REG_PC)
+	      as_tsktsk (MVE_BAD_PC);
+	  }
+
+	unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
+
 	constraint (et.type == NT_invtype, _("bad type for scalar"));
-	constraint (x >= 64 / et.size, _("scalar index out of range"));
+	constraint (x >= size / et.size, _("scalar index out of range"));
 
 	switch (et.size)
 	  {
@@ -18051,7 +18309,7 @@ do_neon_mov (void)
 	  default: ;
 	  }
 
-	abcdebits |= x << logsize;
+	abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
 	inst.instruction = 0xe100b10;
 	do_vfp_cond_or_thumb ();
 	inst.instruction |= LOW4 (dn) << 16;
@@ -18059,11 +18317,13 @@ do_neon_mov (void)
 	inst.instruction |= inst.operands[0].reg << 12;
 	inst.instruction |= (abcdebits & 3) << 5;
 	inst.instruction |= (abcdebits >> 2) << 21;
+	inst.instruction |= (x >> (3-logsize)) << 16;
       }
       break;
 
     case NS_RRD:  /* case 7 (fmrrd).  */
-      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+		  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
 		  _(BAD_FPU));
 
       inst.instruction = 0xc500b10;
@@ -18130,11 +18390,21 @@ do_neon_mov (void)
 	do_scalar_fp16_v82_encode ();
       break;
 
+    case NS_RRSS:
+      do_mve_mov (0);
+      break;
+    case NS_SSRR:
+      do_mve_mov (1);
+      break;
+
     /* The encoders for the fmrrs and fmsrr instructions expect three operands
        (one of which is a list), but we have parsed four.  Do some fiddling to
        make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
        expect.  */
     case NS_RRFF:  /* case 14 (fmrrs).  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+		  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+		  _(BAD_FPU));
       constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
 		  _("VFP registers must be adjacent"));
       inst.operands[2].imm = 2;
@@ -18143,6 +18413,9 @@ do_neon_mov (void)
       break;
 
     case NS_FFRR:  /* case 15 (fmsrr).  */
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
+		  && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
+		  _(BAD_FPU));
       constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
 		  _("VFP registers must be adjacent"));
       inst.operands[1] = inst.operands[2];
@@ -18162,6 +18435,39 @@ do_neon_mov (void)
     }
 }
 
+static void
+do_mve_movl (void)
+{
+  if (!(inst.operands[0].present && inst.operands[0].isquad
+      && inst.operands[1].present && inst.operands[1].isquad
+      && !inst.operands[2].present))
+    {
+      inst.instruction = 0;
+      inst.cond = 0xb;
+      if (thumb_mode)
+	set_pred_insn_type (INSIDE_IT_INSN);
+      do_neon_mov ();
+      return;
+    }
+
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    return;
+
+  if (inst.cond != COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+
+  struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
+					    | N_S16 | N_U16 | N_KEY);
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= (neon_logbits (et.size) + 1) << 19;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
 static void
 do_neon_rshift_round_imm (void)
 {
@@ -21199,6 +21505,10 @@ static struct asm_barrier_opt barrier_opt_names[] =
 #define cCE(mnem,  op, nops, ops, ae)	\
   { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
 
+/* mov instructions that are shared between coprocessor and MVE.  */
+#define mcCE(mnem,  op, nops, ops, ae)	\
+  { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
+
 /* Legacy coprocessor instructions where conditional infix and conditional
    suffix are ambiguous.  For consistency this includes all FPA instructions,
    not just the potentially ambiguous ones.  */
@@ -22473,9 +22783,6 @@ static const struct asm_opcode insns[] =
 #define ARM_VARIANT  & fpu_vfp_ext_v1xd  /* VFP V1xD (single precision).  */
 
   /* Moves and type conversions.  */
- cCE("fcpys",	eb00a40, 2, (RVS, RVS),	      vfp_sp_monadic),
- cCE("fmrs",	e100a10, 2, (RR, RVS),	      vfp_reg_from_sp),
- cCE("fmsr",	e000a10, 2, (RVS, RR),	      vfp_sp_from_reg),
  cCE("fmstat",	ef1fa10, 0, (),		      noargs),
  cCE("vmrs",	ef00a10, 2, (APSR_RR, RVC),   vmrs),
  cCE("vmsr",	ee00a10, 2, (RVC, RR),        vmsr),
@@ -22547,7 +22854,6 @@ static const struct asm_opcode insns[] =
 #define ARM_VARIANT  & fpu_vfp_ext_v1 /* VFP V1 (Double precision).  */
 
   /* Moves and type conversions.  */
- cCE("fcpyd",	eb00b40, 2, (RVD, RVD),	      vfp_dp_rd_rm),
  cCE("fcvtds",	eb70ac0, 2, (RVD, RVS),	      vfp_dp_sp_cvt),
  cCE("fcvtsd",	eb70bc0, 2, (RVS, RVD),	      vfp_sp_dp_cvt),
  cCE("fmdhr",	e200b10, 2, (RVD, RR),	      vfp_dp_rn_rd),
@@ -22583,14 +22889,6 @@ static const struct asm_opcode insns[] =
  cCE("fcmped",	eb40bc0, 2, (RVD, RVD),	      vfp_dp_rd_rm),
  cCE("fcmpezd",	eb50bc0, 1, (RVD),	      vfp_dp_rd),
 
-#undef  ARM_VARIANT
-#define ARM_VARIANT  & fpu_vfp_ext_v2
-
- cCE("fmsrr",	c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
- cCE("fmrrs",	c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
- cCE("fmdrr",	c400b10, 3, (RVD, RR, RR),    vfp_dp_rm_rd_rn),
- cCE("fmrrd",	c500b10, 3, (RR, RR, RVD),    vfp_dp_rd_rn_rm),
-
 /* Instructions which may belong to either the Neon or VFP instruction sets.
    Individual encoder functions perform additional architecture checks.  */
 #undef  ARM_VARIANT
@@ -22629,7 +22927,6 @@ static const struct asm_opcode insns[] =
 
 
   /* NOTE: All VMOV encoding is special-cased!  */
- NCE(vmov,      0,       1, (VMOV), neon_mov),
  NCE(vmovq,     0,       1, (VMOV), neon_mov),
 
 #undef  THUMB_VARIANT
@@ -23373,11 +23670,24 @@ static const struct asm_opcode insns[] =
  mCEF(vldrw,	_vldrw,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
  mCEF(vldrd,	_vldrd,	    2, (RMQ, ADDRMVE),			mve_vstr_vldr),
 
+ mCEF(vmovnt,	_vmovnt,    2, (RMQ, RMQ),			  mve_movn),
+ mCEF(vmovnb,	_vmovnb,    2, (RMQ, RMQ),			  mve_movn),
+
 #undef  ARM_VARIANT
-#define ARM_VARIANT    & fpu_vfp_ext_v1xd
+#define ARM_VARIANT  & fpu_vfp_ext_v1
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_v6t2
 
+ mcCE(fcpyd,	eb00b40, 2, (RVD, RVD),	      vfp_dp_rd_rm),
+
+#undef  ARM_VARIANT
+#define ARM_VARIANT  & fpu_vfp_ext_v1xd
+
+ MNCE(vmov,   0,	1, (VMOV),	      neon_mov),
+ mcCE(fmrs,	e100a10, 2, (RR, RVS),	      vfp_reg_from_sp),
+ mcCE(fmsr,	e000a10, 2, (RVS, RR),	      vfp_sp_from_reg),
+ mcCE(fcpys,	eb00a40, 2, (RVS, RVS),	      vfp_sp_monadic),
+
  mCEF(vmullt, _vmullt,	3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ),	mve_vmull),
  mnCEF(vadd,  _vadd,	3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR),	neon_addsub_if_i),
  mnCEF(vsub,  _vsub,	3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR),	neon_addsub_if_i),
@@ -23385,6 +23695,17 @@ static const struct asm_opcode insns[] =
  MNCEF(vabs,  1b10300,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
  MNCEF(vneg,  1b10380,	2, (RNSDQMQ, RNSDQMQ),	neon_abs_neg),
 
+ mCEF(vmovlt, _vmovlt,	1, (VMOV),		mve_movl),
+ mCEF(vmovlb, _vmovlb,	1, (VMOV),		mve_movl),
+
+#undef  ARM_VARIANT
+#define ARM_VARIANT  & fpu_vfp_ext_v2
+
+ mcCE(fmsrr,	c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
+ mcCE(fmrrs,	c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
+ mcCE(fmdrr,	c400b10, 3, (RVD, RR, RR),    vfp_dp_rm_rd_rn),
+ mcCE(fmrrd,	c500b10, 3, (RR, RR, RVD),    vfp_dp_rd_rn_rm),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT    & fpu_vfp_ext_armv8xd
  mnUF(vcvta,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvta),
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-1.d b/gas/testsuite/gas/arm/mve-vmov-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..a1933bf5dff7015f0dff118b8643b9f454c4dddb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMOV (between general-purpose register and vector lane)
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmov-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-1.l b/gas/testsuite/gas/arm/mve-vmov-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..4cff35850df1f4a4b79d9936ce73482ec6220b08
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-1.l
@@ -0,0 +1,24 @@
+[^:]*: Assembler messages:
+[^:]*:3: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:4: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:5: Error: bad type for scalar -- `vmov.64 q0\[0\],r0'
+[^:]*:6: Error: scalar index out of range -- `vmov.8 q0\[16\],r0'
+[^:]*:7: Error: scalar index out of range -- `vmov.16 q0\[8\],r0'
+[^:]*:8: Error: scalar index out of range -- `vmov.32 q0\[4\],r0'
+[^:]*:10: Error: syntax error -- `vmovt.8 q0\[0\],r0'
+[^:]*:11: Error: syntax error -- `vmovt.8 q0\[0\],r0'
+[^:]*:13: Error: instruction not allowed in IT block -- `vmov.8 q0\[0\],r0'
+[^:]*:14: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:15: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:16: Error: bad type for scalar -- `vmov.u64 r0,q0\[0\]'
+[^:]*:17: Error: bad type for scalar -- `vmov.s64 r0,q0\[0\]'
+[^:]*:18: Error: bad type for scalar -- `vmov.64 r0,q0\[0\]'
+[^:]*:19: Error: bad type for scalar -- `vmov.8 r0,q0\[0\]'
+[^:]*:20: Error: bad type for scalar -- `vmov.16 r0,q0\[0\]'
+[^:]*:21: Error: bad type for scalar -- `vmov.f16 r0,q0\[0\]'
+[^:]*:22: Error: scalar index out of range -- `vmov.u8 r0,q0\[16\]'
+[^:]*:23: Error: scalar index out of range -- `vmov.u16 r0,q0\[8\]'
+[^:]*:24: Error: scalar index out of range -- `vmov.32 r0,q0\[4\]'
+[^:]*:26: Error: syntax error -- `vmovt.u8 r0,q0\[0\]'
+[^:]*:27: Error: syntax error -- `vmovt.u8 r0,q0\[0\]'
+[^:]*:29: Error: instruction not allowed in IT block -- `vmov.u8 r0,q0\[0\]'
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-1.s b/gas/testsuite/gas/arm/mve-vmov-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..5d58d498f28aefbb7af4623d0004ce4a9ce4c4d9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-1.s
@@ -0,0 +1,29 @@
+.syntax unified
+.thumb
+vmov.8 q0[0], sp
+vmov.8 q0[0], pc
+vmov.64 q0[0], r0
+vmov.8 q0[16], r0
+vmov.16 q0[8], r0
+vmov.32 q0[4], r0
+vpst
+vmovt.8 q0[0], r0
+vmovt.8 q0[0], r0
+it eq
+vmov.8 q0[0], r0
+vmov.u8 sp, q0[0]
+vmov.u8 pc, q0[0]
+vmov.u64 r0, q0[0]
+vmov.s64 r0, q0[0]
+vmov.64 r0, q0[0]
+vmov.8 r0, q0[0]
+vmov.16 r0, q0[0]
+vmov.f16 r0, q0[0]
+vmov.u8 r0, q0[16]
+vmov.u16 r0, q0[8]
+vmov.32 r0, q0[4]
+vpst
+vmovt.u8 r0, q0[0]
+vmovt.u8 r0, q0[0]
+it eq
+vmov.u8 r0, q0[0]
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-2.d b/gas/testsuite/gas/arm/mve-vmov-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..c2b02d00100760a8ed1cb7975fc40364b4ed0cc9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMOV (between two 32-bit vector lanes to two general-purpose registers)
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmov-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-2.l b/gas/testsuite/gas/arm/mve-vmov-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..2f4bdc8293a04e3814a9cc80871af51048b23c44
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-2.l
@@ -0,0 +1,10 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: General purpose registers may not be the same -- `vmov r0,r0,q0\[2\],q0\[0\]'
+[^:]*:4: Error: r13 not allowed here -- `vmov sp,r0,q0\[2\],q0\[0\]'
+[^:]*:5: Error: r13 not allowed here -- `vmov r0,sp,q0\[2\],q0\[0\]'
+[^:]*:6: Error: r15 not allowed here -- `vmov pc,r0,q0\[2\],q0\[0\]'
+[^:]*:7: Error: r15 not allowed here -- `vmov r0,pc,q0\[2\],q0\[0\]'
+[^:]*:8: Error: r13 not allowed here -- `vmov q0\[2\],q0\[0\],sp,r0'
+[^:]*:9: Error: r13 not allowed here -- `vmov q0\[2\],q0\[0\],r0,sp'
+[^:]*:10: Error: r15 not allowed here -- `vmov q0\[2\],q0\[0\],pc,r0'
+[^:]*:11: Error: r15 not allowed here -- `vmov q0\[2\],q0\[0\],r0,pc'
diff --git a/gas/testsuite/gas/arm/mve-vmov-bad-2.s b/gas/testsuite/gas/arm/mve-vmov-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..20db239cbb9259e680a4a1b2fcc90d61c7aad60e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmov-bad-2.s
@@ -0,0 +1,11 @@
+.syntax unified
+.thumb
+vmov r0, r0, q0[2], q0[0]
+vmov sp, r0, q0[2], q0[0]
+vmov r0, sp, q0[2], q0[0]
+vmov pc, r0, q0[2], q0[0]
+vmov r0, pc, q0[2], q0[0]
+vmov q0[2], q0[0], sp, r0
+vmov q0[2], q0[0], r0, sp
+vmov q0[2], q0[0], pc, r0
+vmov q0[2], q0[0], r0, pc

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 11/57][Arm][GAS] Add support for MVE instructions: vadc, vsbc and vbrsr
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (9 preceding siblings ...)
  2019-05-01 17:03 ` [PATCH 9/57][Arm][GAS] Add support for MVE instructions: vmov Andre Vieira (lists)
@ 2019-05-01 17:05 ` Andre Vieira (lists)
  2019-05-01 17:06 ` [PATCH 12/57][Arm][GAS] Add support for MVE instructions: vaddlv and vaddv Andre Vieira (lists)
                   ` (49 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:05 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]

Hi,

This patch adds support for MVE instructions VADC, VSBC and VBRSR.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vadc, M_MNEM_vadci, M_MNEM_vbrsr):
         New instruction encodings.
	(do_mve_vadc): New encoding instruction.
	(do_mve_vbrsr): Likewise.
	(do_mve_vsbc): Likewise.
	* testsuite/gas/arm/mve-vadc-bad.d: New test.
	* testsuite/gas/arm/mve-vadc-bad.l: New test.
	* testsuite/gas/arm/mve-vadc-bad.s: New test.
	* testsuite/gas/arm/mve-vbrsr-bad.d: New test.
	* testsuite/gas/arm/mve-vbrsr-bad.l: New test.
	* testsuite/gas/arm/mve-vbrsr-bad.s: New test.
	* testsuite/gas/arm/mve-vsbc-bad.d: New test.
	* testsuite/gas/arm/mve-vsbc-bad.l: New test.
	* testsuite/gas/arm/mve-vsbc-bad.s: New test.

[-- Attachment #2: 11.patch --]
[-- Type: text/x-patch, Size: 11365 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b6ca4a48626f199347b7f1b2d281065198fd43ca..91754e3da9d500300443e28455ee6f248ded249b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14139,6 +14139,9 @@ do_t_loloop (void)
 #define M_MNEM_vmovlb	0xeea00f40
 #define M_MNEM_vmovnt	0xfe311e81
 #define M_MNEM_vmovnb	0xfe310e81
+#define M_MNEM_vadc	0xee300f00
+#define M_MNEM_vadci	0xee301f00
+#define M_MNEM_vbrsr	0xfe011e60
 
 /* Neon instruction encoder helpers.  */
 
@@ -16761,6 +16764,52 @@ do_neon_qdmulh (void)
     }
 }
 
+static void
+do_mve_vadc (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
+
+  if (et.type == NT_invtype)
+    first_error (BAD_EL_TYPE);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_qqq (0, 64);
+}
+
+static void
+do_mve_vbrsr (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_qqr (et.size, 0);
+}
+
+static void
+do_mve_vsbc (void)
+{
+  neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_qqq (1, 64);
+}
+
 static void
 do_mve_vmull (void)
 {
@@ -23911,6 +23960,10 @@ static const struct asm_opcode insns[] =
  ToC("vpsteee",	fe712f4d, 0, (), mve_vpt),
 
  /* MVE and MVE FP only.  */
+ 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),
+ mToC("vsbci",	fe301f00,   3, (RMQ, RMQ, RMQ),			  mve_vsbc),
  mCEF(vmullb,	_vmullb,    3, (RMQ, RMQ, RMQ),			  mve_vmull),
  mCEF(vabav,	_vabav,	    3, (RRnpcsp, RMQ, RMQ),		  mve_vabav),
  mCEF(vmladav,	  _vmladav,	3, (RRe, RMQ, RMQ),		mve_vmladav),
@@ -23947,6 +24000,7 @@ static const struct asm_opcode insns[] =
 
  mCEF(vmovnt,	_vmovnt,    2, (RMQ, RMQ),			  mve_movn),
  mCEF(vmovnb,	_vmovnb,    2, (RMQ, RMQ),			  mve_movn),
+ mCEF(vbrsr,	_vbrsr,     3, (RMQ, RMQ, RR),			  mve_vbrsr),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
diff --git a/gas/testsuite/gas/arm/mve-vadc-bad.d b/gas/testsuite/gas/arm/mve-vadc-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..81d95c2c57f970f833cc2059ddef5164948b85fd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vadc-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VADC instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vadc-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vadc-bad.l b/gas/testsuite/gas/arm/mve-vadc-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..ca1c3a579fa7ccbe803a7ea92407b4e594367433
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vadc-bad.l
@@ -0,0 +1,31 @@
+[^:]*: Assembler messages:
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Error: bad type in SIMD instruction -- `vadc.i8 q0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vadc.i16 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vadc.i64 q0,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vadc.f32 q0,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vadci.i8 q0,q1,q2'
+[^:]*:18: Error: bad type in SIMD instruction -- `vadci.i16 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vadci.i64 q0,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vadci.f32 q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vadceq.i32 q0,q1,q2'
+[^:]*:23: Error: syntax error -- `vadceq.i32 q0,q1,q2'
+[^:]*:25: Error: syntax error -- `vadceq.i32 q0,q1,q2'
+[^:]*:26: Error: vector predicated instruction should be in VPT/VPST block -- `vadct.i32 q0,q1,q2'
+[^:]*:28: Error: instruction missing MVE vector predication code -- `vadc.i32 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vadcieq.i32 q0,q1,q2'
+[^:]*:31: Error: syntax error -- `vadcieq.i32 q0,q1,q2'
+[^:]*:33: Error: syntax error -- `vadcieq.i32 q0,q1,q2'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vadcit.i32 q0,q1,q2'
+[^:]*:36: Error: instruction missing MVE vector predication code -- `vadci.i32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vadc-bad.s b/gas/testsuite/gas/arm/mve-vadc-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..6627c9e54f081c2f7811ce15072dc0839f3739cb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vadc-bad.s
@@ -0,0 +1,36 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+.irp mnem, vadc.i32, vadci.i32
+it \cond
+\mnem q0, q1, q2
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vadc.i8 q0, q1, q2
+vadc.i16 q0, q1, q2
+vadc.i64 q0, q1, q2
+vadc.f32 q0, q1, q2
+vadci.i8 q0, q1, q2
+vadci.i16 q0, q1, q2
+vadci.i64 q0, q1, q2
+vadci.f32 q0, q1, q2
+it eq
+vadceq.i32 q0, q1, q2
+vadceq.i32 q0, q1, q2
+vpst
+vadceq.i32 q0, q1, q2
+vadct.i32 q0, q1, q2
+vpst
+vadc.i32 q0, q1, q2
+it eq
+vadcieq.i32 q0, q1, q2
+vadcieq.i32 q0, q1, q2
+vpst
+vadcieq.i32 q0, q1, q2
+vadcit.i32 q0, q1, q2
+vpst
+vadci.i32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vbrsr-bad.d b/gas/testsuite/gas/arm/mve-vbrsr-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..b4fc21aba00d159293ba9a9656060a2f612ccf25
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbrsr-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VBRSR instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vbrsr-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vbrsr-bad.l b/gas/testsuite/gas/arm/mve-vbrsr-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..d0b8de9178e2f74eff436f53c5f69411403d1922
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbrsr-bad.l
@@ -0,0 +1,14 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Error: bad type in SIMD instruction -- `vbrsr.64 q0,q1,r2'
+[^:]*:12: Error: ARM register expected -- `vbrsr.32 q0,q1,q2'
+[^:]*:14: Error: syntax error -- `vbrsreq.32 q0,q1,r2'
+[^:]*:15: Error: syntax error -- `vbrsreq.32 q0,q1,r2'
+[^:]*:17: Error: syntax error -- `vbrsreq.32 q0,q1,r2'
+[^:]*:19: Error: instruction missing MVE vector predication code -- `vbrsr.32 q0,q1,r2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vbrsrt.32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vbrsr-bad.s b/gas/testsuite/gas/arm/mve-vbrsr-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..af02bd941d721d6b1be27953746260038892b6fd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbrsr-bad.s
@@ -0,0 +1,20 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vbrsr.16 q0, q1, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vbrsr.64 q0, q1, r2
+vbrsr.32 q0, q1, q2
+it eq
+vbrsreq.32 q0, q1, r2
+vbrsreq.32 q0, q1, r2
+vpst
+vbrsreq.32 q0, q1, r2
+vpst
+vbrsr.32 q0, q1, r2
+vbrsrt.32 q0, q1, r2
diff --git a/gas/testsuite/gas/arm/mve-vsbc-bad.d b/gas/testsuite/gas/arm/mve-vsbc-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..29186c1cac47f2d35068a00d026ab6858fc84eda
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsbc-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSBC instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vsbc-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vsbc-bad.l b/gas/testsuite/gas/arm/mve-vsbc-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..e730751262dd0d3765a8bd6d1947a724a3236979
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsbc-bad.l
@@ -0,0 +1,25 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vsbc.i16 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vsbci.i16 q0,q1,q2'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: syntax error -- `vsbceq.i32 q0,q1,q2'
+[^:]*:16: Error: syntax error -- `vsbceq.i32 q0,q1,q2'
+[^:]*:18: Error: syntax error -- `vsbceq.i32 q0,q1,q2'
+[^:]*:20: Error: instruction missing MVE vector predication code -- `vsbc.i32 q0,q1,q2'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vsbct.i32 q0,q1,q2'
+[^:]*:23: Error: syntax error -- `vsbcieq.i32 q0,q1,q2'
+[^:]*:24: Error: syntax error -- `vsbcieq.i32 q0,q1,q2'
+[^:]*:26: Error: syntax error -- `vsbcieq.i32 q0,q1,q2'
+[^:]*:28: Error: instruction missing MVE vector predication code -- `vsbci.i32 q0,q1,q2'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vsbcit.i32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vsbc-bad.s b/gas/testsuite/gas/arm/mve-vsbc-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..869ba6e228bdd21b6f9282b62447e66a3c7adb81
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsbc-bad.s
@@ -0,0 +1,29 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().i32 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vsbc.i16 q0, q1, q2
+vsbci.i16 q0, q1, q2
+cond vsbc
+cond vsbci
+it eq
+vsbceq.i32 q0, q1, q2
+vsbceq.i32 q0, q1, q2
+vpst
+vsbceq.i32 q0, q1, q2
+vpst
+vsbc.i32 q0, q1, q2
+vsbct.i32 q0, q1, q2
+it eq
+vsbcieq.i32 q0, q1, q2
+vsbcieq.i32 q0, q1, q2
+vpst
+vsbcieq.i32 q0, q1, q2
+vpst
+vsbci.i32 q0, q1, q2
+vsbcit.i32 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 12/57][Arm][GAS] Add support for MVE instructions: vaddlv and vaddv
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (10 preceding siblings ...)
  2019-05-01 17:05 ` [PATCH 11/57][Arm][GAS] Add support for MVE instructions: vadc, vsbc and vbrsr Andre Vieira (lists)
@ 2019-05-01 17:06 ` Andre Vieira (lists)
  2019-05-01 17:07 ` [PATCH 13/57][Arm][GAS] Add support for MVE instructions: vand, vbic, vorr, vorn and veor Andre Vieira (lists)
                   ` (48 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:06 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 682 bytes --]

Hi,

This patch adds support for MVE instructions VADDLV and VADDV.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vaddlv, M_MNEM_vaddlva, M_MNEM_vaddv,
         M_MNEM_vaddva): New instruction encodings.
	(mve_encode_rq): New encoding helper function.
	(do_mve_vaddlv): New encoding function.
	(do_mve_vaddv): New encoding function.
	* testsuite/gas/arm/mve-vaddlv-bad.d: New test.
	* testsuite/gas/arm/mve-vaddlv-bad.l: New test.
	* testsuite/gas/arm/mve-vaddlv-bad.s: New test.
	* testsuite/gas/arm/mve-vaddv-bad.d: New test.
	* testsuite/gas/arm/mve-vaddv-bad.l: New test.
	* testsuite/gas/arm/mve-vaddv-bad.s: New test.

[-- Attachment #2: 12.patch --]
[-- Type: text/x-patch, Size: 11537 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 91754e3da9d500300443e28455ee6f248ded249b..34e2c592ab00c32bd829152693d6fa036dc2a81f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14142,6 +14142,10 @@ do_t_loloop (void)
 #define M_MNEM_vadc	0xee300f00
 #define M_MNEM_vadci	0xee301f00
 #define M_MNEM_vbrsr	0xfe011e60
+#define M_MNEM_vaddlv	0xee890f00
+#define M_MNEM_vaddlva	0xee890f20
+#define M_MNEM_vaddv	0xeef10f00
+#define M_MNEM_vaddva	0xeef10f20
 
 /* Neon instruction encoder helpers.  */
 
@@ -14318,6 +14322,8 @@ NEON_ENC_TAB
   X(3, (D, D, S), DOUBLE),		\
   X(3, (Q, Q, S), QUAD),		\
   X(3, (Q, Q, R), QUAD),		\
+  X(3, (R, R, Q), QUAD),		\
+  X(2, (R, Q),	  QUAD),		\
   X(2, (D, D), DOUBLE),			\
   X(2, (Q, Q), QUAD),			\
   X(2, (D, S), DOUBLE),			\
@@ -15766,6 +15772,15 @@ mve_encode_qqq (int ubit, int size)
   inst.is_neon = 1;
 }
 
+static void
+mve_encode_rq (unsigned bit28, unsigned size)
+{
+  inst.instruction |= bit28 << 28;
+  inst.instruction |= neon_logbits (size) << 18;
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
 
 /* Encode insns with bit pattern:
 
@@ -16489,6 +16504,30 @@ do_mve_vst_vld (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vaddlv (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
+
+  if (et.type == NT_invtype)
+    first_error (BAD_EL_TYPE);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= inst.operands[1].reg << 19;
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[2].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_neon_dyadic_if_su (void)
 {
@@ -16764,6 +16803,26 @@ do_neon_qdmulh (void)
     }
 }
 
+static void
+do_mve_vaddv (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (2, rs, N_EQK,  N_SU_32 | N_KEY);
+
+  if (et.type == NT_invtype)
+    first_error (BAD_EL_TYPE);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+  mve_encode_rq (et.type == NT_unsigned, et.size);
+}
+
 static void
 do_mve_vadc (void)
 {
@@ -24001,6 +24060,10 @@ static const struct asm_opcode insns[] =
  mCEF(vmovnt,	_vmovnt,    2, (RMQ, RMQ),			  mve_movn),
  mCEF(vmovnb,	_vmovnb,    2, (RMQ, RMQ),			  mve_movn),
  mCEF(vbrsr,	_vbrsr,     3, (RMQ, RMQ, RR),			  mve_vbrsr),
+ mCEF(vaddlv,	_vaddlv,    3, (RRe, RRo, RMQ),			  mve_vaddlv),
+ mCEF(vaddlva,	_vaddlva,   3, (RRe, RRo, RMQ),			  mve_vaddlv),
+ mCEF(vaddv,	_vaddv,	    2, (RRe, RMQ),			  mve_vaddv),
+ mCEF(vaddva,	_vaddva,    2, (RRe, RMQ),			  mve_vaddv),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
diff --git a/gas/testsuite/gas/arm/mve-vaddlv-bad.d b/gas/testsuite/gas/arm/mve-vaddlv-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..b5993f3181cd4885d81a59224e7f19e1c5a9425f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddlv-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VADDLV instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vaddlv-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vaddlv-bad.l b/gas/testsuite/gas/arm/mve-vaddlv-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..771fc009f9ea7e802e15ddfe1e41dd6e75523627
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddlv-bad.l
@@ -0,0 +1,42 @@
+[^:]*: Assembler messages:
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Error: bad type in SIMD instruction -- `vaddlv.i32 r0,r1,q0'
+[^:]*:14: Error: bad type in SIMD instruction -- `vaddlv.f32 r0,r1,q0'
+[^:]*:15: Error: bad type in SIMD instruction -- `vaddlv.s8 r0,r1,q0'
+[^:]*:16: Error: bad type in SIMD instruction -- `vaddlv.s16 r0,r1,q0'
+[^:]*:17: Error: bad type in SIMD instruction -- `vaddlv.s64 r0,r1,q0'
+[^:]*:18: Error: bad type in SIMD instruction -- `vaddlv.u8 r0,r1,q0'
+[^:]*:19: Error: bad type in SIMD instruction -- `vaddlv.u16 r0,r1,q0'
+[^:]*:20: Error: bad type in SIMD instruction -- `vaddlv.u64 r0,r1,q0'
+[^:]*:21: Error: bad type in SIMD instruction -- `vaddlva.i32 r0,r1,q0'
+[^:]*:22: Error: bad type in SIMD instruction -- `vaddlva.f32 r0,r1,q0'
+[^:]*:23: Error: bad type in SIMD instruction -- `vaddlva.s8 r0,r1,q0'
+[^:]*:24: Error: bad type in SIMD instruction -- `vaddlva.s16 r0,r1,q0'
+[^:]*:25: Error: bad type in SIMD instruction -- `vaddlva.s64 r0,r1,q0'
+[^:]*:26: Error: bad type in SIMD instruction -- `vaddlva.u8 r0,r1,q0'
+[^:]*:27: Error: bad type in SIMD instruction -- `vaddlva.u16 r0,r1,q0'
+[^:]*:28: Error: bad type in SIMD instruction -- `vaddlva.u64 r0,r1,q0'
+[^:]*:29: Error: Odd register not allowed here -- `vaddlv.s32 r1,r3,q0'
+[^:]*:30: Error: Even register not allowed here -- `vaddlva.s32 r0,r2,q0'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Error: syntax error -- `vaddlveq.s32 r0,r1,q0'
+[^:]*:34: Error: syntax error -- `vaddlveq.s32 r0,r1,q0'
+[^:]*:36: Error: syntax error -- `vaddlveq.s32 r0,r1,q0'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vaddlvt.s32 r0,r1,q0'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vaddlv.s32 r0,r1,q0'
+[^:]*:41: Error: syntax error -- `vaddlvaeq.s32 r0,r1,q0'
+[^:]*:42: Error: syntax error -- `vaddlvaeq.s32 r0,r1,q0'
+[^:]*:44: Error: syntax error -- `vaddlvaeq.s32 r0,r1,q0'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vaddlvat.s32 r0,r1,q0'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vaddlva.s32 r0,r1,q0'
diff --git a/gas/testsuite/gas/arm/mve-vaddlv-bad.s b/gas/testsuite/gas/arm/mve-vaddlv-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..eda6923ffed6b836f5b40db73309e39601f8e650
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddlv-bad.s
@@ -0,0 +1,47 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+.irp mnem, vaddlv.s32, vaddlva.u32
+it \cond
+\mnem r0, r1, q0
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vaddlv.i32 r0, r1, q0
+vaddlv.f32 r0, r1, q0
+vaddlv.s8 r0, r1, q0
+vaddlv.s16 r0, r1, q0
+vaddlv.s64 r0, r1, q0
+vaddlv.u8 r0, r1, q0
+vaddlv.u16 r0, r1, q0
+vaddlv.u64 r0, r1, q0
+vaddlva.i32 r0, r1, q0
+vaddlva.f32 r0, r1, q0
+vaddlva.s8 r0, r1, q0
+vaddlva.s16 r0, r1, q0
+vaddlva.s64 r0, r1, q0
+vaddlva.u8 r0, r1, q0
+vaddlva.u16 r0, r1, q0
+vaddlva.u64 r0, r1, q0
+vaddlv.s32 r1, r3, q0
+vaddlva.s32 r0, r2, q0
+vaddlv.s32 r0, sp, q0
+it eq
+vaddlveq.s32 r0, r1, q0
+vaddlveq.s32 r0, r1, q0
+vpst
+vaddlveq.s32 r0, r1, q0
+vaddlvt.s32 r0, r1, q0
+vpst
+vaddlv.s32 r0, r1, q0
+it eq
+vaddlvaeq.s32 r0, r1, q0
+vaddlvaeq.s32 r0, r1, q0
+vpst
+vaddlvaeq.s32 r0, r1, q0
+vaddlvat.s32 r0, r1, q0
+vpst
+vaddlva.s32 r0, r1, q0
diff --git a/gas/testsuite/gas/arm/mve-vaddv-bad.d b/gas/testsuite/gas/arm/mve-vaddv-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..2291b7af74f47a34a3c3ef94d9c481f789877c2a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddv-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VADDV instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vaddv-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vaddv-bad.l b/gas/testsuite/gas/arm/mve-vaddv-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..0d77dbdb41bcab7b2decdb91258dcd93f5e6c955
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddv-bad.l
@@ -0,0 +1,32 @@
+[^:]*: Assembler messages:
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Error: bad type in SIMD instruction -- `vaddv.i32 r0,q0'
+[^:]*:14: Error: bad type in SIMD instruction -- `vaddv.f32 r0,q0'
+[^:]*:15: Error: bad type in SIMD instruction -- `vaddv.s64 r0,q0'
+[^:]*:16: Error: bad type in SIMD instruction -- `vaddv.u64 r0,q0'
+[^:]*:17: Error: bad type in SIMD instruction -- `vaddva.i32 r0,q0'
+[^:]*:18: Error: bad type in SIMD instruction -- `vaddva.f32 r0,q0'
+[^:]*:19: Error: bad type in SIMD instruction -- `vaddva.s64 r0,q0'
+[^:]*:20: Error: bad type in SIMD instruction -- `vaddva.u64 r0,q0'
+[^:]*:21: Error: Odd register not allowed here -- `vaddv.s32 r1,q0'
+[^:]*:23: Error: syntax error -- `vaddveq.s32 r0,q0'
+[^:]*:24: Error: syntax error -- `vaddveq.s32 r0,q0'
+[^:]*:26: Error: syntax error -- `vaddveq.s32 r0,q0'
+[^:]*:27: Error: vector predicated instruction should be in VPT/VPST block -- `vaddvt.s32 r0,q0'
+[^:]*:29: Error: instruction missing MVE vector predication code -- `vaddv.s32 r0,q0'
+[^:]*:31: Error: syntax error -- `vaddvaeq.s32 r0,q0'
+[^:]*:32: Error: syntax error -- `vaddvaeq.s32 r0,q0'
+[^:]*:34: Error: syntax error -- `vaddvaeq.s32 r0,q0'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vaddvat.s32 r0,q0'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vaddva.s32 r0,q0'
diff --git a/gas/testsuite/gas/arm/mve-vaddv-bad.s b/gas/testsuite/gas/arm/mve-vaddv-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..eb5a65de128c5b9dbdca13231c8874152adf119c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vaddv-bad.s
@@ -0,0 +1,37 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+.irp mnem, vaddv.s32, vaddva.u32
+it \cond
+\mnem r0, q0
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+vaddv.i32 r0, q0
+vaddv.f32 r0, q0
+vaddv.s64 r0, q0
+vaddv.u64 r0, q0
+vaddva.i32 r0, q0
+vaddva.f32 r0, q0
+vaddva.s64 r0, q0
+vaddva.u64 r0, q0
+vaddv.s32 r1, q0
+it eq
+vaddveq.s32 r0, q0
+vaddveq.s32 r0, q0
+vpst
+vaddveq.s32 r0, q0
+vaddvt.s32 r0, q0
+vpst
+vaddv.s32 r0, q0
+it eq
+vaddvaeq.s32 r0, q0
+vaddvaeq.s32 r0, q0
+vpst
+vaddvaeq.s32 r0, q0
+vaddvat.s32 r0, q0
+vpst
+vaddva.s32 r0, q0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 13/57][Arm][GAS] Add support for MVE instructions: vand, vbic, vorr, vorn and veor
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (11 preceding siblings ...)
  2019-05-01 17:06 ` [PATCH 12/57][Arm][GAS] Add support for MVE instructions: vaddlv and vaddv Andre Vieira (lists)
@ 2019-05-01 17:07 ` Andre Vieira (lists)
  2019-05-01 17:08 ` [PATCH 14/57][Arm][GAS] Add support for MVE instructions: vcadd, vcmla and vcmul Andre Vieira (lists)
                   ` (47 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:07 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1168 bytes --]

Hi,

This patch adds support for MVE instructions VAND, VBIC, VORR, VORN, and 
VEOR.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): New operands.
	(parse_operands): Handle new operands.
	(enum vfp_or_neon_is_neon_bits): Moved
	(vfp_or_neon_is_neon): Moved
	(check_simd_pred_availability): Moved.
	(do_neon_logic): Change to accept MVE variants.
	(insns): Changed to accept MVE variants.
	* testsuite/gas/arm/mve-vand-bad.d: New test.
	* testsuite/gas/arm/mve-vand-bad.l: New test.
	* testsuite/gas/arm/mve-vand-bad.s: New test.
	* testsuite/gas/arm/mve-vbic-bad.d: New test.
	* testsuite/gas/arm/mve-vbic-bad.l: New test.
	* testsuite/gas/arm/mve-vbic-bad.s: New test.
	* testsuite/gas/arm/mve-veor-bad.d: New test.
	* testsuite/gas/arm/mve-veor-bad.l: New test.
	* testsuite/gas/arm/mve-veor-bad.s: New test.
	* testsuite/gas/arm/mve-vorn-bad.d: New test.
	* testsuite/gas/arm/mve-vorn-bad.l: New test.
	* testsuite/gas/arm/mve-vorn-bad.s: New test.
	* testsuite/gas/arm/mve-vorr-bad.d: New test.
	* testsuite/gas/arm/mve-vorr-bad.l: New test.
	* testsuite/gas/arm/mve-vorr-bad.s: New test.

[-- Attachment #2: 13.patch --]
[-- Type: text/x-patch, Size: 24832 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 34e2c592ab00c32bd829152693d6fa036dc2a81f..ce50b9e6040c8af62b7a5c3a4461da881b77d817 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6957,6 +6957,8 @@ enum operand_parse_code
   OP_RND_RNSC,  /* Neon D reg, or Neon scalar.  */
   OP_VMOV,      /* Neon VMOV operands.  */
   OP_RNDQ_Ibig,	/* Neon D or Q reg, or big immediate for logic and VMVN.  */
+  /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN.  */
+  OP_RNDQMQ_Ibig,
   OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift.  */
   OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2.  */
   OP_VLDR,	/* VLDR operand.  */
@@ -7371,6 +7373,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
 	  break;
 
+	case OP_RNDQMQ_Ibig:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
+	  break;
+	try_rndq_ibig:
 	case OP_RNDQ_Ibig:
 	  {
 	    po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
@@ -16005,12 +16011,104 @@ 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)
 {
   if (inst.operands[2].present && inst.operands[2].isreg)
     {
       enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+      if (rs == NS_QQQ
+	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
+	  == FAIL)
+	return;
+      else if (rs != NS_QQQ
+	       && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
+	first_error (BAD_FPU);
+
       neon_check_type (3, rs, N_IGNORE_TYPE);
       /* U bit and size field were set as part of the bitmask.  */
       NEON_ENCODE (INTEGER, inst);
@@ -16024,14 +16122,29 @@ do_neon_logic (void)
       enum neon_shape rs = (three_ops_form
 			    ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
 			    : neon_select_shape (NS_DI, NS_QI, NS_NULL));
-      struct neon_type_el et = neon_check_type (2, rs,
-	N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
+      /* Because neon_select_shape makes the second operand a copy of the first
+	 if the second operand is not present.  */
+      if (rs == NS_QQI
+	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
+	  == FAIL)
+	return;
+      else if (rs != NS_QQI
+	       && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
+	first_error (BAD_FPU);
+
+      struct neon_type_el et;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
+      else
+	et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
+			      | N_KEY, N_EQK);
+
+      if (et.type == NT_invtype)
+	return;
       enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
       unsigned immbits;
       int cmode;
 
-      if (et.type == NT_invtype)
-	return;
 
       if (three_ops_form)
 	constraint (inst.operands[0].reg != inst.operands[1].reg,
@@ -16141,90 +16254,6 @@ do_neon_dyadic_if_i_d (void)
   neon_dyadic_misc (NT_untyped, N_IF_32, 0);
 }
 
-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_mve_vstr_vldr_QI (int size, int elsize, int load)
 {
@@ -23349,15 +23378,10 @@ static const struct asm_opcode insns[] =
  nUF(vqshl,     _vqshl,   3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
  nUF(vqshlq,    _vqshl,   3, (RNQ,  oRNQ,  RNDQ_I63b), neon_qshl_imm),
   /* Logic ops, types optional & ignored.  */
- nUF(vand,      _vand,    3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
  nUF(vandq,     _vand,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
- nUF(vbic,      _vbic,    3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
  nUF(vbicq,     _vbic,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
- nUF(vorr,      _vorr,    3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
  nUF(vorrq,     _vorr,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
- nUF(vorn,      _vorn,    3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
  nUF(vornq,     _vorn,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
- nUF(veor,      _veor,    3, (RNDQ, oRNDQ, RNDQ),      neon_logic),
  nUF(veorq,     _veor,    3, (RNQ,  oRNQ,  RNQ),       neon_logic),
   /* Bitfield ops, untyped.  */
  NUF(vbsl,      1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
@@ -24110,10 +24134,15 @@ static const struct asm_opcode insns[] =
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & fpu_neon_ext_v1
- mnUF(vabd,      _vabd,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
+ mnUF(vabd,      _vabd,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
  mnUF(vabdl,     _vabdl,	  3, (RNQMQ, RNDMQ, RNDMQ),   neon_dyadic_long),
  mnUF(vaddl,     _vaddl,	  3, (RNQMQ, RNDMQ, RNDMQR),  neon_dyadic_long),
  mnUF(vsubl,     _vsubl,	  3, (RNQMQ, RNDMQ, RNDMQR),  neon_dyadic_long),
+ mnUF(vand,      _vand,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
+ mnUF(vbic,      _vbic,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
+ mnUF(vorr,      _vorr,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
+ mnUF(vorn,      _vorn,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
+ mnUF(veor,      _veor,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
 };
 #undef ARM_VARIANT
 #undef THUMB_VARIANT
diff --git a/gas/testsuite/gas/arm/mve-vand-bad.d b/gas/testsuite/gas/arm/mve-vand-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..1889759d344b460b8e1e7d54359fe989a4940bf1
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vand-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VAND instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vand-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vand-bad.l b/gas/testsuite/gas/arm/mve-vand-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..f6044b123ee0e61d05657765abc974aaa7083194
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vand-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vandeq q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vandeq q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vandeq q0,q1,q2'
+[^:]*:24: Error: instruction missing MVE vector predication code -- `vand q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vandt q0,q1,q2'
+[^:]*: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
+[^:]*:28: Error: syntax error -- `vandeq.i16 q0,#255'
+[^:]*:29: Error: syntax error -- `vandeq.i16 q0,#255'
+[^:]*:31: Error: syntax error -- `vandeq.i16 q0,#255'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vand.i16 q0,#255'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vandt.i16 q0,#255'
+[^:]*:35: Error: bad type in SIMD instruction -- `vand.i8 q0,#255'
+[^:]*:36: Error: bad type in SIMD instruction -- `vand.i64 q0,#255'
+[^:]*:37: Error: immediate value out of range -- `vand.i16 q0,#0'
+[^:]*:38: Error: immediate value out of range -- `vand.i32 q0,#0'
diff --git a/gas/testsuite/gas/arm/mve-vand-bad.s b/gas/testsuite/gas/arm/mve-vand-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..77f27bdc4db8c190c41d3f94a824878aae9fdbcc
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vand-bad.s
@@ -0,0 +1,38 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vand q0, q1, q2
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vand.i16 q0, #255
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1
+it eq
+vandeq q0, q1, q2
+vandeq q0, q1, q2
+vpst
+vandeq q0, q1, q2
+vpst
+vand q0, q1, q2
+vandt q0, q1, q2
+cond2
+it eq
+vandeq.i16 q0, #255
+vandeq.i16 q0, #255
+vpst
+vandeq.i16 q0, #255
+vpst
+vand.i16 q0, #255
+vandt.i16 q0, #255
+vand.i8 q0, #255
+vand.i64 q0, #255
+vand.i16 q0, #0
+vand.i32 q0, #0
diff --git a/gas/testsuite/gas/arm/mve-vbic-bad.d b/gas/testsuite/gas/arm/mve-vbic-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..5c17bf47589d7bbfd8140126ddcb69cecaa98297
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbic-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VBIC instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vbic-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vbic-bad.l b/gas/testsuite/gas/arm/mve-vbic-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..10deb9dcd02aca1d870fac04273815b600cd0180
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbic-bad.l
@@ -0,0 +1,28 @@
+[^:]*: Assembler messages:
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vbiceq q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vbiceq q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vbiceq q0,q1,q2'
+[^:]*:24: Error: instruction missing MVE vector predication code -- `vbic q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vbict q0,q1,q2'
+[^:]*: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
+[^:]*:28: Error: syntax error -- `vbiceq.i16 q0,#255'
+[^:]*:29: Error: syntax error -- `vbiceq.i16 q0,#255'
+[^:]*:31: Error: syntax error -- `vbiceq.i16 q0,#255'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vbic.i16 q0,#255'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vbict.i16 q0,#255'
+[^:]*:35: Error: bad type in SIMD instruction -- `vbic.i8 q0,#255'
+[^:]*:36: Error: bad type in SIMD instruction -- `vbic.i64 q0,#255'
+[^:]*:37: Error: immediate value out of range -- `vbic.i16 q0,#257'
+[^:]*:38: Error: immediate value out of range -- `vbic.i32 q0,#257'
+
diff --git a/gas/testsuite/gas/arm/mve-vbic-bad.s b/gas/testsuite/gas/arm/mve-vbic-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..4f35158e05bcf7a5e29705dce15fe76e870841a3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vbic-bad.s
@@ -0,0 +1,38 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vbic q0, q1, q2
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vbic.i16 q0, #255
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1
+it eq
+vbiceq q0, q1, q2
+vbiceq q0, q1, q2
+vpst
+vbiceq q0, q1, q2
+vpst
+vbic q0, q1, q2
+vbict q0, q1, q2
+cond2
+it eq
+vbiceq.i16 q0, #255
+vbiceq.i16 q0, #255
+vpst
+vbiceq.i16 q0, #255
+vpst
+vbic.i16 q0, #255
+vbict.i16 q0, #255
+vbic.i8 q0, #255
+vbic.i64 q0, #255
+vbic.i16 q0, #257
+vbic.i32 q0, #257
diff --git a/gas/testsuite/gas/arm/mve-veor-bad.d b/gas/testsuite/gas/arm/mve-veor-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..e51228660bb45955cc131a8f1993255ad361b008
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-veor-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VEOR instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-veor-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-veor-bad.l b/gas/testsuite/gas/arm/mve-veor-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..3da9c7170ee7051a6a983f89df1f720ef921d42c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-veor-bad.l
@@ -0,0 +1,12 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Error: syntax error -- `veoreq q0,q1,q2'
+[^:]*:13: Error: syntax error -- `veoreq q0,q1,q2'
+[^:]*:15: Error: syntax error -- `veoreq q0,q1,q2'
+[^:]*:17: Error: instruction missing MVE vector predication code -- `veor q0,q1,q2'
+[^:]*:18: Error: vector predicated instruction should be in VPT/VPST block -- `veort q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-veor-bad.s b/gas/testsuite/gas/arm/mve-veor-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..ffc1a0095055ca72b5a567bebab3db0454034e01
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-veor-bad.s
@@ -0,0 +1,18 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+veor q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+it eq
+veoreq q0, q1, q2
+veoreq q0, q1, q2
+vpst
+veoreq q0, q1, q2
+vpst
+veor q0, q1, q2
+veort q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vorn-bad.d b/gas/testsuite/gas/arm/mve-vorn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..e78957f9ece3bf063cc3aa8c6b103b99a4f0fe3d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorn-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VORN instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vorn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vorn-bad.l b/gas/testsuite/gas/arm/mve-vorn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..69e479b847989b231a685491ae46c28def8a217b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorn-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vorneq q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vorneq q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vorneq q0,q1,q2'
+[^:]*:24: Error: instruction missing MVE vector predication code -- `vorn q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vornt q0,q1,q2'
+[^:]*: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
+[^:]*:28: Error: syntax error -- `vorneq.i16 q0,#255'
+[^:]*:29: Error: syntax error -- `vorneq.i16 q0,#255'
+[^:]*:31: Error: syntax error -- `vorneq.i16 q0,#255'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vorn.i16 q0,#255'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vornt.i16 q0,#255'
+[^:]*:35: Error: bad type in SIMD instruction -- `vorn.i8 q0,#255'
+[^:]*:36: Error: bad type in SIMD instruction -- `vorn.i64 q0,#255'
+[^:]*:37: Error: immediate value out of range -- `vorn.i16 q0,#0'
+[^:]*:38: Error: immediate value out of range -- `vorn.i32 q0,#0'
diff --git a/gas/testsuite/gas/arm/mve-vorn-bad.s b/gas/testsuite/gas/arm/mve-vorn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..9a2edb0cfcbd4a137cb3027599a954c8e69b537c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorn-bad.s
@@ -0,0 +1,38 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vorn q0, q1, q2
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vorn.i16 q0, #255
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1
+it eq
+vorneq q0, q1, q2
+vorneq q0, q1, q2
+vpst
+vorneq q0, q1, q2
+vpst
+vorn q0, q1, q2
+vornt q0, q1, q2
+cond2
+it eq
+vorneq.i16 q0, #255
+vorneq.i16 q0, #255
+vpst
+vorneq.i16 q0, #255
+vpst
+vorn.i16 q0, #255
+vornt.i16 q0, #255
+vorn.i8 q0, #255
+vorn.i64 q0, #255
+vorn.i16 q0, #0
+vorn.i32 q0, #0
diff --git a/gas/testsuite/gas/arm/mve-vorr-bad.d b/gas/testsuite/gas/arm/mve-vorr-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..4e94b8a4d460b5844ad7919d58f6e5261f34bc29
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorr-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VORR instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vorr-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vorr-bad.l b/gas/testsuite/gas/arm/mve-vorr-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..19a0ab8d09c6c964997a1f3d69e25c5b2762a72b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorr-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vorreq q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vorreq q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vorreq q0,q1,q2'
+[^:]*:24: Error: instruction missing MVE vector predication code -- `vorr q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vorrt q0,q1,q2'
+[^:]*: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
+[^:]*:28: Error: syntax error -- `vorreq.i16 q0,#255'
+[^:]*:29: Error: syntax error -- `vorreq.i16 q0,#255'
+[^:]*:31: Error: syntax error -- `vorreq.i16 q0,#255'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vorr.i16 q0,#255'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vorrt.i16 q0,#255'
+[^:]*:35: Error: bad type in SIMD instruction -- `vorr.i8 q0,#255'
+[^:]*:36: Error: bad type in SIMD instruction -- `vorr.i64 q0,#255'
+[^:]*:37: Error: immediate value out of range -- `vorr.i16 q0,#257'
+[^:]*:38: Error: immediate value out of range -- `vorr.i32 q0,#257'
diff --git a/gas/testsuite/gas/arm/mve-vorr-bad.s b/gas/testsuite/gas/arm/mve-vorr-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..671e35f71026b3ec8a5d1efd4d7eab7162ac5ace
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vorr-bad.s
@@ -0,0 +1,38 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vorr q0, q1, q2
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vorr.i16 q0, #255
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1
+it eq
+vorreq q0, q1, q2
+vorreq q0, q1, q2
+vpst
+vorreq q0, q1, q2
+vpst
+vorr q0, q1, q2
+vorrt q0, q1, q2
+cond2
+it eq
+vorreq.i16 q0, #255
+vorreq.i16 q0, #255
+vpst
+vorreq.i16 q0, #255
+vpst
+vorr.i16 q0, #255
+vorrt.i16 q0, #255
+vorr.i8 q0, #255
+vorr.i64 q0, #255
+vorr.i16 q0, #257
+vorr.i32 q0, #257

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 14/57][Arm][GAS] Add support for MVE instructions: vcadd, vcmla and vcmul
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (12 preceding siblings ...)
  2019-05-01 17:07 ` [PATCH 13/57][Arm][GAS] Add support for MVE instructions: vand, vbic, vorr, vorn and veor Andre Vieira (lists)
@ 2019-05-01 17:08 ` Andre Vieira (lists)
  2019-05-01 17:09 ` [PATCH 15/57][Arm][GAS] Add support for MVE instructions: vcls, vclz and vfmas Andre Vieira (lists)
                   ` (46 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:08 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1352 bytes --]

Hi,

This patch adds support for MVE instructions VCADD, VCMLA, and VCMUL.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): New operands.
	(parse_operands): Handle new operands.
	(do_mve_vcmul): New encoding function.
	(do_vcmla): Change to support MVE variants.
	(do_vcadd): Change to support MVE variants.
         (insns): Change existing to support MVE variants and add new.
* testsuite/gas/arm/mve-vcadd-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcadd-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcadd-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcadd-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcadd-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcadd-bad-2.s: New test.
	* testsuite/gas/arm/mve-vcmla-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcmla-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcmla-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcmla-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcmla-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcmla-bad-2.s: New test.
	* testsuite/gas/arm/mve-vcmul-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcmul-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcmul-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcmul-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcmul-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcmul-bad-2.s: New test.

[-- Attachment #2: 14.patch --]
[-- Type: text/x-patch, Size: 21094 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index ce50b9e6040c8af62b7a5c3a4461da881b77d817..171ae9be36bfb5733037fbb0e4647be4acc2279f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6954,6 +6954,7 @@ enum operand_parse_code
   OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
 		     */
   OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar.  */
+  OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar.  */
   OP_RND_RNSC,  /* Neon D reg, or Neon scalar.  */
   OP_VMOV,      /* Neon VMOV operands.  */
   OP_RNDQ_Ibig,	/* Neon D or Q reg, or big immediate for logic and VMVN.  */
@@ -7349,6 +7350,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  }
 	  break;
 
+	case OP_RNDQMQ_RNSC:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
+	  break;
+	try_rndq_rnsc:
 	case OP_RNDQ_RNSC:
 	  {
 	    po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
@@ -15577,6 +15582,38 @@ do_mve_vcmp (void)
   return;
 }
 
+static void
+do_mve_vcmul (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_F_MVE | 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 != 0 && rot != 90 && rot != 180 && rot != 270,
+	      _("immediate out of range"));
+
+  if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
+			|| inst.operands[0].reg == inst.operands[2].reg))
+    as_tsktsk (BAD_MVE_SRCDEST);
+
+  inst.instruction |= (et.size == 32) << 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 |= (rot > 90) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[2].reg);
+  inst.instruction |= (rot == 90 || rot == 270);
+  inst.is_neon = 1;
+}
+
 static void
 do_vfp_nsyn_cmp (void)
 {
@@ -19679,16 +19716,23 @@ neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
 static void
 do_vcmla (void)
 {
-  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
-	      _(BAD_FPU));
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
+	      && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
+		  || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
   constraint (inst.relocs[0].exp.X_op != O_constant,
 	      _("expression too complex"));
   unsigned rot = inst.relocs[0].exp.X_add_number;
   constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
 	      _("immediate out of range"));
   rot /= 90;
+
+  if (check_simd_pred_availability (1, NEON_CHECK_ARCH8 | NEON_CHECK_CC))
+    return;
+
   if (inst.operands[2].isscalar)
     {
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
+	first_error (_("invalid instruction shape"));
       enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
       unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
 				       N_KEY | N_F16 | N_F32).size;
@@ -19707,9 +19751,19 @@ do_vcmla (void)
     }
   else
     {
-      enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
+      enum neon_shape rs;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
+	rs = neon_select_shape (NS_QQQI, NS_NULL);
+      else
+	rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
+
       unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
 				       N_KEY | N_F16 | N_F32).size;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
+	  && (inst.operands[0].reg == inst.operands[1].reg
+	      || inst.operands[0].reg == inst.operands[2].reg))
+	as_tsktsk (BAD_MVE_SRCDEST);
+
       neon_three_same (neon_quad (rs), 0, -1);
       inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup.  */
       inst.instruction |= 0xfc200800;
@@ -19721,20 +19775,60 @@ do_vcmla (void)
 static void
 do_vcadd (void)
 {
-  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
-	      _(BAD_FPU));
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
+	      && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
+		  || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
   constraint (inst.relocs[0].exp.X_op != O_constant,
 	      _("expression too complex"));
+
   unsigned rot = inst.relocs[0].exp.X_add_number;
   constraint (rot != 90 && rot != 270, _("immediate out of range"));
-  enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
-  unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
-				   N_KEY | N_F16 | N_F32).size;
-  neon_three_same (neon_quad (rs), 0, -1);
-  inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup.  */
-  inst.instruction |= 0xfc800800;
-  inst.instruction |= (rot == 270) << 24;
-  inst.instruction |= (size == 32) << 20;
+  enum neon_shape rs;
+  struct neon_type_el et;
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    {
+      rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_QQQI, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
+			    | N_I16 | N_I32);
+      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"));
+    }
+
+  if (et.type == NT_invtype)
+    return;
+
+  if (check_simd_pred_availability (et.type == NT_float, NEON_CHECK_ARCH8
+				    | NEON_CHECK_CC))
+    return;
+
+  if (et.type == NT_float)
+    {
+      neon_three_same (neon_quad (rs), 0, -1);
+      inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup.  */
+      inst.instruction |= 0xfc800800;
+      inst.instruction |= (rot == 270) << 24;
+      inst.instruction |= (et.size == 32) << 20;
+    }
+  else
+    {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
+      inst.instruction = 0xfe000f00;
+      inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+      inst.instruction |= neon_logbits (et.size) << 20;
+      inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+      inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+      inst.instruction |= (rot == 270) << 12;
+      inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+      inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+      inst.instruction |= LOW4 (inst.operands[2].reg);
+      inst.is_neon = 1;
+    }
 }
 
 /* Dot Product instructions encoding support.  */
@@ -22721,8 +22815,6 @@ static const struct asm_opcode insns[] =
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT & arm_ext_v8_3
  NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
- NUF (vcmla, 0, 4, (RNDQ, RNDQ, RNDQ_RNSC, EXPi), vcmla),
- NUF (vcadd, 0, 4, (RNDQ, RNDQ, RNDQ, EXPi), vcadd),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT   & fpu_neon_ext_dotprod
@@ -24089,6 +24181,10 @@ static const struct asm_opcode insns[] =
  mCEF(vaddv,	_vaddv,	    2, (RRe, RMQ),			  mve_vaddv),
  mCEF(vaddva,	_vaddva,    2, (RRe, RMQ),			  mve_vaddv),
 
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & mve_fp_ext
+ mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
 #undef  THUMB_VARIANT
@@ -24143,6 +24239,13 @@ static const struct asm_opcode insns[] =
  mnUF(vorr,      _vorr,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(vorn,      _vorn,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(veor,      _veor,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
+
+#undef	ARM_VARIANT
+#define ARM_VARIANT & arm_ext_v8_3
+#undef	THUMB_VARIANT
+#define	THUMB_VARIANT & arm_ext_v6t2_v8m
+ MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
+ MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
 };
 #undef ARM_VARIANT
 #undef THUMB_VARIANT
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-1.d b/gas/testsuite/gas/arm/mve-vcadd-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..dbadb30cc8d0b2173b7ebcfc20edf86baab7f600
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCADD instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vcadd-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-1.l b/gas/testsuite/gas/arm/mve-vcadd-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..dee86afb03018df799f689e087d730be2066617e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-1.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: selected FPU does not support instruction -- `vcadd.f16 q0,q1,q2,#90'
+[^:]*:11: Error: bad type in SIMD instruction -- `vcadd.64 q0,q1,q2,#90'
+[^:]*:12: Error: immediate out of range -- `vcadd.i32 q0,q1,q2,#180'
+[^:]*:13: Error: immediate out of range -- `vcadd.i32 q0,q1,q2,#0'
+[^:]*:14: Warning: 32-bit element size and same first and third operand makes instruction UNPREDICTABLE
+[^:]*: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 -- `vcaddeq.i16 q0,q1,q2,#90'
+[^:]*:18: Error: syntax error -- `vcaddeq.i16 q0,q1,q2,#90'
+[^:]*:20: Error: syntax error -- `vcaddeq.i16 q0,q1,q2,#90'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vcaddt.i16 q0,q1,q2,#90'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcadd.i16 q0,q1,q2,#90'
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-1.s b/gas/testsuite/gas/arm/mve-vcadd-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..23a686e63c1b5d506ccdd349ad8eb0e0cc69bae2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-1.s
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcadd.i16 q0, q1, q2, #90
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcadd.f16 q0, q1, q2, #90
+vcadd.64 q0, q1, q2, #90
+vcadd.i32 q0, q1, q2, #180
+vcadd.i32 q0, q1, q2, #0
+vcadd.i32 q0, q1, q0, #90
+cond
+it eq
+vcaddeq.i16 q0, q1, q2, #90
+vcaddeq.i16 q0, q1, q2, #90
+vpst
+vcaddeq.i16 q0, q1, q2, #90
+vcaddt.i16 q0, q1, q2, #90
+vpst
+vcadd.i16 q0, q1, q2, #90
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-2.d b/gas/testsuite/gas/arm/mve-vcadd-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..271160c31cee95b417c588c9c13359cf9b4f1e71
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VCADD instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcadd-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-2.l b/gas/testsuite/gas/arm/mve-vcadd-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..cdf3fd3af9b5c7cd846d7659f24a8899d9561c6f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-2.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vcadd.f64 q0,q1,q2,#90'
+[^:]*:11: Error: immediate out of range -- `vcadd.f32 q0,q1,q2,#180'
+[^:]*:12: Error: immediate out of range -- `vcadd.f32 q0,q1,q2,#0'
+[^:]*:13: Warning: 32-bit element size and same first and third operand makes instruction UNPREDICTABLE
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: syntax error -- `vcaddeq.f16 q0,q1,q2,#90'
+[^:]*:17: Error: syntax error -- `vcaddeq.f16 q0,q1,q2,#90'
+[^:]*:19: Error: syntax error -- `vcaddeq.f16 q0,q1,q2,#90'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vcaddt.f16 q0,q1,q2,#90'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vcadd.f16 q0,q1,q2,#90'
+
diff --git a/gas/testsuite/gas/arm/mve-vcadd-bad-2.s b/gas/testsuite/gas/arm/mve-vcadd-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..9634840dbdaca5622aa9ba5333a1ae3c46b4e349
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcadd-bad-2.s
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcadd.f32 q0, q1, q2, #90
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcadd.f64 q0, q1, q2, #90
+vcadd.f32 q0, q1, q2, #180
+vcadd.f32 q0, q1, q2, #0
+vcadd.f32 q0, q1, q0, #90
+cond
+it eq
+vcaddeq.f16 q0, q1, q2, #90
+vcaddeq.f16 q0, q1, q2, #90
+vpst
+vcaddeq.f16 q0, q1, q2, #90
+vcaddt.f16 q0, q1, q2, #90
+vpst
+vcadd.f16 q0, q1, q2, #90
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-1.d b/gas/testsuite/gas/arm/mve-vcmla-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..477486d7b0bc364c3a13962fbd557c4bb54554f0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCMLA instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vcmla-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-1.l b/gas/testsuite/gas/arm/mve-vcmla-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..d660f4972ea6b66445cd3806ac9a5ba7542c99a3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-1.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: selected FPU does not support instruction -- `vcmla.f16 q0,q1,q2,#0'
+[^:]*:4: Error: selected FPU does not support instruction -- `vcmla.f32 q0,q1,q2,#0'
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-1.s b/gas/testsuite/gas/arm/mve-vcmla-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..68202040a2e5112eb62f356696631843dc210be0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-1.s
@@ -0,0 +1,4 @@
+.syntax unified
+.thumb
+vcmla.f16 q0, q1, q2, #0
+vcmla.f32 q0, q1, q2, #0
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-2.d b/gas/testsuite/gas/arm/mve-vcmla-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..6a95d41b4b6a6e8205991fa4a9589a2c6a5f10dd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VCMLA instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcmla-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-2.l b/gas/testsuite/gas/arm/mve-vcmla-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..ca1d34950de044aa3c8ae108145d58f4a9704a0c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-2.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: immediate out of range -- `vcmla.f16 q0,q1,q2,#20'
+[^:]*:11: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:12: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:13: Error: bad type in SIMD instruction -- `vcmla.f64 q0,q1,q2,#0'
+[^:]*:14: Error: bad type in SIMD instruction -- `vcmla.i16 q0,q1,q2,#0'
+[^:]*: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 -- `vcmlaeq.f16 q0,q1,q2,#0'
+[^:]*:18: Error: syntax error -- `vcmlaeq.f16 q0,q1,q2,#0'
+[^:]*:20: Error: syntax error -- `vcmlaeq.f16 q0,q1,q2,#0'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vcmlat.f16 q0,q1,q2,#0'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcmla.f16 q0,q1,q2,#0'
diff --git a/gas/testsuite/gas/arm/mve-vcmla-bad-2.s b/gas/testsuite/gas/arm/mve-vcmla-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..d9ddb1f8735f4c01e97b2361e37db0bec122e04d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmla-bad-2.s
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcmla.f32 q0, q1, q2, #0
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcmla.f16 q0, q1, q2, #20
+vcmla.f32 q0, q0, q1, #0
+vcmla.f32 q0, q1, q0, #0
+vcmla.f64 q0, q1, q2, #0
+vcmla.i16 q0, q1, q2, #0
+cond
+it eq
+vcmlaeq.f16 q0, q1, q2, #0
+vcmlaeq.f16 q0, q1, q2, #0
+vpst
+vcmlaeq.f16 q0, q1, q2, #0
+vcmlat.f16 q0, q1, q2, #0
+vpst
+vcmla.f16 q0, q1, q2, #0
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-1.d b/gas/testsuite/gas/arm/mve-vcmul-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..34fb38f60885be72df5a8feb879f88985a30c8eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCMUL instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vcmul-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-1.l b/gas/testsuite/gas/arm/mve-vcmul-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..2b2e6c43317feaa4e0f0148c53b0f3762df538bf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-1.l
@@ -0,0 +1,4 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: selected processor does not support `vcmul.f16 q0,q1,q2,#0' in Thumb mode
+[^:]*:4: Error: selected processor does not support `vcmul.f32 q0,q1,q2,#0' in Thumb mode
+[^:]*:5: Error: selected processor does not support `vcmul.i16 q0,q1,q2,#0' in Thumb mode
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-1.s b/gas/testsuite/gas/arm/mve-vcmul-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..e8b405d775f3b7e4ce902683376bd9976a6fe381
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-1.s
@@ -0,0 +1,5 @@
+.syntax unified
+.thumb
+vcmul.f16 q0, q1, q2, #0
+vcmul.f32 q0, q1, q2, #0
+vcmul.i16 q0, q1, q2, #0
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-2.d b/gas/testsuite/gas/arm/mve-vcmul-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..c440cbc87cbc7dde84140c2fa73da002eea9ca97
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VCMUL instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcmul-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-2.l b/gas/testsuite/gas/arm/mve-vcmul-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..c2e58a46cafeed9987ce6096c8264495f0cd9a61
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-2.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vcmul.i16 q0,q1,q2,#0'
+[^:]*:11: Error: bad type in SIMD instruction -- `vcmul.f64 q0,q1,q2,#0'
+[^:]*:12: Error: immediate out of range -- `vcmul.f32 q0,q1,q2,#20'
+[^:]*:13: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*: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 -- `vcmuleq.f32 q0,q1,q2,#0'
+[^:]*:18: Error: syntax error -- `vcmuleq.f32 q0,q1,q2,#0'
+[^:]*:20: Error: syntax error -- `vcmuleq.f32 q0,q1,q2,#0'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vcmult.f32 q0,q1,q2,#0'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcmul.f32 q0,q1,q2,#0'
diff --git a/gas/testsuite/gas/arm/mve-vcmul-bad-2.s b/gas/testsuite/gas/arm/mve-vcmul-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..4eedefabb1883c4eef8ef2d7e70010b61ca8ce48
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmul-bad-2.s
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcmul.f32 q0, q1, q2, #0
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcmul.i16 q0, q1, q2, #0
+vcmul.f64 q0, q1, q2, #0
+vcmul.f32 q0, q1, q2, #20
+vcmul.f32 q0, q1, q0, #0
+vcmul.f32 q0, q0, q1, #0
+cond
+it eq
+vcmuleq.f32 q0, q1, q2, #0
+vcmuleq.f32 q0, q1, q2, #0
+vpst
+vcmuleq.f32 q0, q1, q2, #0
+vcmult.f32 q0, q1, q2, #0
+vpst
+vcmul.f32 q0, q1, q2, #0

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 16/57][Arm][GAS] Add support for MVE instructions: vdup, vddup, vdwdup, vidup and viwdup
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (14 preceding siblings ...)
  2019-05-01 17:09 ` [PATCH 15/57][Arm][GAS] Add support for MVE instructions: vcls, vclz and vfmas Andre Vieira (lists)
@ 2019-05-01 17:09 ` Andre Vieira (lists)
  2019-05-01 17:11 ` [PATCH 17/57][Arm][GAS] Add support for MVE instructions: vfma and vfms Andre Vieira (lists)
                   ` (44 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:09 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 898 bytes --]

Hi,

This patch adds support for MVE instructions VDUP, VDDUP, VDWDUP, VIDUP, 
and VIWDUP.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vddup, M_MNEM_vdwdup, M_MNEM_vidup,
	M_MNEM_viwdup): New instruction encodings.
	(NEON_SHAPE_DEF): New shapes.
	(do_mve_viddup): New encoding function.
	(do_neon_dup): Change to support new MVE variants.
         (insns): Change existing to accept MVE variants and add new.
	* testsuite/gas/arm/mve-vddup-bad.d: New test.
	* testsuite/gas/arm/mve-vddup-bad.l: New test.
	* testsuite/gas/arm/mve-vddup-bad.s: New test.
	* testsuite/gas/arm/mve-vdup-bad.d: New test.
	* testsuite/gas/arm/mve-vdup-bad.l: New test.
	* testsuite/gas/arm/mve-vdup-bad.s: New test.
	* testsuite/gas/arm/mve-vidup-bad.d: New test.
	* testsuite/gas/arm/mve-vidup-bad.l: New test.
	* testsuite/gas/arm/mve-vidup-bad.s: New test.

[-- Attachment #2: 16.patch --]
[-- Type: text/x-patch, Size: 15205 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index e739c5b94ab1924f65a262e15342a748e2a4dc40..af6550eeb95db17f444acc7e6bfdb73e3dc14f3c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14157,6 +14157,10 @@ do_t_loloop (void)
 #define M_MNEM_vaddlva	0xee890f20
 #define M_MNEM_vaddv	0xeef10f00
 #define M_MNEM_vaddva	0xeef10f20
+#define M_MNEM_vddup	0xee011f6e
+#define M_MNEM_vdwdup	0xee011f60
+#define M_MNEM_vidup	0xee010f6e
+#define M_MNEM_viwdup	0xee010f60
 
 /* Neon instruction encoder helpers.  */
 
@@ -14321,8 +14325,10 @@ NEON_ENC_TAB
      - a table used to drive neon_select_shape.  */
 
 #define NEON_SHAPE_DEF			\
+  X(4, (Q, R, R, I), QUAD),		\
   X(4, (R, R, S, S), QUAD),		\
   X(4, (S, S, R, R), QUAD),		\
+  X(3, (Q, R, I), QUAD),		\
   X(3, (I, Q, Q), QUAD),		\
   X(3, (I, Q, R), QUAD),		\
   X(3, (R, Q, Q), QUAD),		\
@@ -15608,6 +15614,49 @@ do_mve_vfmas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_viddup (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  unsigned imm = inst.relocs[0].exp.X_add_number;
+  constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
+	      _("immediate must be either 1, 2, 4 or 8"));
+
+  enum neon_shape rs;
+  struct neon_type_el et;
+  unsigned Rm;
+  if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
+    {
+      rs = neon_select_shape (NS_QRI, NS_NULL);
+      et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
+      Rm = 7;
+    }
+  else
+    {
+      constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
+      if (inst.operands[2].reg == REG_SP)
+	as_tsktsk (MVE_BAD_SP);
+      else if (inst.operands[2].reg == REG_PC)
+	first_error (BAD_PC);
+
+      rs = neon_select_shape (NS_QRRI, NS_NULL);
+      et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
+      Rm = inst.operands[2].reg >> 1;
+    }
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= neon_logbits (et.size) << 20;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= (imm > 2) << 7;
+  inst.instruction |= Rm << 1;
+  inst.instruction |= (imm == 2 || imm == 8);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vcmul (void)
 {
@@ -18407,6 +18456,8 @@ do_neon_dup (void)
 {
   if (inst.operands[1].isscalar)
     {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
+		  BAD_FPU);
       enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
       struct neon_type_el et = neon_check_type (2, rs,
 	N_EQK, N_8 | N_16 | N_32 | N_KEY);
@@ -18434,6 +18485,23 @@ do_neon_dup (void)
       enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
       struct neon_type_el et = neon_check_type (2, rs,
 	N_8 | N_16 | N_32 | N_KEY, N_EQK);
+      if (rs == NS_QR)
+	{
+	  if (check_simd_pred_availability (0, NEON_CHECK_ARCH))
+	    return;
+	}
+      else
+	constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
+		    BAD_FPU);
+
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  if (inst.operands[1].reg == REG_SP)
+	    as_tsktsk (MVE_BAD_SP);
+	  else if (inst.operands[1].reg == REG_PC)
+	    as_tsktsk (MVE_BAD_PC);
+	}
+
       /* Duplicate ARM register to lanes of vector.  */
       NEON_ENCODE (ARMREG, inst);
       switch (et.size)
@@ -23659,7 +23727,6 @@ static const struct asm_opcode insns[] =
  NUF(vrev16,    1b00100, 2, (RNDQ, RNDQ),     neon_rev),
  NUF(vrev16q,   1b00100, 2, (RNQ,  RNQ),      neon_rev),
   /* Vector replicate. Sizes 8 16 32.  */
- nCE(vdup,      _vdup,    2, (RNDQ, RR_RNSC),  neon_dup),
  nCE(vdupq,     _vdup,    2, (RNQ,  RR_RNSC),  neon_dup),
   /* VMOVL. Types S8 S16 S32 U8 U16 U32.  */
  NUF(vmovl,     0800a10, 2, (RNQ, RND),       neon_movl),
@@ -24221,6 +24288,10 @@ static const struct asm_opcode insns[] =
  mCEF(vaddlva,	_vaddlva,   3, (RRe, RRo, RMQ),			  mve_vaddlv),
  mCEF(vaddv,	_vaddv,	    2, (RRe, RMQ),			  mve_vaddv),
  mCEF(vaddva,	_vaddva,    2, (RRe, RMQ),			  mve_vaddv),
+ mCEF(vddup,	_vddup,	    3, (RMQ, RRe, EXPi),		  mve_viddup),
+ mCEF(vdwdup,	_vdwdup,    4, (RMQ, RRe, RR, EXPi),		  mve_viddup),
+ mCEF(vidup,	_vidup,	    3, (RMQ, RRe, EXPi),		  mve_viddup),
+ mCEF(viwdup,	_viwdup,    4, (RMQ, RRe, RR, EXPi),		  mve_viddup),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
@@ -24283,6 +24354,7 @@ static const struct asm_opcode insns[] =
  mnUF(veor,      _veor,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
  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),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.d b/gas/testsuite/gas/arm/mve-vddup-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..a6522dc25423352b027d58a0b0f495f7f0705245
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vddup-bad.d
@@ -0,0 +1,6 @@
+#name: bad MVE VDDUP and VDWDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vddup-bad.l
+
+.*: +file format .*arm.*
+
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.l b/gas/testsuite/gas/arm/mve-vddup-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..92ff9657446829f1f703d99be34384d21307e3a9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vddup-bad.l
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:16: Error: bad type in SIMD instruction -- `vddup.s16 q0,r0,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vddup.u64 q0,r0,#1'
+[^:]*:18: Error: immediate must be either 1, 2, 4 or 8 -- `vddup.u32 q0,r0,#3'
+[^:]*:19: Error: immediate must be either 1, 2, 4 or 8 -- `vddup.u32 q0,r0,#0'
+[^:]*:20: Error: bad type in SIMD instruction -- `vdwdup.s16 q0,r0,r1,#1'
+[^:]*:21: Error: bad type in SIMD instruction -- `vdwdup.u64 q0,r0,r1,#1'
+[^:]*:22: Error: immediate must be either 1, 2, 4 or 8 -- `vdwdup.u32 q0,r0,r1,#3'
+[^:]*:23: Error: immediate must be either 1, 2, 4 or 8 -- `vdwdup.u32 q0,r0,r1,#0'
+[^:]*:24: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:25: Error: r15 not allowed here -- `vdwdup.u32 q0,r0,pc,#1'
+[^:]*: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
+[^:]*:29: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:30: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:32: Error: syntax error -- `vddupeq.u32 q0,r0,#1'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vddupt.u32 q0,r0,#1'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vddup.u32 q0,r0,#1'
+[^:]*:37: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:38: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:40: Error: syntax error -- `vdwdupeq.u32 q0,r0,r1,#1'
+[^:]*:41: Error: vector predicated instruction should be in VPT/VPST block -- `vdwdupt.u32 q0,r0,r1,#1'
+[^:]*:43: Error: instruction missing MVE vector predication code -- `vdwdup.u32 q0,r0,r1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vddup-bad.s b/gas/testsuite/gas/arm/mve-vddup-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..9951e9d11843d3302823e7805bbbe20abc79d3eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vddup-bad.s
@@ -0,0 +1,43 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vddup.u32 q0, r2, #1
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vdwdup.u32 q0, r2, r1, #1
+.endr
+.endm
+.syntax unified
+.thumb
+vddup.s16 q0, r0, #1
+vddup.u64 q0, r0, #1
+vddup.u32 q0, r0, #3
+vddup.u32 q0, r0, #0
+vdwdup.s16 q0, r0, r1, #1
+vdwdup.u64 q0, r0, r1, #1
+vdwdup.u32 q0, r0, r1, #3
+vdwdup.u32 q0, r0, r1, #0
+vdwdup.u32 q0, r0, sp, #1
+vdwdup.u32 q0, r0, pc, #1
+cond1
+cond2
+it eq
+vddupeq.u32 q0, r0, #1
+vddupeq.u32 q0, r0, #1
+vpst
+vddupeq.u32 q0, r0, #1
+vddupt.u32 q0, r0, #1
+vpst
+vddup.u32 q0, r0, #1
+it eq
+vdwdupeq.u32 q0, r0, r1, #1
+vdwdupeq.u32 q0, r0, r1, #1
+vpst
+vdwdupeq.u32 q0, r0, r1, #1
+vdwdupt.u32 q0, r0, r1, #1
+vpst
+vdwdup.u32 q0, r0, r1, #1
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.d b/gas/testsuite/gas/arm/mve-vdup-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..2ad95976135bb46535720195d17b0024cf391abc
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vdup-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vdup-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.l b/gas/testsuite/gas/arm/mve-vdup-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..08808393569f7e7a839680b001e38e9f1ca66886
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vdup-bad.l
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:11: Error: bad type in SIMD instruction -- `vdup.64 q0,r1'
+[^:]*:12: Error: selected FPU does not support instruction -- `vdup.32 q0,d0\[1\]'
+[^:]*:13: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:14: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*: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 -- `vdupeq.32 q0,r2'
+[^:]*:18: Error: syntax error -- `vdupeq.32 q0,r2'
+[^:]*:20: Error: syntax error -- `vdupeq.32 q0,r2'
+[^:]*:21: Error: incorrect condition in VPT/VPST block -- `vdupt.32 q0,r2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vdup.32 q0,r2'
diff --git a/gas/testsuite/gas/arm/mve-vdup-bad.s b/gas/testsuite/gas/arm/mve-vdup-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..c6539d860575184fcf6745d165995edf80270f6e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vdup-bad.s
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vdup.32 q0, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vdup.f16 q0, r1
+vdup.64 q0, r1
+vdup.32 q0, d0[1]
+vdup.32 q0, sp
+vdup.32 q0, pc
+cond
+it eq
+vdupeq.32 q0, r2
+vdupeq.32 q0, r2
+vpste
+vdupeq.32 q0, r2
+vdupt.32 q0, r2
+vpst
+vdup.32 q0, r2
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.d b/gas/testsuite/gas/arm/mve-vidup-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6a9a0384048c05c0f962130078755c6dd983e962
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vidup-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VIDUP and VIWDUP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vidup-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.l b/gas/testsuite/gas/arm/mve-vidup-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5fb742559f5bd1573aa03ea767a56112a5acb9f0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vidup-bad.l
@@ -0,0 +1,34 @@
+[^:]*: Assembler messages:
+[^:]*:16: Error: bad type in SIMD instruction -- `vidup.s16 q0,r0,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vidup.u64 q0,r0,#1'
+[^:]*:18: Error: immediate must be either 1, 2, 4 or 8 -- `vidup.u32 q0,r0,#3'
+[^:]*:19: Error: immediate must be either 1, 2, 4 or 8 -- `vidup.u32 q0,r0,#0'
+[^:]*:20: Error: bad type in SIMD instruction -- `viwdup.s16 q0,r0,r1,#1'
+[^:]*:21: Error: bad type in SIMD instruction -- `viwdup.u64 q0,r0,r1,#1'
+[^:]*:22: Error: immediate must be either 1, 2, 4 or 8 -- `viwdup.u32 q0,r0,r1,#3'
+[^:]*:23: Error: immediate must be either 1, 2, 4 or 8 -- `viwdup.u32 q0,r0,r1,#0'
+[^:]*:24: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:25: Error: r15 not allowed here -- `viwdup.u32 q0,r0,pc,#1'
+[^:]*: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
+[^:]*:29: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:30: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:32: Error: syntax error -- `vidupeq.u32 q0,r0,#1'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vidupt.u32 q0,r0,#1'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vidup.u32 q0,r0,#1'
+[^:]*:37: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:38: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:40: Error: syntax error -- `viwdupeq.u32 q0,r0,r1,#1'
+[^:]*:41: Error: vector predicated instruction should be in VPT/VPST block -- `viwdupt.u32 q0,r0,r1,#1'
+[^:]*:43: Error: instruction missing MVE vector predication code -- `viwdup.u32 q0,r0,r1,#1'
+
diff --git a/gas/testsuite/gas/arm/mve-vidup-bad.s b/gas/testsuite/gas/arm/mve-vidup-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..3d3a4488d9c780123754a3243241720a513f4d3c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vidup-bad.s
@@ -0,0 +1,43 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vidup.u32 q0, r2, #1
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+viwdup.u32 q0, r2, r1, #1
+.endr
+.endm
+.syntax unified
+.thumb
+vidup.s16 q0, r0, #1
+vidup.u64 q0, r0, #1
+vidup.u32 q0, r0, #3
+vidup.u32 q0, r0, #0
+viwdup.s16 q0, r0, r1, #1
+viwdup.u64 q0, r0, r1, #1
+viwdup.u32 q0, r0, r1, #3
+viwdup.u32 q0, r0, r1, #0
+viwdup.u32 q0, r0, sp, #1
+viwdup.u32 q0, r0, pc, #1
+cond1
+cond2
+it eq
+vidupeq.u32 q0, r0, #1
+vidupeq.u32 q0, r0, #1
+vpst
+vidupeq.u32 q0, r0, #1
+vidupt.u32 q0, r0, #1
+vpst
+vidup.u32 q0, r0, #1
+it eq
+viwdupeq.u32 q0, r0, r1, #1
+viwdupeq.u32 q0, r0, r1, #1
+vpst
+viwdupeq.u32 q0, r0, r1, #1
+viwdupt.u32 q0, r0, r1, #1
+vpst
+viwdup.u32 q0, r0, r1, #1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 15/57][Arm][GAS] Add support for MVE instructions: vcls, vclz and vfmas
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (13 preceding siblings ...)
  2019-05-01 17:08 ` [PATCH 14/57][Arm][GAS] Add support for MVE instructions: vcadd, vcmla and vcmul Andre Vieira (lists)
@ 2019-05-01 17:09 ` Andre Vieira (lists)
  2019-05-01 17:09 ` [PATCH 16/57][Arm][GAS] Add support for MVE instructions: vdup, vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
                   ` (45 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:09 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 785 bytes --]

Hi,

This patch adds support for MVE instructions: VCLS, VCLZ, and VFMAS.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vfmas): New encoding function.
	(do_neon_cls): Change to support MVE variants.
	(do_neon_clz): Change to support MVE variants.
	(insns): Change to support MVE variants and add new.
	* testsuite/gas/arm/mve-vcls-bad.d: New test.
	* testsuite/gas/arm/mve-vcls-bad.l: New test.
	* testsuite/gas/arm/mve-vcls-bad.s: New test.
	* testsuite/gas/arm/mve-vclz-bad.d: New test.
	* testsuite/gas/arm/mve-vclz-bad.l: New test.
	* testsuite/gas/arm/mve-vclz-bad.s: New test.
	* testsuite/gas/arm/mve-vfmas-bad.d: New test.
	* testsuite/gas/arm/mve-vfmas-bad.l: New test.
	* testsuite/gas/arm/mve-vfmas-bad.s: New test.

[-- Attachment #2: 15.patch --]
[-- Type: text/x-patch, Size: 10428 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 8d61ab3f1c5017294c36524047137c410dae32a6..e739c5b94ab1924f65a262e15342a748e2a4dc40 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15582,6 +15582,32 @@ do_mve_vcmp (void)
   return;
 }
 
+static void
+do_mve_vfmas (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  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 |= (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) << 7;
+  inst.instruction |= inst.operands[2].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vcmul (void)
 {
@@ -19006,7 +19032,15 @@ do_neon_recip_est (void)
 static void
 do_neon_cls (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+    return;
+
+  enum neon_shape rs;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+   rs = neon_select_shape (NS_QQ, NS_NULL);
+  else
+   rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+
   struct neon_type_el et = neon_check_type (2, rs,
     N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
   neon_two_same (neon_quad (rs), 1, et.size);
@@ -19015,7 +19049,15 @@ do_neon_cls (void)
 static void
 do_neon_clz (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+    return;
+
+  enum neon_shape rs;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+   rs = neon_select_shape (NS_QQ, NS_NULL);
+  else
+   rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+
   struct neon_type_el et = neon_check_type (2, rs,
     N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
   neon_two_same (neon_quad (rs), 1, et.size);
@@ -23648,10 +23690,8 @@ static const struct asm_opcode insns[] =
  NUF(vrsqrte,   1b30480, 2, (RNDQ, RNDQ),     neon_recip_est),
  NUF(vrsqrteq,  1b30480, 2, (RNQ,  RNQ),      neon_recip_est),
   /* VCLS. Types S8 S16 S32.  */
- NUF(vcls,      1b00400, 2, (RNDQ, RNDQ),     neon_cls),
  NUF(vclsq,     1b00400, 2, (RNQ,  RNQ),      neon_cls),
   /* VCLZ. Types I8 I16 I32.  */
- NUF(vclz,      1b00480, 2, (RNDQ, RNDQ),     neon_clz),
  NUF(vclzq,     1b00480, 2, (RNQ,  RNQ),      neon_clz),
   /* VCNT. Size 8.  */
  NUF(vcnt,      1b00500, 2, (RNDQ, RNDQ),     neon_cnt),
@@ -24185,6 +24225,7 @@ static const struct asm_opcode insns[] =
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
+ mToC("vfmas", ee311e40,   3, (RMQ, RMQ, RR),			  mve_vfmas),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
@@ -24240,6 +24281,8 @@ static const struct asm_opcode insns[] =
  mnUF(vorr,      _vorr,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(vorn,      _vorn,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
  mnUF(veor,      _veor,		  3, (RNDQMQ, oRNDQMQ, RNDQMQ),      neon_logic),
+ MNUF(vcls,      1b00400,	  2, (RNDQMQ, RNDQMQ),		     neon_cls),
+ MNUF(vclz,      1b00480,	  2, (RNDQMQ, RNDQMQ),		     neon_clz),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.d b/gas/testsuite/gas/arm/mve-vcls-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..0cfdabd7a5f8c3152cd704eb1a68dfda40bed56c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcls-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCLS instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcls-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.l b/gas/testsuite/gas/arm/mve-vcls-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..c58d34f6cf1a95e6b4f37ff410b647ae095c17c8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcls-bad.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vcls.f32 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vcls.u32 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vcls.32 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vcls.i32 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vcls.s64 q0,q1'
+[^:]*: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 -- `vclseq.s16 q0,q1'
+[^:]*:18: Error: syntax error -- `vclseq.s16 q0,q1'
+[^:]*:20: Error: syntax error -- `vclseq.s16 q0,q1'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vclst.s16 q0,q1'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vcls.s16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vcls-bad.s b/gas/testsuite/gas/arm/mve-vcls-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..a3cb1be59d21c3cbd04a462496bd0c425aa97f77
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcls-bad.s
@@ -0,0 +1,24 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vcls.s32 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vcls.f32 q0, q1
+vcls.u32 q0, q1
+vcls.32 q0, q1
+vcls.i32 q0, q1
+vcls.s64 q0, q1
+cond
+it eq
+vclseq.s16 q0, q1
+vclseq.s16 q0, q1
+vpst
+vclseq.s16 q0, q1
+vclst.s16 q0, q1
+vpst
+vcls.s16 q0, q1
+
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.d b/gas/testsuite/gas/arm/mve-vclz-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..72f37da2c9ee0a3dd9c09cd0c45c8156ab98c1d8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vclz-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCLZ instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vclz-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.l b/gas/testsuite/gas/arm/mve-vclz-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..aa68b0f5f7d8c4f3a409f2c37f1a44fc2a018142
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vclz-bad.l
@@ -0,0 +1,14 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vclz.f32 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vclz.i64 q0,q1'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:15: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:17: Error: syntax error -- `vclzeq.i16 q0,q1'
+[^:]*:18: Error: vector predicated instruction should be in VPT/VPST block -- `vclzt.i16 q0,q1'
+[^:]*:20: Error: instruction missing MVE vector predication code -- `vclz.i16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vclz-bad.s b/gas/testsuite/gas/arm/mve-vclz-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..088e831afa2ca6c3227e871c7c61f849704fe9cf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vclz-bad.s
@@ -0,0 +1,20 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vclz.i32 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vclz.f32 q0, q1
+vclz.i64 q0, q1
+cond
+it eq
+vclzeq.i16 q0, q1
+vclzeq.i16 q0, q1
+vpst
+vclzeq.i16 q0, q1
+vclzt.i16 q0, q1
+vpst
+vclz.i16 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.d b/gas/testsuite/gas/arm/mve-vfmas-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..dd3510f87ec10d0db605a4b8f9b93943c4031146
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vfmas-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VFMAS instructions 
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vfmas-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.l b/gas/testsuite/gas/arm/mve-vfmas-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..6a9b1f4313e611d3f213023bb9d0745492e8ccc9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vfmas-bad.l
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:11: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:12: Error: bad type in SIMD instruction -- `vfmas.i32 q0,q1,r2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vfmas.f64 q0,q1,r2'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:17: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:19: Error: syntax error -- `vfmaseq.f32 q0,q1,r2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vfmast.f32 q0,q1,r2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vfmas.f32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vfmas-bad.s b/gas/testsuite/gas/arm/mve-vfmas-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..15f894a6f65f9473ed5e04efabf6908e6342cb68
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vfmas-bad.s
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vfmas.f32 q0, q1, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vfmas.f32 q0, q1, sp
+vfmas.f32 q0, q1, pc
+vfmas.i32 q0, q1, r2
+vfmas.f64 q0, q1, r2
+cond
+it eq
+vfmaseq.f32 q0, q1, r2
+vfmaseq.f32 q0, q1, r2
+vpst
+vfmaseq.f32 q0, q1, r2
+vfmast.f32 q0, q1, r2
+vpst
+vfmas.f32 q0, q1, r2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 17/57][Arm][GAS] Add support for MVE instructions: vfma and vfms
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (15 preceding siblings ...)
  2019-05-01 17:09 ` [PATCH 16/57][Arm][GAS] Add support for MVE instructions: vdup, vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
@ 2019-05-01 17:11 ` Andre Vieira (lists)
  2019-05-01 17:12 ` [PATCH 19/57][Arm][GAS] Add support for MVE instructions: vmax[nm][a] and vmin[nm][a] Andre Vieira (lists)
                   ` (43 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:11 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Hi,

This patch adds support for MVE instructions VFMA and VFMS.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* 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.

[-- Attachment #2: 17.patch --]
[-- Type: text/x-patch, Size: 6493 bytes --]

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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 19/57][Arm][GAS] Add support for MVE instructions: vmax[nm][a] and vmin[nm][a]
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (16 preceding siblings ...)
  2019-05-01 17:11 ` [PATCH 17/57][Arm][GAS] Add support for MVE instructions: vfma and vfms Andre Vieira (lists)
@ 2019-05-01 17:12 ` Andre Vieira (lists)
  2019-05-01 17:12 ` [PATCH 18/57][Arm][GAS] Add support for MVE instructions: vhcadd, vhadd, vhsub and vrhadd Andre Vieira (lists)
                   ` (42 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:12 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1087 bytes --]

Hi,

This patch adds support for MVE instructions VMAX, VMAXA, VMAXNM, 
VMAXNMA, VMIN, VMINA, VMINNM, and VMINNMA.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vmaxa_vmina): New encoding function.
	(do_mve_vmaxnma_vminnma): Likewise.
	(do_neon_dyadic_if_su): Change to support MVE variants.
	(do_vmaxnm): Likewise.
	(insns): Change to accept MVE variants and add new.
	* testsuite/gas/arm/mve-vmax-vmin-bad.d: New test.
	* testsuite/gas/arm/mve-vmax-vmin-bad.l: New test.
	* testsuite/gas/arm/mve-vmax-vmin-bad.s: New test.
	* testsuite/gas/arm/mve-vmaxa-vmina-bad.d: New test.
	* testsuite/gas/arm/mve-vmaxa-vmina-bad.l: New test.
	* testsuite/gas/arm/mve-vmaxa-vmina-bad.s: New test.
	* testsuite/gas/arm/mve-vmaxnm-vminnm-bad.d: New test.
	* testsuite/gas/arm/mve-vmaxnm-vminnm-bad.l: New test.
	* testsuite/gas/arm/mve-vmaxnm-vminnm-bad.s: New test.
	* testsuite/gas/arm/mve-vmaxnma-vminnma-bad.d: New test.
	* testsuite/gas/arm/mve-vmaxnma-vminnma-bad.l: New test.
	* testsuite/gas/arm/mve-vmaxnma-vminnma-bad.s: New test.

[-- Attachment #2: 19.patch --]
[-- Type: text/x-patch, Size: 19032 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index de3c8b69b767a9232488129985ebb540b08c2192..f490b91b685d4c0089bd8c4ad055b534d389aa8b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15593,6 +15593,26 @@ do_mve_vcmp (void)
   return;
 }
 
+static void
+do_mve_vmaxa_vmina (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
+
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= neon_logbits (et.size) << 18;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vfmas (void)
 {
@@ -15662,6 +15682,26 @@ do_mve_viddup (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vmaxnma_vminnma (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  inst.instruction |= (et.size == 16) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vcmul (void)
 {
@@ -16704,6 +16744,11 @@ do_neon_dyadic_if_su (void)
   struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
 					    N_SUF_32 | N_KEY);
 
+  constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
+	       || inst.instruction == ((unsigned) N_MNEM_vmin))
+	      && et.type == NT_float
+	      && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
+
   if (check_simd_pred_availability (et.type == NT_float,
 				    NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
@@ -19746,12 +19791,13 @@ do_vsel (void)
 static void
 do_vmaxnm (void)
 {
-  set_pred_insn_type (OUTSIDE_PRED_INSN);
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    set_pred_insn_type (OUTSIDE_PRED_INSN);
 
   if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
     return;
 
-  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
+  if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
     return;
 
   neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
@@ -22954,8 +23000,6 @@ static const struct asm_opcode insns[] =
   nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD),		vsel),
   nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD),		vsel),
   nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD),		vsel),
-  nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ),	vmaxnm),
-  nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ),	vmaxnm),
   nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintr),
   nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintz),
   nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintx),
@@ -23674,9 +23718,7 @@ static const struct asm_opcode insns[] =
  NUF(vbifq,     1300110, 3, (RNQ,  RNQ,  RNQ),  neon_bitfield),
   /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32.  */
  nUF(vabdq,     _vabd,    3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_if_su),
- nUF(vmax,      _vmax,    3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
  nUF(vmaxq,     _vmax,    3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_if_su),
- nUF(vmin,      _vmin,    3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
  nUF(vminq,     _vmin,    3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_if_su),
   /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
      back to neon_dyadic_if_su.  */
@@ -24373,11 +24415,15 @@ static const struct asm_opcode insns[] =
  mCEF(vdwdup,	_vdwdup,    4, (RMQ, RRe, RR, EXPi),		  mve_viddup),
  mCEF(vidup,	_vidup,	    3, (RMQ, RRe, EXPi),		  mve_viddup),
  mCEF(viwdup,	_viwdup,    4, (RMQ, RRe, RR, EXPi),		  mve_viddup),
+ mToC("vmaxa",	ee330e81,   2, (RMQ, RMQ),			  mve_vmaxa_vmina),
+ mToC("vmina",	ee331e81,   2, (RMQ, RMQ),			  mve_vmaxa_vmina),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
  mToC("vfmas", ee311e40,   3, (RMQ, RMQ, RR),			  mve_vfmas),
+ mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ),			  mve_vmaxnma_vminnma),
+ mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ),			  mve_vmaxnma_vminnma),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
@@ -24421,6 +24467,8 @@ static const struct asm_opcode insns[] =
  mnUF(vcvtp,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvtp),
  mnUF(vcvtn,  _vcvta,  3, (RNSDQMQ, oRNSDQMQ, oI32z),	neon_cvtn),
  mnUF(vcvtm,  _vcvta,  2, (RNSDQMQ, oRNSDQMQ),		neon_cvtm),
+ mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ),	vmaxnm),
+ mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ),	vmaxnm),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & fpu_neon_ext_v1
@@ -24439,6 +24487,8 @@ static const struct asm_opcode insns[] =
  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),
+ mnUF(vmin,      _vmin,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
+ mnUF(vmax,      _vmax,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vmax-vmin-bad.d b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..9ffbca4becedc3882251c5c4341d0cafb81f8ff3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAX and VMIN instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmax-vmin-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmax-vmin-bad.l b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..17d5c74602151bc387d082a95cc050d5ab3e565f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmax.s64 q0,q1,q2'
+[^:]*:11: Error: selected FPU does not support instruction -- `vmax.f16 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vmax.u64 q0,q1,q2'
+[^:]*:13: Error: selected FPU does not support instruction -- `vmax.f32 q0,q1,q2'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vmaxeq.s16 q0,q1,q2'
+[^:]*:18: Error: syntax error -- `vmaxeq.s16 q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vmaxeq.s16 q0,q1,q2'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxt.s16 q0,q1,q2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vmax.s16 q0,q1,q2'
+[^:]*:25: Error: syntax error -- `vmineq.u32 q0,q1,q2'
+[^:]*:26: Error: syntax error -- `vmineq.u32 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vmineq.u32 q0,q1,q2'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vmint.u32 q0,q1,q2'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vmin.u32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmax-vmin-bad.s b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..b7b92427c2235574efba55eb2539d39b2ded1c65
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmax-vmin-bad.s
@@ -0,0 +1,31 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s8 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmax.s64 q0, q1, q2
+vmax.f16 q0, q1, q2
+vmax.u64 q0, q1, q2
+vmax.f32 q0, q1, q2
+cond vmax
+cond vmin
+it eq
+vmaxeq.s16 q0, q1, q2
+vmaxeq.s16 q0, q1, q2
+vpst
+vmaxeq.s16 q0, q1, q2
+vmaxt.s16 q0, q1, q2
+vpst
+vmax.s16 q0, q1, q2
+it eq
+vmineq.u32 q0, q1, q2
+vmineq.u32 q0, q1, q2
+vpst
+vmineq.u32 q0, q1, q2
+vmint.u32 q0, q1, q2
+vpst
+vmin.u32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.d b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..11105db987b6239c556005557d1d9a074059a785
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAXA and VMINA instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmaxa-vmina-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.l b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..0e2ffed6d54de7a829c33b291aa42069734827c4
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.l
@@ -0,0 +1,29 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmaxa.u8 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmaxa.s64 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vmaxa.f16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vmina.u8 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmina.s64 q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmina.f16 q0,q1'
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vmaxaeq.s8 q0,q1'
+[^:]*:20: Error: syntax error -- `vmaxaeq.s8 q0,q1'
+[^:]*:22: Error: syntax error -- `vmaxaeq.s8 q0,q1'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxat.s8 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vmaxa.s8 q0,q1'
+[^:]*:27: Error: syntax error -- `vminaeq.s8 q0,q1'
+[^:]*:28: Error: syntax error -- `vminaeq.s8 q0,q1'
+[^:]*:30: Error: syntax error -- `vminaeq.s8 q0,q1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vminat.s8 q0,q1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vmina.s8 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.s b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..08cc60a2baca34108d4003fb658dc25afc36081b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxa-vmina-bad.s
@@ -0,0 +1,33 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s8 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmaxa.u8 q0, q1
+vmaxa.s64 q0, q1
+vmaxa.f16 q0, q1
+vmina.u8 q0, q1
+vmina.s64 q0, q1
+vmina.f16 q0, q1
+cond vmaxa
+cond vmina
+it eq
+vmaxaeq.s8 q0, q1
+vmaxaeq.s8 q0, q1
+vpst
+vmaxaeq.s8 q0, q1
+vmaxat.s8 q0, q1
+vpst
+vmaxa.s8 q0, q1
+it eq
+vminaeq.s8 q0, q1
+vminaeq.s8 q0, q1
+vpst
+vminaeq.s8 q0, q1
+vminat.s8 q0, q1
+vpst
+vmina.s8 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.d b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..4617cd4c3dc2e0bb9420d60e160ff2026ce59442
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAXNM and VMINNM instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmaxnm-vminnm-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.l b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..012ab35bf18d2908f61dfdbc8c3028bd113d06ce
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmaxnm.f64 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmaxnm.i16 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vminnm.f64 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vminnm.i16 q0,q1,q2'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vmaxnmeq.f32 q0,q1,q2'
+[^:]*:18: Error: syntax error -- `vmaxnmeq.f32 q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vmaxnmeq.f32 q0,q1,q2'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxnmt.f32 q0,q1,q2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vmaxnm.f32 q0,q1,q2'
+[^:]*:25: Error: syntax error -- `vminnmeq.f32 q0,q1,q2'
+[^:]*:26: Error: syntax error -- `vminnmeq.f32 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vminnmeq.f32 q0,q1,q2'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vminnmt.f32 q0,q1,q2'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vminnm.f32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.s b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..2b6436cc6a27d51d3a01eafbb2de10afe76f3eb6
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnm-vminnm-bad.s
@@ -0,0 +1,31 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().f16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmaxnm.f64 q0, q1, q2
+vmaxnm.i16 q0, q1, q2
+vminnm.f64 q0, q1, q2
+vminnm.i16 q0, q1, q2
+cond vmaxnm
+cond vminnm
+it eq
+vmaxnmeq.f32 q0, q1, q2
+vmaxnmeq.f32 q0, q1, q2
+vpst
+vmaxnmeq.f32 q0, q1, q2
+vmaxnmt.f32 q0, q1, q2
+vpst
+vmaxnm.f32 q0, q1, q2
+it eq
+vminnmeq.f32 q0, q1, q2
+vminnmeq.f32 q0, q1, q2
+vpst
+vminnmeq.f32 q0, q1, q2
+vminnmt.f32 q0, q1, q2
+vpst
+vminnm.f32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.d b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..5d11eee34c4040fbef21c0c3799e3c98d75ca123
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAXNMA and VMINNMA instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmaxnma-vminnma-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.l b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..fdc8aac7a80bc41229f9965e5fa65b68bbb19799
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmaxnma.f64 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmaxnma.i16 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vminnma.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vminnma.i16 q0,q1'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vmaxnmaeq.f32 q0,q1'
+[^:]*:18: Error: syntax error -- `vmaxnmaeq.f32 q0,q1'
+[^:]*:20: Error: syntax error -- `vmaxnmaeq.f32 q0,q1'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxnmat.f32 q0,q1'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vmaxnma.f32 q0,q1'
+[^:]*:25: Error: syntax error -- `vminnmaeq.f32 q0,q1'
+[^:]*:26: Error: syntax error -- `vminnmaeq.f32 q0,q1'
+[^:]*:28: Error: syntax error -- `vminnmaeq.f32 q0,q1'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vminnmat.f32 q0,q1'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vminnma.f32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.s b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..43f6dce36a45a7c8f572e4eb1c3c5503db8649d8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnma-vminnma-bad.s
@@ -0,0 +1,31 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().f16 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmaxnma.f64 q0, q1
+vmaxnma.i16 q0, q1
+vminnma.f64 q0, q1
+vminnma.i16 q0, q1
+cond vmaxnma
+cond vminnma
+it eq
+vmaxnmaeq.f32 q0, q1
+vmaxnmaeq.f32 q0, q1
+vpst
+vmaxnmaeq.f32 q0, q1
+vmaxnmat.f32 q0, q1
+vpst
+vmaxnma.f32 q0, q1
+it eq
+vminnmaeq.f32 q0, q1
+vminnmaeq.f32 q0, q1
+vpst
+vminnmaeq.f32 q0, q1
+vminnmat.f32 q0, q1
+vpst
+vminnma.f32 q0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 18/57][Arm][GAS] Add support for MVE instructions: vhcadd, vhadd, vhsub and vrhadd
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (17 preceding siblings ...)
  2019-05-01 17:12 ` [PATCH 19/57][Arm][GAS] Add support for MVE instructions: vmax[nm][a] and vmin[nm][a] Andre Vieira (lists)
@ 2019-05-01 17:12 ` Andre Vieira (lists)
  2019-05-01 17:13 ` [PATCH 21/57][Arm][GAS] Add support for MVE instructions: vmaxv, vmaxav, vminv and vminav Andre Vieira (lists)
                   ` (41 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:12 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]

Hi,

This patch adds support for the MVE instructions VHCADD, VHADD, VHSUB 
and VRHADD.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* 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.

[-- Attachment #2: 18.patch --]
[-- Type: text/x-patch, Size: 20923 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7e0df057c6ab3223ed7665f616f119507aec3dec..de3c8b69b767a9232488129985ebb540b08c2192 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6905,6 +6905,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 */
@@ -7245,6 +7246,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);
@@ -15823,7 +15828,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);
@@ -15850,6 +15855,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;
     }
@@ -15948,15 +15963,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
@@ -16123,90 +16235,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)
 {
@@ -16335,7 +16363,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);
     }
@@ -16343,7 +16371,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);
     }
@@ -16994,6 +17022,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)
 {
@@ -17024,7 +17076,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
@@ -23588,11 +23640,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),
@@ -24274,6 +24323,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),
@@ -24386,6 +24436,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 0000000000000000000000000000000000000000..acb12a42c6707c266fec2a327127d61e6a29021c
--- /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 0000000000000000000000000000000000000000..e49015c663950a4b8790e9551f8a07fdc2c8db53
--- /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 0000000000000000000000000000000000000000..bebefc933b40b7e3c956886c614471be7283f7ee
--- /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 0000000000000000000000000000000000000000..51b37a4bf1fe60e794a8b5613789b82b64f46b7b
--- /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 0000000000000000000000000000000000000000..61200723dfa668f1268b45a04e2bf7a65f6a19ef
--- /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 0000000000000000000000000000000000000000..ede5b7e45e04968340dc814bc39cfb5cda1c3acd
--- /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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 21/57][Arm][GAS] Add support for MVE instructions: vmaxv, vmaxav, vminv and vminav
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (18 preceding siblings ...)
  2019-05-01 17:12 ` [PATCH 18/57][Arm][GAS] Add support for MVE instructions: vhcadd, vhadd, vhsub and vrhadd Andre Vieira (lists)
@ 2019-05-01 17:13 ` Andre Vieira (lists)
  2019-05-01 17:13 ` [PATCH 20/57][Arm][GAS] Add support for MVE instructions: vmaxnmv, vmaxnmav, vminnmv and vminnmav Andre Vieira (lists)
                   ` (40 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:13 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

Hi,

This patch adds support for MVE instructions VMAXV, VMAXAV, VMINV and 
VMINAV.

gas/ChangeLog:

2019-01-02  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vmaxv, M_MNEM_vmaxav, M_MNEM_vminv,
         M_MNEM_vminav): New instruction encodings.
	(do_mve_vmaxv): New encoding function.
         (insns): Add entries for new MVE mnemonics.
	* testsuite/gas/arm/mve-vmaxv-vminv-bad.d: New test.
	* testsuite/gas/arm/mve-vmaxv-vminv-bad.l: New test.
	* testsuite/gas/arm/mve-vmaxv-vminv-bad.s: New test.

[-- Attachment #2: 21.patch --]
[-- Type: text/x-patch, Size: 7565 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 051ab6837b6b5cf4d8482ef267d5cd4a4a67243c..1f6569495a6f5ec1c89a4cf56544f6ad73058bdf 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14166,6 +14166,10 @@ do_t_loloop (void)
 #define M_MNEM_vdwdup	0xee011f60
 #define M_MNEM_vidup	0xee010f6e
 #define M_MNEM_viwdup	0xee010f60
+#define M_MNEM_vmaxv	0xeee20f00
+#define M_MNEM_vmaxav	0xeee00f00
+#define M_MNEM_vminv	0xeee20f80
+#define M_MNEM_vminav	0xeee00f80
 
 /* Neon instruction encoder helpers.  */
 
@@ -17271,6 +17275,31 @@ do_mve_vmaxnmv (void)
   mve_encode_rq (et.size == 16, 64);
 }
 
+static void
+do_mve_vmaxv (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
+  struct neon_type_el et;
+
+  if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
+    et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
+  else
+    et = neon_check_type (2, rs, 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;
+
+  if (inst.operands[0].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+  else if (inst.operands[0].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+
+  mve_encode_rq (et.type == NT_unsigned, et.size);
+}
+
+
 static void
 do_neon_qrdmlah (void)
 {
@@ -24437,6 +24466,10 @@ static const struct asm_opcode insns[] =
  mCEF(viwdup,	_viwdup,    4, (RMQ, RRe, RR, EXPi),		  mve_viddup),
  mToC("vmaxa",	ee330e81,   2, (RMQ, RMQ),			  mve_vmaxa_vmina),
  mToC("vmina",	ee331e81,   2, (RMQ, RMQ),			  mve_vmaxa_vmina),
+ mCEF(vmaxv,	_vmaxv,	  2, (RR, RMQ),				  mve_vmaxv),
+ mCEF(vmaxav,	_vmaxav,  2, (RR, RMQ),				  mve_vmaxv),
+ mCEF(vminv,	_vminv,	  2, (RR, RMQ),				  mve_vmaxv),
+ mCEF(vminav,	_vminav,  2, (RR, RMQ),				  mve_vmaxv),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
diff --git a/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.d b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..9dd5c3ee581b80cd660636ab487ffc0a75f6c603
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAXV, VMAXAV, VMIMV and VMINAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmaxv-vminv-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.l b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..16d109d2d34856b79b17de7bc4ba9f26ae912f1c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.l
@@ -0,0 +1,57 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmaxv.u64 r0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmaxv.f16 r0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vminv.s64 r0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vminv.f32 r0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmaxav.u16 r0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmaxav.f32 r0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vminav.u32 r0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vminav.f16 r0,q1'
+[^:]*:18: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:20: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:21: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vmaxveq.s32 r0,q1'
+[^:]*:28: Error: syntax error -- `vmaxveq.s32 r0,q1'
+[^:]*:30: Error: syntax error -- `vmaxveq.s32 r0,q1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxvt.s32 r0,q1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vmaxv.s32 r0,q1'
+[^:]*:35: Error: syntax error -- `vmaxaveq.s32 r0,q1'
+[^:]*:36: Error: syntax error -- `vmaxaveq.s32 r0,q1'
+[^:]*:38: Error: syntax error -- `vmaxaveq.s32 r0,q1'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxavt.s32 r0,q1'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vmaxav.s32 r0,q1'
+[^:]*:43: Error: syntax error -- `vminveq.s32 r0,q1'
+[^:]*:44: Error: syntax error -- `vminveq.s32 r0,q1'
+[^:]*:46: Error: syntax error -- `vminveq.s32 r0,q1'
+[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vminvt.s32 r0,q1'
+[^:]*:49: Error: instruction missing MVE vector predication code -- `vminv.s32 r0,q1'
+[^:]*:51: Error: syntax error -- `vminaveq.s32 r0,q1'
+[^:]*:52: Error: syntax error -- `vminaveq.s32 r0,q1'
+[^:]*:54: Error: syntax error -- `vminaveq.s32 r0,q1'
+[^:]*:55: Error: vector predicated instruction should be in VPT/VPST block -- `vminavt.s32 r0,q1'
+[^:]*:57: Error: instruction missing MVE vector predication code -- `vminav.s32 r0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.s b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..e274a7a51c3869f26b04e20caf96486164ac73d8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxv-vminv-bad.s
@@ -0,0 +1,57 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmaxv.u64 r0, q1
+vmaxv.f16 r0, q1
+vminv.s64 r0, q1
+vminv.f32 r0, q1
+vmaxav.u16 r0, q1
+vmaxav.f32 r0, q1
+vminav.u32 r0, q1
+vminav.f16 r0, q1
+vmaxv.s32 sp, q1
+vmaxav.s32 pc, q1
+vminv.s32 pc, q1
+vminav.s32 sp, q1
+cond vmaxv
+cond vmaxav
+cond vminv
+cond vminav
+it eq
+vmaxveq.s32 r0, q1
+vmaxveq.s32 r0, q1
+vpst
+vmaxveq.s32 r0, q1
+vmaxvt.s32 r0, q1
+vpst
+vmaxv.s32 r0, q1
+it eq
+vmaxaveq.s32 r0, q1
+vmaxaveq.s32 r0, q1
+vpst
+vmaxaveq.s32 r0, q1
+vmaxavt.s32 r0, q1
+vpst
+vmaxav.s32 r0, q1
+it eq
+vminveq.s32 r0, q1
+vminveq.s32 r0, q1
+vpst
+vminveq.s32 r0, q1
+vminvt.s32 r0, q1
+vpst
+vminv.s32 r0, q1
+it eq
+vminaveq.s32 r0, q1
+vminaveq.s32 r0, q1
+vpst
+vminaveq.s32 r0, q1
+vminavt.s32 r0, q1
+vpst
+vminav.s32 r0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 20/57][Arm][GAS] Add support for MVE instructions: vmaxnmv, vmaxnmav, vminnmv and vminnmav
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (19 preceding siblings ...)
  2019-05-01 17:13 ` [PATCH 21/57][Arm][GAS] Add support for MVE instructions: vmaxv, vmaxav, vminv and vminav Andre Vieira (lists)
@ 2019-05-01 17:13 ` Andre Vieira (lists)
  2019-05-01 17:15 ` [PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav, vrmlaldavh, vrmlalvh and vrmlsldavh Andre Vieira (lists)
                   ` (39 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:13 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 454 bytes --]

Hi,

This patch adds support for MVE instructions VMAXNMV, VMAXNMAV, VMINNMV, 
and VMINNMAV.


gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vmaxnmv): New encoding function.
         (insns): Add entries for new mnemonics.
	* testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.d: New test.
	* testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.l: New test.
	* testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.s: New test.

[-- Attachment #2: 20.patch --]
[-- Type: text/x-patch, Size: 7272 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index f490b91b685d4c0089bd8c4ad055b534d389aa8b..051ab6837b6b5cf4d8482ef267d5cd4a4a67243c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -17251,6 +17251,26 @@ do_mve_vmladav (void)
   inst.instruction |= (et.size == 32) << 16;
 }
 
+static void
+do_mve_vmaxnmv (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (inst.operands[0].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+  else if (inst.operands[0].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+
+  mve_encode_rq (et.size == 16, 64);
+}
+
 static void
 do_neon_qrdmlah (void)
 {
@@ -24424,6 +24444,10 @@ static const struct asm_opcode insns[] =
  mToC("vfmas", ee311e40,   3, (RMQ, RMQ, RR),			  mve_vfmas),
  mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ),			  mve_vmaxnma_vminnma),
  mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ),			  mve_vmaxnma_vminnma),
+ mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ),			  mve_vmaxnmv),
+ mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ),			  mve_vmaxnmv),
+ mToC("vminnmv", eeee0f80, 2, (RR, RMQ),			  mve_vmaxnmv),
+ mToC("vminnmav",eeec0f80, 2, (RR, RMQ),			  mve_vmaxnmv),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v1
diff --git a/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.d b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..aca103c92aec94fdb3629f2416f1318f6cd5b1e2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMAXNMV, VMAXNMAV, VMINNMV and VMINNMAV instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmaxnmv-vminnmv-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.l b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5b30434027c203db386f252e99b26851e2dd8fec
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.l
@@ -0,0 +1,57 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmaxnmv.f64 r0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmaxnmv.i16 r0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vminnmv.f64 r0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vminnmv.i16 r0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmaxnmav.f64 r0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmaxnmav.i16 r0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vminnmav.f64 r0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vminnmav.i16 r0,q1'
+[^:]*:18: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:20: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:21: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vmaxnmveq.f32 r0,q1'
+[^:]*:28: Error: syntax error -- `vmaxnmveq.f32 r0,q1'
+[^:]*:30: Error: syntax error -- `vmaxnmveq.f32 r0,q1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxnmvt.f32 r0,q1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vmaxnmv.f32 r0,q1'
+[^:]*:35: Error: syntax error -- `vmaxnmaveq.f32 r0,q1'
+[^:]*:36: Error: syntax error -- `vmaxnmaveq.f32 r0,q1'
+[^:]*:38: Error: syntax error -- `vmaxnmaveq.f32 r0,q1'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vmaxnmavt.f32 r0,q1'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vmaxnmav.f32 r0,q1'
+[^:]*:43: Error: syntax error -- `vminnmveq.f32 r0,q1'
+[^:]*:44: Error: syntax error -- `vminnmveq.f32 r0,q1'
+[^:]*:46: Error: syntax error -- `vminnmveq.f32 r0,q1'
+[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vminnmvt.f32 r0,q1'
+[^:]*:49: Error: instruction missing MVE vector predication code -- `vminnmv.f32 r0,q1'
+[^:]*:51: Error: syntax error -- `vminnmaveq.f32 r0,q1'
+[^:]*:52: Error: syntax error -- `vminnmaveq.f32 r0,q1'
+[^:]*:54: Error: syntax error -- `vminnmaveq.f32 r0,q1'
+[^:]*:55: Error: vector predicated instruction should be in VPT/VPST block -- `vminnmavt.f32 r0,q1'
+[^:]*:57: Error: instruction missing MVE vector predication code -- `vminnmav.f32 r0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.s b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..58c4de1e5bcb1e5bf7c525c5ec797056bb2c5bab
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmaxnmv-vminnmv-bad.s
@@ -0,0 +1,57 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().f16 r0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmaxnmv.f64 r0, q1
+vmaxnmv.i16 r0, q1
+vminnmv.f64 r0, q1
+vminnmv.i16 r0, q1
+vmaxnmav.f64 r0, q1
+vmaxnmav.i16 r0, q1
+vminnmav.f64 r0, q1
+vminnmav.i16 r0, q1
+vmaxnmv.f16 sp, q1
+vmaxnmav.f32 pc, q1
+vminnmav.f16 sp, q1
+vminnmv.f32 pc, q1
+cond vmaxnmv
+cond vminnmv
+cond vmaxnmav
+cond vminnmav
+it eq
+vmaxnmveq.f32 r0, q1
+vmaxnmveq.f32 r0, q1
+vpst
+vmaxnmveq.f32 r0, q1
+vmaxnmvt.f32 r0, q1
+vpst
+vmaxnmv.f32 r0, q1
+it eq
+vmaxnmaveq.f32 r0, q1
+vmaxnmaveq.f32 r0, q1
+vpst
+vmaxnmaveq.f32 r0, q1
+vmaxnmavt.f32 r0, q1
+vpst
+vmaxnmav.f32 r0, q1
+it eq
+vminnmveq.f32 r0, q1
+vminnmveq.f32 r0, q1
+vpst
+vminnmveq.f32 r0, q1
+vminnmvt.f32 r0, q1
+vpst
+vminnmv.f32 r0, q1
+it eq
+vminnmaveq.f32 r0, q1
+vminnmaveq.f32 r0, q1
+vpst
+vminnmaveq.f32 r0, q1
+vminnmavt.f32 r0, q1
+vpst
+vminnmav.f32 r0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav, vrmlaldavh, vrmlalvh and vrmlsldavh
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (20 preceding siblings ...)
  2019-05-01 17:13 ` [PATCH 20/57][Arm][GAS] Add support for MVE instructions: vmaxnmv, vmaxnmav, vminnmv and vminnmav Andre Vieira (lists)
@ 2019-05-01 17:15 ` Andre Vieira (lists)
  2019-05-01 17:15 ` [PATCH 23/57][Arm][GAS] Add support for MVE instructions: vmla, vmul, vqadd and vqsub Andre Vieira (lists)
                   ` (38 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:15 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1380 bytes --]

Hi,

This patch adds support for MVE instructions VMLALDAV, VMLALV, VMLSLDAV, 
VRMLALDAVH, VRMLALVH, and VRMLSLDAVH.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vmlaldav, M_MNEM_vmlaldava,
         M_MNEM_vmlaldavx, M_MNEM_vmlaldavax, M_MNEM_vmlsldav,
         M_MNEM_vmlsldava, M_MNEM_vmlsldavx, M_MNEM_vmlsldavax,
         M_MNEM_vrmlaldavhx, M_MNEM_vrmlaldavhax, M_MNEM_vrmlsldavh,
         M_MNEM_vrmlsldavha, M_MNEM_vrmlsldavhx, M_MNEM_vrmlsldavhax):
         New instruction encodings.
	(NEON_SHAPE_DEF): New shape
	(mve_encode_rrqq): New encoding helper function.
	(do_mve_vmlaldav): New encoding function.
	(do_mve_vrmlaldavh): New encoding function.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vmlaldav-bad.d: New test.
	* testsuite/gas/arm/mve-vmlaldav-bad.l: New test.
	* testsuite/gas/arm/mve-vmlaldav-bad.s: New test.
	* testsuite/gas/arm/mve-vmlalv-bad.d: New test.
	* testsuite/gas/arm/mve-vmlalv-bad.l: New test.
	* testsuite/gas/arm/mve-vmlalv-bad.s: New test.
	* testsuite/gas/arm/mve-vmlsldav-bad.d: New test.
	* testsuite/gas/arm/mve-vmlsldav-bad.l: New test.
	* testsuite/gas/arm/mve-vmlsldav-bad.s: New test.
	* testsuite/gas/arm/mve-vrmlaldavh-bad.d: New test.
	* testsuite/gas/arm/mve-vrmlaldavh-bad.l: New test.
	* testsuite/gas/arm/mve-vrmlaldavh-bad.s: New test.

[-- Attachment #2: 22.patch --]
[-- Type: text/x-patch, Size: 41335 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1f6569495a6f5ec1c89a4cf56544f6ad73058bdf..77a68067f95ddcbd4b31b5309ea833dd875d063c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14170,6 +14170,20 @@ do_t_loloop (void)
 #define M_MNEM_vmaxav	0xeee00f00
 #define M_MNEM_vminv	0xeee20f80
 #define M_MNEM_vminav	0xeee00f80
+#define M_MNEM_vmlaldav	  0xee800e00
+#define M_MNEM_vmlaldava  0xee800e20
+#define M_MNEM_vmlaldavx  0xee801e00
+#define M_MNEM_vmlaldavax 0xee801e20
+#define M_MNEM_vmlsldav	  0xee800e01
+#define M_MNEM_vmlsldava  0xee800e21
+#define M_MNEM_vmlsldavx  0xee801e01
+#define M_MNEM_vmlsldavax 0xee801e21
+#define M_MNEM_vrmlaldavhx  0xee801f00
+#define M_MNEM_vrmlaldavhax 0xee801f20
+#define M_MNEM_vrmlsldavh   0xfe800e01
+#define M_MNEM_vrmlsldavha  0xfe800e21
+#define M_MNEM_vrmlsldavhx  0xfe801e01
+#define M_MNEM_vrmlsldavhax 0xfe801e21
 
 /* Neon instruction encoder helpers.  */
 
@@ -14334,6 +14348,7 @@ NEON_ENC_TAB
      - a table used to drive neon_select_shape.  */
 
 #define NEON_SHAPE_DEF			\
+  X(4, (R, R, Q, Q), QUAD),		\
   X(4, (Q, R, R, I), QUAD),		\
   X(4, (R, R, S, S), QUAD),		\
   X(4, (S, S, R, R), QUAD),		\
@@ -15959,6 +15974,21 @@ mve_encode_rq (unsigned bit28, unsigned size)
   inst.is_neon = 1;
 }
 
+static void
+mve_encode_rrqq (unsigned U, unsigned size)
+{
+  constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
+
+  inst.instruction |= U << 28;
+  inst.instruction |= (inst.operands[1].reg >> 1) << 20;
+  inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
+  inst.instruction |= (size == 32) << 16;
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= HI1 (inst.operands[2].reg) << 7;
+  inst.instruction |= inst.operands[3].reg;
+  inst.is_neon = 1;
+}
+
 /* Encode insns with bit pattern:
 
   |28/24|23|22 |21 20|19 16|15 12|11    8|7|6|5|4|3  0|
@@ -17255,6 +17285,73 @@ do_mve_vmladav (void)
   inst.instruction |= (et.size == 32) << 16;
 }
 
+static void
+do_mve_vmlaldav (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
+		       N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
+
+  if (et.type == NT_unsigned
+      && (inst.instruction == M_MNEM_vmlsldav
+	  || inst.instruction == M_MNEM_vmlsldava
+	  || inst.instruction == M_MNEM_vmlsldavx
+	  || inst.instruction == M_MNEM_vmlsldavax))
+    first_error (BAD_SIMD_TYPE);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_rrqq (et.type == NT_unsigned, et.size);
+}
+
+static void
+do_mve_vrmlaldavh (void)
+{
+  struct neon_type_el et;
+  if (inst.instruction == M_MNEM_vrmlsldavh
+     || inst.instruction == M_MNEM_vrmlsldavha
+     || inst.instruction == M_MNEM_vrmlsldavhx
+     || inst.instruction == M_MNEM_vrmlsldavhax)
+    {
+      et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
+      if (inst.operands[1].reg == REG_SP)
+	as_tsktsk (MVE_BAD_SP);
+    }
+  else
+    {
+      if (inst.instruction == M_MNEM_vrmlaldavhx
+	  || inst.instruction == M_MNEM_vrmlaldavhax)
+	et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
+      else
+	et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
+			      N_U32 | N_S32 | N_KEY);
+      /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
+	 with vmax/min instructions, making the use of SP in assembly really
+	 nonsensical, so instead of issuing a warning like we do for other uses
+	 of SP for the odd register operand we error out.  */
+      constraint (inst.operands[1].reg == REG_SP, BAD_SP);
+    }
+
+  /* Make sure we still check the second operand is an odd one and that PC is
+     disallowed.  This because we are parsing for any GPR operand, to be able
+     to distinguish between giving a warning or an error for SP as described
+     above.  */
+  constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
+  constraint (inst.operands[1].reg == REG_PC, BAD_PC);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_rrqq (et.type == NT_unsigned, 0);
+}
+
+
 static void
 do_mve_vmaxnmv (void)
 {
@@ -24471,6 +24568,27 @@ static const struct asm_opcode insns[] =
  mCEF(vminv,	_vminv,	  2, (RR, RMQ),				  mve_vmaxv),
  mCEF(vminav,	_vminav,  2, (RR, RMQ),				  mve_vmaxv),
 
+ mCEF(vmlaldav,	  _vmlaldav,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlaldava,  _vmlaldava,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlaldavx,  _vmlaldavx,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlaldavax, _vmlaldavax,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlalv,	  _vmlaldav,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlalva,	  _vmlaldava,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlsldav,	  _vmlsldav,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlsldava,  _vmlsldava,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlsldavx,  _vmlsldavx,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mCEF(vmlsldavax, _vmlsldavax,	4, (RRe, RRo, RMQ, RMQ),	mve_vmlaldav),
+ mToC("vrmlaldavh", ee800f00,	   4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mToC("vrmlaldavha",ee800f20,	   4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlaldavhx,  _vrmlaldavhx,  4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mToC("vrmlalvh",   ee800f00,	   4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mToC("vrmlalvha",  ee800f20,	   4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlsldavh,   _vrmlsldavh,   4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlsldavha,  _vrmlsldavha,  4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlsldavhx,  _vrmlsldavhx,  4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+ mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vmlaldav-bad.d b/gas/testsuite/gas/arm/mve-vmlaldav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..af5fdb16fb6c67b89ae87c2283945016c02a2e5f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlaldav-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLALDAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlaldav-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlaldav-bad.l b/gas/testsuite/gas/arm/mve-vmlaldav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..4789176383e0cf8415a4001a901b96d760a54877
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlaldav-bad.l
@@ -0,0 +1,62 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: bad type in SIMD instruction -- `vmlaldav.s64 r0,r1,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vmlaldav.f32 r0,r1,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vmlaldav.s8 r0,r1,q1,q2'
+[^:]*:18: Error: ARM register expected -- `vmlaldav.s16 r0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vmlaldava.s64 r0,r1,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vmlaldava.f32 r0,r1,q1,q2'
+[^:]*:21: Error: bad type in SIMD instruction -- `vmlaldava.s8 r0,r1,q1,q2'
+[^:]*:22: Error: ARM register expected -- `vmlaldava.s16 r0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vmlaldavx.s64 r0,r1,q1,q2'
+[^:]*:24: Error: bad type in SIMD instruction -- `vmlaldavx.f32 r0,r1,q1,q2'
+[^:]*:25: Error: bad type in SIMD instruction -- `vmlaldavx.s8 r0,r1,q1,q2'
+[^:]*:26: Error: ARM register expected -- `vmlaldavx.s16 r0,q1,q2'
+[^:]*:27: Error: bad type in SIMD instruction -- `vmlaldavax.s64 r0,r1,q1,q2'
+[^:]*:28: Error: bad type in SIMD instruction -- `vmlaldavax.f32 r0,r1,q1,q2'
+[^:]*:29: Error: bad type in SIMD instruction -- `vmlaldavax.s8 r0,r1,q1,q2'
+[^:]*:30: Error: ARM register expected -- `vmlaldavax.s16 r0,q1,q2'
+[^:]*:32: Error: syntax error -- `vmlaldaveq.s16 r0,r1,q1,q2'
+[^:]*:33: Error: syntax error -- `vmlaldaveq.s16 r0,r1,q1,q2'
+[^:]*:34: Error: syntax error -- `vmlaldaveq.s16 r0,r1,q1,q2'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vmlaldavt.s16 r0,r1,q1,q2'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vmlaldav.s16 r0,r1,q1,q2'
+[^:]*:39: Error: syntax error -- `vmlaldavaeq.s16 r0,r1,q1,q2'
+[^:]*:40: Error: syntax error -- `vmlaldavaeq.s16 r0,r1,q1,q2'
+[^:]*:41: Error: syntax error -- `vmlaldavaeq.s16 r0,r1,q1,q2'
+[^:]*:42: Error: vector predicated instruction should be in VPT/VPST block -- `vmlaldavat.s16 r0,r1,q1,q2'
+[^:]*:44: Error: instruction missing MVE vector predication code -- `vmlaldava.s16 r0,r1,q1,q2'
+[^:]*:46: Error: syntax error -- `vmlaldavxeq.s16 r0,r1,q1,q2'
+[^:]*:47: Error: syntax error -- `vmlaldavxeq.s16 r0,r1,q1,q2'
+[^:]*:48: Error: syntax error -- `vmlaldavxeq.s16 r0,r1,q1,q2'
+[^:]*:49: Error: vector predicated instruction should be in VPT/VPST block -- `vmlaldavxt.s16 r0,r1,q1,q2'
+[^:]*:51: Error: instruction missing MVE vector predication code -- `vmlaldavx.s16 r0,r1,q1,q2'
+[^:]*:53: Error: syntax error -- `vmlaldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:54: Error: syntax error -- `vmlaldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:55: Error: syntax error -- `vmlaldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:56: Error: vector predicated instruction should be in VPT/VPST block -- `vmlaldavaxt.s16 r0,r1,q1,q2'
+[^:]*:58: Error: instruction missing MVE vector predication code -- `vmlaldavax.s16 r0,r1,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmlaldav-bad.s b/gas/testsuite/gas/arm/mve-vmlaldav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..6ae484314ddb9dd75163b5b070a0ba757f7042ad
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlaldav-bad.s
@@ -0,0 +1,58 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, r1, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmlaldav.s16 r0, sp, q1, q2
+cond vmlaldav
+cond vmlaldava
+cond vmlaldavx
+cond vmlaldavax
+vmlaldav.s64 r0, r1, q1, q2
+vmlaldav.f32 r0, r1, q1, q2
+vmlaldav.s8 r0, r1, q1, q2
+vmlaldav.s16 r0, q1, q2
+vmlaldava.s64 r0, r1, q1, q2
+vmlaldava.f32 r0, r1, q1, q2
+vmlaldava.s8 r0, r1, q1, q2
+vmlaldava.s16 r0, q1, q2
+vmlaldavx.s64 r0, r1, q1, q2
+vmlaldavx.f32 r0, r1, q1, q2
+vmlaldavx.s8 r0, r1, q1, q2
+vmlaldavx.s16 r0, q1, q2
+vmlaldavax.s64 r0, r1, q1, q2
+vmlaldavax.f32 r0, r1, q1, q2
+vmlaldavax.s8 r0, r1, q1, q2
+vmlaldavax.s16 r0, q1, q2
+it eq
+vmlaldaveq.s16 r0, r1, q1, q2
+vmlaldaveq.s16 r0, r1, q1, q2
+vmlaldaveq.s16 r0, r1, q1, q2
+vmlaldavt.s16 r0, r1, q1, q2
+vpst
+vmlaldav.s16 r0, r1, q1, q2
+it eq
+vmlaldavaeq.s16 r0, r1, q1, q2
+vmlaldavaeq.s16 r0, r1, q1, q2
+vmlaldavaeq.s16 r0, r1, q1, q2
+vmlaldavat.s16 r0, r1, q1, q2
+vpst
+vmlaldava.s16 r0, r1, q1, q2
+it eq
+vmlaldavxeq.s16 r0, r1, q1, q2
+vmlaldavxeq.s16 r0, r1, q1, q2
+vmlaldavxeq.s16 r0, r1, q1, q2
+vmlaldavxt.s16 r0, r1, q1, q2
+vpst
+vmlaldavx.s16 r0, r1, q1, q2
+it eq
+vmlaldavaxeq.s16 r0, r1, q1, q2
+vmlaldavaxeq.s16 r0, r1, q1, q2
+vmlaldavaxeq.s16 r0, r1, q1, q2
+vmlaldavaxt.s16 r0, r1, q1, q2
+vpst
+vmlaldavax.s16 r0, r1, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmlalv-bad.d b/gas/testsuite/gas/arm/mve-vmlalv-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..dbd3b7705de87b27d7dde3a401f22253cc38d537
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlalv-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLADALV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlalv-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlalv-bad.l b/gas/testsuite/gas/arm/mve-vmlalv-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..0f6ee63d5db9113a662bba019758c84698743ca3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlalv-bad.l
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:11: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Error: bad type in SIMD instruction -- `vmlalv.s64 r0,r1,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vmlalv.f32 r0,r1,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmlalv.s8 r0,r1,q1,q2'
+[^:]*:15: Error: ARM register expected -- `vmlalv.s16 r0,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vmlalva.s64 r0,r1,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vmlalva.f32 r0,r1,q1,q2'
+[^:]*:18: Error: bad type in SIMD instruction -- `vmlalva.s8 r0,r1,q1,q2'
+[^:]*:19: Error: ARM register expected -- `vmlalva.s16 r0,q1,q2'
+[^:]*:20: Error: bad instruction `vmlalvx.s16 r0,r1,q1,q2'
+[^:]*:21: Error: bad instruction `vmlalvax.s16 r0,r1,q1,q2'
+[^:]*:23: Error: syntax error -- `vmlalveq.s16 r0,r1,q1,q2'
+[^:]*:24: Error: syntax error -- `vmlalveq.s16 r0,r1,q1,q2'
+[^:]*:25: Error: syntax error -- `vmlalveq.s16 r0,r1,q1,q2'
+[^:]*:26: Error: vector predicated instruction should be in VPT/VPST block -- `vmlalvt.s16 r0,r1,q1,q2'
+[^:]*:28: Error: instruction missing MVE vector predication code -- `vmlalv.s16 r0,r1,q1,q2'
+[^:]*:30: Error: syntax error -- `vmlalvaeq.s16 r0,r1,q1,q2'
+[^:]*:31: Error: syntax error -- `vmlalvaeq.s16 r0,r1,q1,q2'
+[^:]*:32: Error: syntax error -- `vmlalvaeq.s16 r0,r1,q1,q2'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vmlalvat.s16 r0,r1,q1,q2'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vmlalva.s16 r0,r1,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmlalv-bad.s b/gas/testsuite/gas/arm/mve-vmlalv-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..b390739d221459381a3e27c427c6c7316b63e69b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlalv-bad.s
@@ -0,0 +1,35 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, r1, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond vmlalv
+cond vmlalva
+vmlalv.s64 r0, r1, q1, q2
+vmlalv.f32 r0, r1, q1, q2
+vmlalv.s8 r0, r1, q1, q2
+vmlalv.s16 r0, q1, q2
+vmlalva.s64 r0, r1, q1, q2
+vmlalva.f32 r0, r1, q1, q2
+vmlalva.s8 r0, r1, q1, q2
+vmlalva.s16 r0, q1, q2
+vmlalvx.s16 r0, r1, q1, q2
+vmlalvax.s16 r0, r1, q1, q2
+it eq
+vmlalveq.s16 r0, r1, q1, q2
+vmlalveq.s16 r0, r1, q1, q2
+vmlalveq.s16 r0, r1, q1, q2
+vmlalvt.s16 r0, r1, q1, q2
+vpst
+vmlalv.s16 r0, r1, q1, q2
+it eq
+vmlalvaeq.s16 r0, r1, q1, q2
+vmlalvaeq.s16 r0, r1, q1, q2
+vmlalvaeq.s16 r0, r1, q1, q2
+vmlalvat.s16 r0, r1, q1, q2
+vpst
+vmlalva.s16 r0, r1, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vmlsldav-bad.d b/gas/testsuite/gas/arm/mve-vmlsldav-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..06f9f123290e7fa0c09155162d2c3729299c5e11
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsldav-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLSLDAV instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlsldav-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlsldav-bad.l b/gas/testsuite/gas/arm/mve-vmlsldav-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..15212e9f9d0ba53eea1d7718caa163f3baf42947
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsldav-bad.l
@@ -0,0 +1,63 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:11: Error: bad type in SIMD instruction -- `vmlsldav.u16 r0,r1,q1,q2'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: bad type in SIMD instruction -- `vmlsldav.s64 r0,r1,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vmlsldav.f32 r0,r1,q1,q2'
+[^:]*:18: Error: bad type in SIMD instruction -- `vmlsldav.s8 r0,r1,q1,q2'
+[^:]*:19: Error: ARM register expected -- `vmlsldav.s16 r0,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vmlsldava.s64 r0,r1,q1,q2'
+[^:]*:21: Error: bad type in SIMD instruction -- `vmlsldava.f32 r0,r1,q1,q2'
+[^:]*:22: Error: bad type in SIMD instruction -- `vmlsldava.s8 r0,r1,q1,q2'
+[^:]*:23: Error: ARM register expected -- `vmlsldava.s16 r0,q1,q2'
+[^:]*:24: Error: bad type in SIMD instruction -- `vmlsldavx.s64 r0,r1,q1,q2'
+[^:]*:25: Error: bad type in SIMD instruction -- `vmlsldavx.f32 r0,r1,q1,q2'
+[^:]*:26: Error: bad type in SIMD instruction -- `vmlsldavx.s8 r0,r1,q1,q2'
+[^:]*:27: Error: ARM register expected -- `vmlsldavx.s16 r0,q1,q2'
+[^:]*:28: Error: bad type in SIMD instruction -- `vmlsldavax.s64 r0,r1,q1,q2'
+[^:]*:29: Error: bad type in SIMD instruction -- `vmlsldavax.f32 r0,r1,q1,q2'
+[^:]*:30: Error: bad type in SIMD instruction -- `vmlsldavax.s8 r0,r1,q1,q2'
+[^:]*:31: Error: ARM register expected -- `vmlsldavax.s16 r0,q1,q2'
+[^:]*:33: Error: syntax error -- `vmlsldaveq.s16 r0,r1,q1,q2'
+[^:]*:34: Error: syntax error -- `vmlsldaveq.s16 r0,r1,q1,q2'
+[^:]*:35: Error: syntax error -- `vmlsldaveq.s16 r0,r1,q1,q2'
+[^:]*:36: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsldavt.s16 r0,r1,q1,q2'
+[^:]*:38: Error: instruction missing MVE vector predication code -- `vmlsldav.s16 r0,r1,q1,q2'
+[^:]*:40: Error: syntax error -- `vmlsldavaeq.s16 r0,r1,q1,q2'
+[^:]*:41: Error: syntax error -- `vmlsldavaeq.s16 r0,r1,q1,q2'
+[^:]*:42: Error: syntax error -- `vmlsldavaeq.s16 r0,r1,q1,q2'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsldavat.s16 r0,r1,q1,q2'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vmlsldava.s16 r0,r1,q1,q2'
+[^:]*:47: Error: syntax error -- `vmlsldavxeq.s16 r0,r1,q1,q2'
+[^:]*:48: Error: syntax error -- `vmlsldavxeq.s16 r0,r1,q1,q2'
+[^:]*:49: Error: syntax error -- `vmlsldavxeq.s16 r0,r1,q1,q2'
+[^:]*:50: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsldavxt.s16 r0,r1,q1,q2'
+[^:]*:52: Error: instruction missing MVE vector predication code -- `vmlsldavx.s16 r0,r1,q1,q2'
+[^:]*:54: Error: syntax error -- `vmlsldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:55: Error: syntax error -- `vmlsldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:56: Error: syntax error -- `vmlsldavaxeq.s16 r0,r1,q1,q2'
+[^:]*:57: Error: vector predicated instruction should be in VPT/VPST block -- `vmlsldavaxt.s16 r0,r1,q1,q2'
+[^:]*:59: Error: instruction missing MVE vector predication code -- `vmlsldavax.s16 r0,r1,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmlsldav-bad.s b/gas/testsuite/gas/arm/mve-vmlsldav-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..6cabd3831945db296590dc1587fd7faf273f185e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlsldav-bad.s
@@ -0,0 +1,60 @@
+.macro cond, op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 r0, r1, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmlsldav.s16 r0, sp, q1, q2
+vmlsldav.u16 r0, r1, q1, q2
+cond vmlsldav
+cond vmlsldava
+cond vmlsldavx
+cond vmlsldavax
+vmlsldav.s64 r0, r1, q1, q2
+vmlsldav.f32 r0, r1, q1, q2
+vmlsldav.s8 r0, r1, q1, q2
+vmlsldav.s16 r0, q1, q2
+vmlsldava.s64 r0, r1, q1, q2
+vmlsldava.f32 r0, r1, q1, q2
+vmlsldava.s8 r0, r1, q1, q2
+vmlsldava.s16 r0, q1, q2
+vmlsldavx.s64 r0, r1, q1, q2
+vmlsldavx.f32 r0, r1, q1, q2
+vmlsldavx.s8 r0, r1, q1, q2
+vmlsldavx.s16 r0, q1, q2
+vmlsldavax.s64 r0, r1, q1, q2
+vmlsldavax.f32 r0, r1, q1, q2
+vmlsldavax.s8 r0, r1, q1, q2
+vmlsldavax.s16 r0, q1, q2
+it eq
+vmlsldaveq.s16 r0, r1, q1, q2
+vmlsldaveq.s16 r0, r1, q1, q2
+vmlsldaveq.s16 r0, r1, q1, q2
+vmlsldavt.s16 r0, r1, q1, q2
+vpst
+vmlsldav.s16 r0, r1, q1, q2
+it eq
+vmlsldavaeq.s16 r0, r1, q1, q2
+vmlsldavaeq.s16 r0, r1, q1, q2
+vmlsldavaeq.s16 r0, r1, q1, q2
+vmlsldavat.s16 r0, r1, q1, q2
+vpst
+vmlsldava.s16 r0, r1, q1, q2
+it eq
+vmlsldavxeq.s16 r0, r1, q1, q2
+vmlsldavxeq.s16 r0, r1, q1, q2
+vmlsldavxeq.s16 r0, r1, q1, q2
+vmlsldavxt.s16 r0, r1, q1, q2
+vpst
+vmlsldavx.s16 r0, r1, q1, q2
+it eq
+vmlsldavaxeq.s16 r0, r1, q1, q2
+vmlsldavaxeq.s16 r0, r1, q1, q2
+vmlsldavaxeq.s16 r0, r1, q1, q2
+vmlsldavaxt.s16 r0, r1, q1, q2
+vpst
+vmlsldavax.s16 r0, r1, q1, q2
+
diff --git a/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.d b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..49f3162e0fe55e17d00541abc51276f9ce3634b3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.d
@@ -0,0 +1,5 @@
+#name: bad VRMLALDAVH, VRMLALVH and VRMLSLDAVH instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vrmlaldavh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.l b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..507cc13755e8c3b392482d754af0b043742cc556
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.l
@@ -0,0 +1,171 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vrmlaldavh.s16 r0,r1,q2,q3'
+[^:]*:11: Error: bad type in SIMD instruction -- `vrmlaldavh.i32 r0,r1,q2,q3'
+[^:]*:12: Error: bad type in SIMD instruction -- `vrmlaldavha.s16 r0,r1,q2,q3'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrmlaldavha.i32 r0,r1,q2,q3'
+[^:]*:14: Error: bad type in SIMD instruction -- `vrmlalvh.s16 r0,r1,q2,q3'
+[^:]*:15: Error: bad type in SIMD instruction -- `vrmlalvh.i32 r0,r1,q2,q3'
+[^:]*:16: Error: bad type in SIMD instruction -- `vrmlalvha.s16 r0,r1,q2,q3'
+[^:]*:17: Error: bad type in SIMD instruction -- `vrmlalvha.i32 r0,r1,q2,q3'
+[^:]*:18: Error: bad type in SIMD instruction -- `vrmlaldavhx.u32 r0,r1,q2,q3'
+[^:]*:19: Error: bad type in SIMD instruction -- `vrmlaldavhax.u32 r0,r1,q2,q3'
+[^:]*:20: Error: bad type in SIMD instruction -- `vrmlaldavhx.i32 r0,r1,q2,q3'
+[^:]*:21: Error: bad type in SIMD instruction -- `vrmlaldavhax.i32 r0,r1,q2,q3'
+[^:]*:22: Error: bad type in SIMD instruction -- `vrmlsldavh.s16 r0,r1,q2,q3'
+[^:]*:23: Error: bad type in SIMD instruction -- `vrmlsldavh.u32 r0,r1,q2,q3'
+[^:]*:24: Error: bad type in SIMD instruction -- `vrmlsldavha.s16 r0,r1,q2,q3'
+[^:]*:25: Error: bad type in SIMD instruction -- `vrmlsldavha.u32 r0,r1,q2,q3'
+[^:]*:26: Error: bad type in SIMD instruction -- `vrmlsldavhx.s16 r0,r1,q2,q3'
+[^:]*:27: Error: bad type in SIMD instruction -- `vrmlsldavhx.u32 r0,r1,q2,q3'
+[^:]*:28: Error: bad type in SIMD instruction -- `vrmlsldavhax.s16 r0,r1,q2,q3'
+[^:]*:29: Error: bad type in SIMD instruction -- `vrmlsldavhax.u32 r0,r1,q2,q3'
+[^:]*:30: Error: Odd register not allowed here -- `vrmlaldavh.s32 r1,r1,q2,q3'
+[^:]*:31: Error: Even register not allowed here -- `vrmlaldavh.s32 r0,r0,q2,q3'
+[^:]*:32: Error: r13 not allowed here -- `vrmlaldavh.s32 r0,sp,q2,q3'
+[^:]*:33: Error: r15 not allowed here -- `vrmlaldavh.s32 r0,pc,q2,q3'
+[^:]*:34: Error: Odd register not allowed here -- `vrmlaldavha.s32 r1,r1,q2,q3'
+[^:]*:35: Error: Even register not allowed here -- `vrmlaldavha.s32 r0,r0,q2,q3'
+[^:]*:36: Error: r13 not allowed here -- `vrmlaldavha.s32 r0,sp,q2,q3'
+[^:]*:37: Error: r15 not allowed here -- `vrmlaldavha.s32 r0,pc,q2,q3'
+[^:]*:38: Error: Odd register not allowed here -- `vrmlaldavhx.s32 r1,r1,q2,q3'
+[^:]*:39: Error: Even register not allowed here -- `vrmlaldavhx.s32 r0,r0,q2,q3'
+[^:]*:40: Error: r13 not allowed here -- `vrmlaldavhx.s32 r0,sp,q2,q3'
+[^:]*:41: Error: r15 not allowed here -- `vrmlaldavhx.s32 r0,pc,q2,q3'
+[^:]*:42: Error: Odd register not allowed here -- `vrmlaldavhax.s32 r1,r1,q2,q3'
+[^:]*:43: Error: Even register not allowed here -- `vrmlaldavhax.s32 r0,r0,q2,q3'
+[^:]*:44: Error: r13 not allowed here -- `vrmlaldavhax.s32 r0,sp,q2,q3'
+[^:]*:45: Error: r15 not allowed here -- `vrmlaldavhax.s32 r0,pc,q2,q3'
+[^:]*:46: Error: Odd register not allowed here -- `vrmlalvh.s32 r1,r1,q2,q3'
+[^:]*:47: Error: Even register not allowed here -- `vrmlalvh.s32 r0,r0,q2,q3'
+[^:]*:48: Error: r13 not allowed here -- `vrmlalvh.s32 r0,sp,q2,q3'
+[^:]*:49: Error: r15 not allowed here -- `vrmlalvh.s32 r0,pc,q2,q3'
+[^:]*:50: Error: Odd register not allowed here -- `vrmlalvha.s32 r1,r1,q2,q3'
+[^:]*:51: Error: Even register not allowed here -- `vrmlalvha.s32 r0,r0,q2,q3'
+[^:]*:52: Error: r13 not allowed here -- `vrmlalvha.s32 r0,sp,q2,q3'
+[^:]*:53: Error: r15 not allowed here -- `vrmlalvha.s32 r0,pc,q2,q3'
+[^:]*:54: Error: Odd register not allowed here -- `vrmlsldavh.s32 r1,r1,q2,q3'
+[^:]*:55: Error: Even register not allowed here -- `vrmlsldavh.s32 r0,r0,q2,q3'
+[^:]*:56: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:57: Error: r15 not allowed here -- `vrmlsldavh.s32 r0,pc,q2,q3'
+[^:]*:58: Error: Odd register not allowed here -- `vrmlsldavha.s32 r1,r1,q2,q3'
+[^:]*:59: Error: Even register not allowed here -- `vrmlsldavha.s32 r0,r0,q2,q3'
+[^:]*:60: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:61: Error: r15 not allowed here -- `vrmlsldavha.s32 r0,pc,q2,q3'
+[^:]*:62: Error: Odd register not allowed here -- `vrmlsldavhx.s32 r1,r1,q2,q3'
+[^:]*:63: Error: Even register not allowed here -- `vrmlsldavhx.s32 r0,r0,q2,q3'
+[^:]*:64: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:65: Error: r15 not allowed here -- `vrmlsldavhx.s32 r0,pc,q2,q3'
+[^:]*:66: Error: Odd register not allowed here -- `vrmlsldavhax.s32 r1,r1,q2,q3'
+[^:]*:67: Error: Even register not allowed here -- `vrmlsldavhax.s32 r0,r0,q2,q3'
+[^:]*:68: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:69: Error: r15 not allowed here -- `vrmlsldavhax.s32 r0,pc,q2,q3'
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:70: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:71: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:72: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:73: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:74: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:75: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:76: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:77: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:78: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:79: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:81: Error: syntax error -- `vrmlaldavheq.s32 r0,r1,q2,q3'
+[^:]*:82: Error: syntax error -- `vrmlaldavheq.s32 r0,r1,q2,q3'
+[^:]*:84: Error: syntax error -- `vrmlaldavheq.s32 r0,r1,q2,q3'
+[^:]*:85: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlaldavht.s32 r0,r1,q2,q3'
+[^:]*:87: Error: instruction missing MVE vector predication code -- `vrmlaldavh.s32 r0,r1,q2,q3'
+[^:]*:89: Error: syntax error -- `vrmlaldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:90: Error: syntax error -- `vrmlaldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:92: Error: syntax error -- `vrmlaldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:93: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlaldavhat.s32 r0,r1,q2,q3'
+[^:]*:95: Error: instruction missing MVE vector predication code -- `vrmlaldavha.s32 r0,r1,q2,q3'
+[^:]*:97: Error: syntax error -- `vrmlaldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:98: Error: syntax error -- `vrmlaldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:100: Error: syntax error -- `vrmlaldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:101: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlaldavhxt.s32 r0,r1,q2,q3'
+[^:]*:103: Error: instruction missing MVE vector predication code -- `vrmlaldavhx.s32 r0,r1,q2,q3'
+[^:]*:105: Error: syntax error -- `vrmlaldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:106: Error: syntax error -- `vrmlaldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:108: Error: syntax error -- `vrmlaldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:109: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlaldavhaxt.s32 r0,r1,q2,q3'
+[^:]*:111: Error: instruction missing MVE vector predication code -- `vrmlaldavhax.s32 r0,r1,q2,q3'
+[^:]*:113: Error: syntax error -- `vrmlalvheq.s32 r0,r1,q2,q3'
+[^:]*:114: Error: syntax error -- `vrmlalvheq.s32 r0,r1,q2,q3'
+[^:]*:116: Error: syntax error -- `vrmlalvheq.s32 r0,r1,q2,q3'
+[^:]*:117: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlalvht.s32 r0,r1,q2,q3'
+[^:]*:119: Error: instruction missing MVE vector predication code -- `vrmlalvh.s32 r0,r1,q2,q3'
+[^:]*:121: Error: syntax error -- `vrmlalvhaeq.s32 r0,r1,q2,q3'
+[^:]*:122: Error: syntax error -- `vrmlalvhaeq.s32 r0,r1,q2,q3'
+[^:]*:124: Error: syntax error -- `vrmlalvhaeq.s32 r0,r1,q2,q3'
+[^:]*:125: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlalvhat.s32 r0,r1,q2,q3'
+[^:]*:127: Error: instruction missing MVE vector predication code -- `vrmlalvha.s32 r0,r1,q2,q3'
+[^:]*:129: Error: syntax error -- `vrmlsldavheq.s32 r0,r1,q2,q3'
+[^:]*:130: Error: syntax error -- `vrmlsldavheq.s32 r0,r1,q2,q3'
+[^:]*:132: Error: syntax error -- `vrmlsldavheq.s32 r0,r1,q2,q3'
+[^:]*:133: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlsldavht.s32 r0,r1,q2,q3'
+[^:]*:135: Error: instruction missing MVE vector predication code -- `vrmlsldavh.s32 r0,r1,q2,q3'
+[^:]*:137: Error: syntax error -- `vrmlsldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:138: Error: syntax error -- `vrmlsldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:140: Error: syntax error -- `vrmlsldavhaeq.s32 r0,r1,q2,q3'
+[^:]*:141: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlsldavhat.s32 r0,r1,q2,q3'
+[^:]*:143: Error: instruction missing MVE vector predication code -- `vrmlsldavha.s32 r0,r1,q2,q3'
+[^:]*:145: Error: syntax error -- `vrmlsldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:146: Error: syntax error -- `vrmlsldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:148: Error: syntax error -- `vrmlsldavhxeq.s32 r0,r1,q2,q3'
+[^:]*:149: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlsldavhxt.s32 r0,r1,q2,q3'
+[^:]*:151: Error: instruction missing MVE vector predication code -- `vrmlsldavhx.s32 r0,r1,q2,q3'
+[^:]*:153: Error: syntax error -- `vrmlsldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:154: Error: syntax error -- `vrmlsldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:156: Error: syntax error -- `vrmlsldavhaxeq.s32 r0,r1,q2,q3'
+[^:]*:157: Error: vector predicated instruction should be in VPT/VPST block -- `vrmlsldavhaxt.s32 r0,r1,q2,q3'
+[^:]*:159: Error: instruction missing MVE vector predication code -- `vrmlsldavhax.s32 r0,r1,q2,q3'
diff --git a/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.s b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..0bd6a853ef3a6837f2cb51a100c09b89aed55f40
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrmlaldavh-bad.s
@@ -0,0 +1,159 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 r0, r1, q2, q3
+.endr
+.endm
+
+.syntax unified
+.thumb
+vrmlaldavh.s16 r0, r1, q2, q3
+vrmlaldavh.i32 r0, r1, q2, q3
+vrmlaldavha.s16 r0, r1, q2, q3
+vrmlaldavha.i32 r0, r1, q2, q3
+vrmlalvh.s16 r0, r1, q2, q3
+vrmlalvh.i32 r0, r1, q2, q3
+vrmlalvha.s16 r0, r1, q2, q3
+vrmlalvha.i32 r0, r1, q2, q3
+vrmlaldavhx.u32 r0, r1, q2, q3
+vrmlaldavhax.u32 r0, r1, q2, q3
+vrmlaldavhx.i32 r0, r1, q2, q3
+vrmlaldavhax.i32 r0, r1, q2, q3
+vrmlsldavh.s16 r0, r1, q2, q3
+vrmlsldavh.u32 r0, r1, q2, q3
+vrmlsldavha.s16 r0, r1, q2, q3
+vrmlsldavha.u32 r0, r1, q2, q3
+vrmlsldavhx.s16 r0, r1, q2, q3
+vrmlsldavhx.u32 r0, r1, q2, q3
+vrmlsldavhax.s16 r0, r1, q2, q3
+vrmlsldavhax.u32 r0, r1, q2, q3
+vrmlaldavh.s32 r1, r1, q2, q3
+vrmlaldavh.s32 r0, r0, q2, q3
+vrmlaldavh.s32 r0, sp, q2, q3
+vrmlaldavh.s32 r0, pc, q2, q3
+vrmlaldavha.s32 r1, r1, q2, q3
+vrmlaldavha.s32 r0, r0, q2, q3
+vrmlaldavha.s32 r0, sp, q2, q3
+vrmlaldavha.s32 r0, pc, q2, q3
+vrmlaldavhx.s32 r1, r1, q2, q3
+vrmlaldavhx.s32 r0, r0, q2, q3
+vrmlaldavhx.s32 r0, sp, q2, q3
+vrmlaldavhx.s32 r0, pc, q2, q3
+vrmlaldavhax.s32 r1, r1, q2, q3
+vrmlaldavhax.s32 r0, r0, q2, q3
+vrmlaldavhax.s32 r0, sp, q2, q3
+vrmlaldavhax.s32 r0, pc, q2, q3
+vrmlalvh.s32 r1, r1, q2, q3
+vrmlalvh.s32 r0, r0, q2, q3
+vrmlalvh.s32 r0, sp, q2, q3
+vrmlalvh.s32 r0, pc, q2, q3
+vrmlalvha.s32 r1, r1, q2, q3
+vrmlalvha.s32 r0, r0, q2, q3
+vrmlalvha.s32 r0, sp, q2, q3
+vrmlalvha.s32 r0, pc, q2, q3
+vrmlsldavh.s32 r1, r1, q2, q3
+vrmlsldavh.s32 r0, r0, q2, q3
+vrmlsldavh.s32 r0, sp, q2, q3
+vrmlsldavh.s32 r0, pc, q2, q3
+vrmlsldavha.s32 r1, r1, q2, q3
+vrmlsldavha.s32 r0, r0, q2, q3
+vrmlsldavha.s32 r0, sp, q2, q3
+vrmlsldavha.s32 r0, pc, q2, q3
+vrmlsldavhx.s32 r1, r1, q2, q3
+vrmlsldavhx.s32 r0, r0, q2, q3
+vrmlsldavhx.s32 r0, sp, q2, q3
+vrmlsldavhx.s32 r0, pc, q2, q3
+vrmlsldavhax.s32 r1, r1, q2, q3
+vrmlsldavhax.s32 r0, r0, q2, q3
+vrmlsldavhax.s32 r0, sp, q2, q3
+vrmlsldavhax.s32 r0, pc, q2, q3
+cond vrmlaldavh
+cond vrmlaldavha
+cond vrmlaldavhx
+cond vrmlaldavhax
+cond vrmlalvh
+cond vrmlalvha
+cond vrmlsldavh
+cond vrmlsldavha
+cond vrmlsldavhx
+cond vrmlsldavhax
+it eq
+vrmlaldavheq.s32 r0, r1, q2, q3
+vrmlaldavheq.s32 r0, r1, q2, q3
+vpst
+vrmlaldavheq.s32 r0, r1, q2, q3
+vrmlaldavht.s32 r0, r1, q2, q3
+vpst
+vrmlaldavh.s32 r0, r1, q2, q3
+it eq
+vrmlaldavhaeq.s32 r0, r1, q2, q3
+vrmlaldavhaeq.s32 r0, r1, q2, q3
+vpst
+vrmlaldavhaeq.s32 r0, r1, q2, q3
+vrmlaldavhat.s32 r0, r1, q2, q3
+vpst
+vrmlaldavha.s32 r0, r1, q2, q3
+it eq
+vrmlaldavhxeq.s32 r0, r1, q2, q3
+vrmlaldavhxeq.s32 r0, r1, q2, q3
+vpst
+vrmlaldavhxeq.s32 r0, r1, q2, q3
+vrmlaldavhxt.s32 r0, r1, q2, q3
+vpst
+vrmlaldavhx.s32 r0, r1, q2, q3
+it eq
+vrmlaldavhaxeq.s32 r0, r1, q2, q3
+vrmlaldavhaxeq.s32 r0, r1, q2, q3
+vpst
+vrmlaldavhaxeq.s32 r0, r1, q2, q3
+vrmlaldavhaxt.s32 r0, r1, q2, q3
+vpst
+vrmlaldavhax.s32 r0, r1, q2, q3
+it eq
+vrmlalvheq.s32 r0, r1, q2, q3
+vrmlalvheq.s32 r0, r1, q2, q3
+vpst
+vrmlalvheq.s32 r0, r1, q2, q3
+vrmlalvht.s32 r0, r1, q2, q3
+vpst
+vrmlalvh.s32 r0, r1, q2, q3
+it eq
+vrmlalvhaeq.s32 r0, r1, q2, q3
+vrmlalvhaeq.s32 r0, r1, q2, q3
+vpst
+vrmlalvhaeq.s32 r0, r1, q2, q3
+vrmlalvhat.s32 r0, r1, q2, q3
+vpst
+vrmlalvha.s32 r0, r1, q2, q3
+it eq
+vrmlsldavheq.s32 r0, r1, q2, q3
+vrmlsldavheq.s32 r0, r1, q2, q3
+vpst
+vrmlsldavheq.s32 r0, r1, q2, q3
+vrmlsldavht.s32 r0, r1, q2, q3
+vpst
+vrmlsldavh.s32 r0, r1, q2, q3
+it eq
+vrmlsldavhaeq.s32 r0, r1, q2, q3
+vrmlsldavhaeq.s32 r0, r1, q2, q3
+vpst
+vrmlsldavhaeq.s32 r0, r1, q2, q3
+vrmlsldavhat.s32 r0, r1, q2, q3
+vpst
+vrmlsldavha.s32 r0, r1, q2, q3
+it eq
+vrmlsldavhxeq.s32 r0, r1, q2, q3
+vrmlsldavhxeq.s32 r0, r1, q2, q3
+vpst
+vrmlsldavhxeq.s32 r0, r1, q2, q3
+vrmlsldavhxt.s32 r0, r1, q2, q3
+vpst
+vrmlsldavhx.s32 r0, r1, q2, q3
+it eq
+vrmlsldavhaxeq.s32 r0, r1, q2, q3
+vrmlsldavhaxeq.s32 r0, r1, q2, q3
+vpst
+vrmlsldavhaxeq.s32 r0, r1, q2, q3
+vrmlsldavhaxt.s32 r0, r1, q2, q3
+vpst
+vrmlsldavhax.s32 r0, r1, q2, q3

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 23/57][Arm][GAS] Add support for MVE instructions: vmla, vmul, vqadd and vqsub
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (21 preceding siblings ...)
  2019-05-01 17:15 ` [PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav, vrmlaldavh, vrmlalvh and vrmlsldavh Andre Vieira (lists)
@ 2019-05-01 17:15 ` Andre Vieira (lists)
  2019-05-01 17:16 ` [PATCH 24/57][Arm][GAS] Add support for MVE instructions: vmlas, vmulh and vrmulh Andre Vieira (lists)
                   ` (37 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:15 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1071 bytes --]

Hi,

This patch adds support for MVE instructions VMLA, VMUL, VQADD, and VQSUB.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): New operand.
	(parse_operands): Handle new operand.
	(mve_encode_qqr): Handle new instructions.
	(do_neon_dyadic_i64_su): Accept MVE variants.
	(neon_dyadic_misc): Likewise.
	(do_neon_mac_maybe_scalar): Likewise.
	(do_neon_mul): Likewise.
	(insns): Change to accept MVE variants.
	* testsuite/gas/arm/mve-vmla-bad.d: New test.
	* testsuite/gas/arm/mve-vmla-bad.l: New test.
	* testsuite/gas/arm/mve-vmla-bad.s: New test.
	* testsuite/gas/arm/mve-vmul-bad-1.d: New test.
	* testsuite/gas/arm/mve-vmul-bad-1.l: New test.
	* testsuite/gas/arm/mve-vmul-bad-1.s: New test.
	* testsuite/gas/arm/mve-vmul-bad-2.d: New test.
	* testsuite/gas/arm/mve-vmul-bad-2.l: New test.
	* testsuite/gas/arm/mve-vmul-bad-2.s: New test.
	* testsuite/gas/arm/mve-vqaddsub-bad.d: New test.
	* testsuite/gas/arm/mve-vqaddsub-bad.l: New test.
	* testsuite/gas/arm/mve-vqaddsub-bad.s: New test.

[-- Attachment #2: 23.patch --]
[-- Type: text/x-patch, Size: 24543 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 77a68067f95ddcbd4b31b5309ea833dd875d063c..dd02a8e5a790f170d1f87ae1c36dd5e7e5a4827a 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6954,6 +6954,8 @@ enum operand_parse_code
   OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar.  */
   OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
 		     */
+  OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
+			  scalar, or ARM register.  */
   OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar.  */
   OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar.  */
   OP_RND_RNSC,  /* Neon D reg, or Neon scalar.  */
@@ -7328,6 +7330,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  }
 	  break;
 
+	case OP_RNSDQ_RNSC_MQ_RR:
+	  po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
+	  break;
+	try_rnsdq_rnsc_mq:
 	case OP_RNSDQ_RNSC_MQ:
 	  po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
 	  break;
@@ -15902,6 +15908,9 @@ mve_encode_qqr (int size, int U, int fp)
       /* vsub.  */
       else if (((unsigned)inst.instruction) == 0x200d00)
 	inst.instruction = 0xee301f40;
+      /* vmul.  */
+      else if (((unsigned)inst.instruction) == 0x1000d10)
+	inst.instruction = 0xee310e60;
 
       /* Setting size which is 1 for F16 and 0 for F32.  */
       inst.instruction |= (size == 16) << 28;
@@ -15920,6 +15929,18 @@ mve_encode_qqr (int size, int U, int fp)
       /* vhsub.  */
       else if (((unsigned)inst.instruction) == 0x200)
 	inst.instruction = 0xee001f40;
+      /* vmla.  */
+      else if (((unsigned)inst.instruction) == 0x900)
+	inst.instruction = 0xee010e40;
+      /* vmul.  */
+      else if (((unsigned)inst.instruction) == 0x910)
+	inst.instruction = 0xee011e60;
+      /* vqadd.  */
+      else if (((unsigned)inst.instruction) == 0x10)
+	inst.instruction = 0xee000f60;
+      /* vqsub.  */
+      else if (((unsigned)inst.instruction) == 0x210)
+	inst.instruction = 0xee001f60;
 
       /* Set U-bit.  */
       inst.instruction |= U << 28;
@@ -16148,10 +16169,24 @@ do_neon_dyadic_i_su (void)
 static void
 do_neon_dyadic_i64_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_ALL | N_KEY);
-  neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+    return;
+  enum neon_shape rs;
+  struct neon_type_el et;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    {
+      rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
+    }
+  if (rs == NS_QQR)
+    mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
+  else
+    neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
 }
 
 static void
@@ -16445,7 +16480,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, 0);
+	mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
       else
 	neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
     }
@@ -16970,19 +17005,30 @@ do_neon_mac_maybe_scalar (void)
   if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
     return;
 
-  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (inst.operands[2].isscalar)
     {
+      constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
       enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
       struct neon_type_el et = neon_check_type (3, rs,
 	N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
       NEON_ENCODE (SCALAR, inst);
       neon_mul_mac (et, neon_quad (rs));
     }
+  else if (!inst.operands[2].isvec)
+    {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
+
+      enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+      neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
+      neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
+    }
   else
     {
+      constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
       /* The "untyped" case can't happen.  Do this to stop the "U" bit being
 	 affected if we specify unsigned args.  */
       neon_dyadic_misc (NT_untyped, N_IF_32, 0);
@@ -17050,13 +17096,34 @@ do_neon_mul (void)
   if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
     return;
 
-  if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (inst.operands[2].isscalar)
-    do_neon_mac_maybe_scalar ();
+    {
+      constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
+      do_neon_mac_maybe_scalar ();
+    }
   else
-    neon_dyadic_misc (NT_poly, N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
+    {
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
+	  struct neon_type_el et
+	    = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
+	  if (et.type == NT_float)
+	    constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
+			BAD_FPU);
+
+	  neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
+	}
+      else
+	{
+	  constraint (!inst.operands[2].isvec, BAD_FPU);
+	  neon_dyadic_misc (NT_poly,
+			    N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
+	}
+    }
 }
 
 static void
@@ -23779,8 +23846,6 @@ static const struct asm_opcode insns[] =
  NCE(vcvtz,     0,       2, (RVSD, RVSD),       vfp_nsyn_cvtz),
 
   /* Mnemonics shared by Neon and VFP.  */
- nCEF(vmul,     _vmul,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mul),
- nCEF(vmla,     _vmla,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
  nCEF(vmls,     _vmls,    3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
 
  NCE(vldm,      c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
@@ -23834,9 +23899,7 @@ static const struct asm_opcode insns[] =
  NUF(vrhaddq,   0000100, 3, (RNQ,  oRNQ,  RNQ),  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),
  NUF(vqaddq,    0000010, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
- NUF(vqsub,     0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
  NUF(vqsubq,    0000210, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
  NUF(vrshl,     0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
  NUF(vrshlq,    0000500, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
@@ -24604,6 +24667,8 @@ static const struct asm_opcode insns[] =
 #define ARM_VARIANT  & fpu_vfp_ext_v1
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT  & arm_ext_v6t2
+ mnCEF(vmla,     _vmla,    3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
+ mnCEF(vmul,     _vmul,    3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
 
  mcCE(fcpyd,	eb00b40, 2, (RVD, RVD),	      vfp_dp_rd_rm),
 
@@ -24664,6 +24729,8 @@ static const struct asm_opcode insns[] =
  MNUF(vhsub,     00000200,	  3, (RNDQMQ, oRNDQMQ, RNDQMQR),  neon_dyadic_i_su),
  mnUF(vmin,      _vmin,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
  mnUF(vmax,      _vmax,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
+ MNUF(vqadd,     0000010,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
+ MNUF(vqsub,     0000210,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vmla-bad.d b/gas/testsuite/gas/arm/mve-vmla-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..a5bc0634cffe01d2275318afb9d54ccb19592ff1
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmla-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLA instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmla-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmla-bad.l b/gas/testsuite/gas/arm/mve-vmla-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..12ed8f17abe0b7a1fc5b0072dd6ff6de08737c66
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmla-bad.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmla.f16 q0,q1,r2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmla.s64 q0,q1,r2'
+[^:]*:12: Error: selected FPU does not support instruction -- `vmla.s32 q0,q1,q2'
+[^:]*:13: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:14: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*: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 -- `vmlaeq.u16 q0,q1,r2'
+[^:]*:18: Error: syntax error -- `vmlaeq.u16 q0,q1,r2'
+[^:]*:20: Error: syntax error -- `vmlaeq.u16 q0,q1,r2'
+[^:]*:21: Error: vector predicated instruction should be in VPT/VPST block -- `vmlat.u16 q0,q1,r2'
+[^:]*:23: Error: instruction missing MVE vector predication code -- `vmla.u16 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vmla-bad.s b/gas/testsuite/gas/arm/mve-vmla-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..65de902fea4877a31d95b2803c5c7dbad1fe83f3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmla-bad.s
@@ -0,0 +1,23 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmla.s16 q0, q1, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmla.f16 q0, q1, r2
+vmla.s64 q0, q1, r2
+vmla.s32 q0, q1, q2
+vmla.s32 q0, q1, sp
+vmla.s32 q0, q1, pc
+cond
+it eq
+vmlaeq.u16 q0, q1, r2
+vmlaeq.u16 q0, q1, r2
+vpst
+vmlaeq.u16 q0, q1, r2
+vmlat.u16 q0, q1, r2
+vpst
+vmla.u16 q0, q1, r2
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-1.d b/gas/testsuite/gas/arm/mve-vmul-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..1e3dc46b8650036990c3dafb53045f0a2c7e9130
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMUL instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmul-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-1.l b/gas/testsuite/gas/arm/mve-vmul-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..88a86caf45feb6f74a09b8be9293c72476acd68f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-1.l
@@ -0,0 +1,31 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: selected FPU does not support instruction -- `vmul.f16 q0,q1,q2'
+[^:]*:11: Error: selected FPU does not support instruction -- `vmul.f16 q0,q1,r2'
+[^:]*:12: Error: selected FPU does not support instruction -- `vmul.f32 q0,q1,q2'
+[^:]*:13: Error: selected FPU does not support instruction -- `vmul.f32 q0,q1,r2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vmul.i64 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vmul.i64 q0,q1,r2'
+[^:]*:16: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:17: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Error: syntax error -- `vmuleq.i32 q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vmuleq.i32 q0,q1,q2'
+[^:]*:24: Error: syntax error -- `vmuleq.i32 q0,q1,q2'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vmult.i32 q0,q1,q2'
+[^:]*:27: Error: instruction missing MVE vector predication code -- `vmul.i32 q0,q1,q2'
+[^:]*:29: Error: syntax error -- `vmuleq.i32 q0,q1,r2'
+[^:]*:30: Error: syntax error -- `vmuleq.i32 q0,q1,r2'
+[^:]*:32: Error: syntax error -- `vmuleq.i32 q0,q1,r2'
+[^:]*:33: Error: vector predicated instruction should be in VPT/VPST block -- `vmult.i32 q0,q1,r2'
+[^:]*:35: Error: instruction missing MVE vector predication code -- `vmul.i32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-1.s b/gas/testsuite/gas/arm/mve-vmul-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..7897a1ab1037b28907de6c92f1c451f1eed2dd9f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-1.s
@@ -0,0 +1,35 @@
+.macro cond lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmul.i16 q0, q1, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmul.f16 q0, q1, q2
+vmul.f16 q0, q1, r2
+vmul.f32 q0, q1, q2
+vmul.f32 q0, q1, r2
+vmul.i64 q0, q1, q2
+vmul.i64 q0, q1, r2
+vmul.i8 q0, q1, pc
+vmul.i8 q0, q1, sp
+cond q2
+cond r2
+it eq
+vmuleq.i32 q0, q1, q2
+vmuleq.i32 q0, q1, q2
+vpst
+vmuleq.i32 q0, q1, q2
+vmult.i32 q0, q1, q2
+vpst
+vmul.i32 q0, q1, q2
+it eq
+vmuleq.i32 q0, q1, r2
+vmuleq.i32 q0, q1, r2
+vpst
+vmuleq.i32 q0, q1, r2
+vmult.i32 q0, q1, r2
+vpst
+vmul.i32 q0, q1, r2
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-2.d b/gas/testsuite/gas/arm/mve-vmul-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..27e639956e2d969a41691beba523a5f287325d5b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VMUL instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmul-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-2.l b/gas/testsuite/gas/arm/mve-vmul-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..a804da8be25f5ca508fb1a4b127d3bb0b9950bdc
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-2.l
@@ -0,0 +1,47 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmul.f64 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmul.f64 q0,q1,r2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vmul.i64 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vmul.i64 q0,q1,r2'
+[^:]*:14: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:15: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:16: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:18: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:20: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:21: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vmuleq.f16 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vmuleq.f16 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vmuleq.f16 q0,q1,q2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vmult.f16 q0,q1,q2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vmul.f16 q0,q1,q2'
+[^:]*:35: Error: syntax error -- `vmuleq.f32 q0,q1,r2'
+[^:]*:36: Error: syntax error -- `vmuleq.f32 q0,q1,r2'
+[^:]*:38: Error: syntax error -- `vmuleq.f32 q0,q1,r2'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vmult.f32 q0,q1,r2'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vmul.f32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vmul-bad-2.s b/gas/testsuite/gas/arm/mve-vmul-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..b5ed4ebff02853ace6030242a413dfe5fd9b0053
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmul-bad-2.s
@@ -0,0 +1,41 @@
+.macro cond size, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmul.\size q0, q1, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmul.f64 q0, q1, q2
+vmul.f64 q0, q1, r2
+vmul.i64 q0, q1, q2
+vmul.i64 q0, q1, r2
+vmul.f16 q0, q1, pc
+vmul.f16 q0, q1, pc
+vmul.f16 q0, q1, sp
+vmul.f16 q0, q1, sp
+vmul.i32 q0, q1, pc
+vmul.i32 q0, q1, pc
+vmul.i32 q0, q1, sp
+vmul.i32 q0, q1, sp
+cond i8 q2
+cond i16 r2
+cond f16 q2
+cond f32 r2
+it eq
+vmuleq.f16 q0, q1, q2
+vmuleq.f16 q0, q1, q2
+vpst
+vmuleq.f16 q0, q1, q2
+vmult.f16 q0, q1, q2
+vpst
+vmul.f16 q0, q1, q2
+it eq
+vmuleq.f32 q0, q1, r2
+vmuleq.f32 q0, q1, r2
+vpst
+vmuleq.f32 q0, q1, r2
+vmult.f32 q0, q1, r2
+vpst
+vmul.f32 q0, q1, r2
diff --git a/gas/testsuite/gas/arm/mve-vqaddsub-bad.d b/gas/testsuite/gas/arm/mve-vqaddsub-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..f37595e49055486c10a5b0f71e8f45e90373b775
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqaddsub-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQADD and VQSUB instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqaddsub-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqaddsub-bad.l b/gas/testsuite/gas/arm/mve-vqaddsub-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..1869371c0c9bf215496aab815e35e7e66ecf2ac8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqaddsub-bad.l
@@ -0,0 +1,57 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqadd.s64 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqsub.u64 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqadd.s64 q0,q1,r2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vqsub.s64 q0,q1,r2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vqadd.f32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqsub.f32 q0,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqadd.f32 q0,q1,r2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vqsub.f32 q0,q1,r2'
+[^:]*:18: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:20: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:21: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vqaddeq.s32 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vqaddeq.s32 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vqaddeq.s32 q0,q1,q2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vqaddt.s32 q0,q1,q2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vqadd.s32 q0,q1,q2'
+[^:]*:35: Error: syntax error -- `vqsubeq.s32 q0,q1,q2'
+[^:]*:36: Error: syntax error -- `vqsubeq.s32 q0,q1,q2'
+[^:]*:38: Error: syntax error -- `vqsubeq.s32 q0,q1,q2'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vqsubt.s32 q0,q1,q2'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vqsub.s32 q0,q1,q2'
+[^:]*:43: Error: syntax error -- `vqaddeq.s32 q0,q1,r2'
+[^:]*:44: Error: syntax error -- `vqaddeq.s32 q0,q1,r2'
+[^:]*:46: Error: syntax error -- `vqaddeq.s32 q0,q1,r2'
+[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vqaddt.s32 q0,q1,r2'
+[^:]*:49: Error: instruction missing MVE vector predication code -- `vqadd.s32 q0,q1,r2'
+[^:]*:51: Error: syntax error -- `vqsubeq.s32 q0,q1,r2'
+[^:]*:52: Error: syntax error -- `vqsubeq.s32 q0,q1,r2'
+[^:]*:54: Error: syntax error -- `vqsubeq.s32 q0,q1,r2'
+[^:]*:55: Error: vector predicated instruction should be in VPT/VPST block -- `vqsubt.s32 q0,q1,r2'
+[^:]*:57: Error: instruction missing MVE vector predication code -- `vqsub.s32 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vqaddsub-bad.s b/gas/testsuite/gas/arm/mve-vqaddsub-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..d5303173c6c940834940206739257c8a08e83965
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqaddsub-bad.s
@@ -0,0 +1,57 @@
+.macro cond op, lastop
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, \lastop
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqadd.s64 q0, q1, q2
+vqsub.u64 q0, q1, q2
+vqadd.s64 q0, q1, r2
+vqsub.s64 q0, q1, r2
+vqadd.f32 q0, q1, q2
+vqsub.f32 q0, q1, q2
+vqadd.f32 q0, q1, r2
+vqsub.f32 q0, q1, r2
+vqadd.s16 q0, q1, sp
+vqadd.s16 q0, q1, pc
+vqsub.s16 q0, q1, sp
+vqsub.s16 q0, q1, pc
+cond vqadd q2
+cond vqadd r2
+cond vqsub q2
+cond vqsub r2
+it eq
+vqaddeq.s32 q0, q1, q2
+vqaddeq.s32 q0, q1, q2
+vpst
+vqaddeq.s32 q0, q1, q2
+vqaddt.s32 q0, q1, q2
+vpst
+vqadd.s32 q0, q1, q2
+it eq
+vqsubeq.s32 q0, q1, q2
+vqsubeq.s32 q0, q1, q2
+vpst
+vqsubeq.s32 q0, q1, q2
+vqsubt.s32 q0, q1, q2
+vpst
+vqsub.s32 q0, q1, q2
+it eq
+vqaddeq.s32 q0, q1, r2
+vqaddeq.s32 q0, q1, r2
+vpst
+vqaddeq.s32 q0, q1, r2
+vqaddt.s32 q0, q1, r2
+vpst
+vqadd.s32 q0, q1, r2
+it eq
+vqsubeq.s32 q0, q1, r2
+vqsubeq.s32 q0, q1, r2
+vpst
+vqsubeq.s32 q0, q1, r2
+vqsubt.s32 q0, q1, r2
+vpst
+vqsub.s32 q0, q1, r2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 24/57][Arm][GAS] Add support for MVE instructions: vmlas, vmulh and vrmulh
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (22 preceding siblings ...)
  2019-05-01 17:15 ` [PATCH 23/57][Arm][GAS] Add support for MVE instructions: vmla, vmul, vqadd and vqsub Andre Vieira (lists)
@ 2019-05-01 17:16 ` Andre Vieira (lists)
  2019-05-01 17:17 ` [PATCH 25/57][Arm][GAS] Add support for MVE instruction: vmvn, vqabs and vqneg Andre Vieira (lists)
                   ` (36 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:16 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

Hi,

This patch adds support for MVE instructions VMLAS, VMULH, and VRMULH.


gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vmlas): New encoding function.
	(do_mve_vmulh): Likewise.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vmlas-bad.d: New test.
	* testsuite/gas/arm/mve-vmlas-bad.l: New test.
	* testsuite/gas/arm/mve-vmlas-bad.s: New test.
	* testsuite/gas/arm/mve-vmulh-bad.d: New test.
	* testsuite/gas/arm/mve-vmulh-bad.l: New test.
	* testsuite/gas/arm/mve-vmulh-bad.s: New test.

[-- Attachment #2: 24.patch --]
[-- Type: text/x-patch, Size: 8067 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index dd02a8e5a790f170d1f87ae1c36dd5e7e5a4827a..1819b7bf078721aecd44a7a4c429b357b478657b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15707,6 +15707,33 @@ do_mve_viddup (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vmlas (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
+  if (inst.operands[2].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+  else if (inst.operands[2].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= neon_logbits (et.size) << 20;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 7;
+  inst.instruction |= inst.operands[2].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vmaxnma_vminnma (void)
 {
@@ -17238,6 +17265,21 @@ do_mve_vsbc (void)
   mve_encode_qqq (1, 64);
 }
 
+static void
+do_mve_vmulh (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_qqq (et.type == NT_unsigned, et.size);
+}
+
 static void
 do_mve_vmull (void)
 {
@@ -24652,6 +24694,10 @@ static const struct asm_opcode insns[] =
  mCEF(vrmlsldavhx,  _vrmlsldavhx,  4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
  mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ),  mve_vrmlaldavh),
 
+ mToC("vmlas",	  ee011e40,	3, (RMQ, RMQ, RR),		mve_vmlas),
+ mToC("vmulh",	  ee010e01,	3, (RMQ, RMQ, RMQ),		mve_vmulh),
+ mToC("vrmulh",	  ee011e01,	3, (RMQ, RMQ, RMQ),		mve_vmulh),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vmlas-bad.d b/gas/testsuite/gas/arm/mve-vmlas-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..d33b1853628db5af044eea556e8005c56a409075
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlas-bad.d
@@ -0,0 +1,5 @@
+#name: Bad MVE VMLAS instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vmlas-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmlas-bad.l b/gas/testsuite/gas/arm/mve-vmlas-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..3a06f32f636331a73ae150a5a62bd51b4360122d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlas-bad.l
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmlas.s64 q0,q1,r2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmlas.f32 q0,q1,r2'
+[^:]*:12: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:13: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: syntax error -- `vmlaseq.s16 q0,q1,r2'
+[^:]*:17: Error: syntax error -- `vmlaseq.s16 q0,q1,r2'
+[^:]*:19: Error: syntax error -- `vmlaseq.s16 q0,q1,r2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vmlast.s16 q0,q1,r2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vmlas.s16 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vmlas-bad.s b/gas/testsuite/gas/arm/mve-vmlas-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..5eff30e4f38aed6a3d970b9f0fa7d7f96eae468f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmlas-bad.s
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmlas.s16 q0, q1, r2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmlas.s64 q0, q1, r2
+vmlas.f32 q0, q1, r2
+vmlas.u32 q0, q1, sp
+vmlas.u32 q0, q1, pc
+cond
+it eq
+vmlaseq.s16 q0, q1, r2
+vmlaseq.s16 q0, q1, r2
+vpst
+vmlaseq.s16 q0, q1, r2
+vmlast.s16 q0, q1, r2
+vpst
+vmlas.s16 q0, q1, r2
diff --git a/gas/testsuite/gas/arm/mve-vmulh-bad.d b/gas/testsuite/gas/arm/mve-vmulh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..febf2812545e7901a0021f1220c0a78d8749a7d0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmulh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMULH and VRMULH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmulh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmulh-bad.l b/gas/testsuite/gas/arm/mve-vmulh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..7e3c01b38f94f36c69d208110c0a8b51f79c4893
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmulh-bad.l
@@ -0,0 +1,29 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vmulh.f16 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vmulh.i32 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vmulh.s64 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrmulh.f16 q0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vrmulh.i32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vrmulh.s64 q0,q1,q2'
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vmulheq.s16 q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vmulheq.s16 q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vmulheq.s16 q0,q1,q2'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vmulht.s16 q0,q1,q2'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vmulh.s16 q0,q1,q2'
+[^:]*:27: Error: syntax error -- `vrmulheq.s16 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vrmulheq.s16 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vrmulheq.s16 q0,q1,q2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vrmulht.s16 q0,q1,q2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vrmulh.s16 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vmulh-bad.s b/gas/testsuite/gas/arm/mve-vmulh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..84d3cceb87a21ff926e546daf05670fe6f22a39a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmulh-bad.s
@@ -0,0 +1,33 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().u16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmulh.f16 q0, q1, q2
+vmulh.i32 q0, q1, q2
+vmulh.s64 q0, q1, q2
+vrmulh.f16 q0, q1, q2
+vrmulh.i32 q0, q1, q2
+vrmulh.s64 q0, q1, q2
+cond vmulh
+cond vrmulh
+it eq
+vmulheq.s16 q0, q1, q2
+vmulheq.s16 q0, q1, q2
+vpst
+vmulheq.s16 q0, q1, q2
+vmulht.s16 q0, q1, q2
+vpst
+vmulh.s16 q0, q1, q2
+it eq
+vrmulheq.s16 q0, q1, q2
+vrmulheq.s16 q0, q1, q2
+vpst
+vrmulheq.s16 q0, q1, q2
+vrmulht.s16 q0, q1, q2
+vpst
+vrmulh.s16 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 26/57][Arm][GAS] Add support for MVE instructions: vpnot and vpsel
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (24 preceding siblings ...)
  2019-05-01 17:17 ` [PATCH 25/57][Arm][GAS] Add support for MVE instruction: vmvn, vqabs and vqneg Andre Vieira (lists)
@ 2019-05-01 17:17 ` Andre Vieira (lists)
  2019-05-01 17:18 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (34 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:17 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 566 bytes --]

Hi,

This patch adds support for MVE instructions VPNOT and VPSEL.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vpsel): New encoding function.
	(do_mve_vpnot): Likewise.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vpnot-bad.d: New test.
	* testsuite/gas/arm/mve-vpnot-bad.l: New test.
	* testsuite/gas/arm/mve-vpnot-bad.s: New test.
	* testsuite/gas/arm/mve-vpsel-bad.d: New test.
	* testsuite/gas/arm/mve-vpsel-bad.l: New test.
	* testsuite/gas/arm/mve-vpsel-bad.s: New test.

[-- Attachment #2: 26.patch --]
[-- Type: text/x-patch, Size: 5329 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 4615f10246ca227257d76962a0e86557d9d9186f..b5c263688134bcd733c5ba8f93fe003268859abd 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15734,6 +15734,34 @@ do_mve_vmlas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vpsel (void)
+{
+  neon_select_shape (NS_QQQ, NS_NULL);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  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) << 7;
+  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[2].reg);
+  inst.is_neon = 1;
+}
+
+static void
+do_mve_vpnot (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+}
+
 static void
 do_mve_vmaxnma_vminnma (void)
 {
@@ -24715,6 +24743,8 @@ static const struct asm_opcode insns[] =
  mToC("vmlas",	  ee011e40,	3, (RMQ, RMQ, RR),		mve_vmlas),
  mToC("vmulh",	  ee010e01,	3, (RMQ, RMQ, RMQ),		mve_vmulh),
  mToC("vrmulh",	  ee011e01,	3, (RMQ, RMQ, RMQ),		mve_vmulh),
+ mToC("vpnot",	  fe310f4d,	0, (),				mve_vpnot),
+ mToC("vpsel",	  fe310f01,	3, (RMQ, RMQ, RMQ),		mve_vpsel),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
diff --git a/gas/testsuite/gas/arm/mve-vpnot-bad.d b/gas/testsuite/gas/arm/mve-vpnot-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6aab2c47c1ddf3102ed172efad8d70c2fe98a4f8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpnot-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VPNOT instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vpnot-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpnot-bad.l b/gas/testsuite/gas/arm/mve-vpnot-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..2ba96c6ddda767f039586f6117243dce78fc2bad
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpnot-bad.l
@@ -0,0 +1,12 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Error: syntax error -- `vpnoteq'
+[^:]*:13: Error: syntax error -- `vpnoteq'
+[^:]*:15: Error: syntax error -- `vpnoteq'
+[^:]*:16: Error: vector predicated instruction should be in VPT/VPST block -- `vpnott'
+[^:]*:18: Error: instruction missing MVE vector predication code -- `vpnot'
diff --git a/gas/testsuite/gas/arm/mve-vpnot-bad.s b/gas/testsuite/gas/arm/mve-vpnot-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..3588f60bda8db2327ce55220072cd8a6836423bd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpnot-bad.s
@@ -0,0 +1,18 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vpnot
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+it eq
+vpnoteq
+vpnoteq
+vpst
+vpnoteq
+vpnott
+vpst
+vpnot
diff --git a/gas/testsuite/gas/arm/mve-vpsel-bad.d b/gas/testsuite/gas/arm/mve-vpsel-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..b8a602a6b1d03bf87765d09d382ccc20288d7c84
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpsel-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VPSEL instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vpsel-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpsel-bad.l b/gas/testsuite/gas/arm/mve-vpsel-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..d2b2890d287669ace51675d20797f27cf7708eac
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpsel-bad.l
@@ -0,0 +1,12 @@
+[^:]*: Assembler messages:
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:10: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Error: syntax error -- `vpseleq.i16 q0,q1,q2'
+[^:]*:13: Error: syntax error -- `vpseleq.i16 q0,q1,q2'
+[^:]*:15: Error: syntax error -- `vpseleq.i16 q0,q1,q2'
+[^:]*:16: Error: vector predicated instruction should be in VPT/VPST block -- `vpselt.i16 q0,q1,q2'
+[^:]*:18: Error: instruction missing MVE vector predication code -- `vpsel.i16 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vpsel-bad.s b/gas/testsuite/gas/arm/mve-vpsel-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..fc14fdc3d316c2869c3fe8b0295a05dbbc22f664
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpsel-bad.s
@@ -0,0 +1,19 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vpsel.i16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond
+it eq
+vpseleq.i16 q0, q1, q2
+vpseleq.i16 q0, q1, q2
+vpst
+vpseleq.i16 q0, q1, q2
+vpselt.i16 q0, q1, q2
+vpst
+vpsel.i16 q0, q1, q2
+

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 25/57][Arm][GAS] Add support for MVE instruction: vmvn, vqabs and vqneg
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (23 preceding siblings ...)
  2019-05-01 17:16 ` [PATCH 24/57][Arm][GAS] Add support for MVE instructions: vmlas, vmulh and vrmulh Andre Vieira (lists)
@ 2019-05-01 17:17 ` Andre Vieira (lists)
  2019-05-01 17:17 ` [PATCH 26/57][Arm][GAS] Add support for MVE instructions: vpnot and vpsel Andre Vieira (lists)
                   ` (35 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:17 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 581 bytes --]

Hi,

This patch adds support for MVE instructions VMVN, VQABS, and VQNEG.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_neon_mvn): Change to accept MVE
         variants.
	(do_neon_sat_abs_neg): Likewise.
         (insns): Likewise.
	* testsuite/gas/arm/mve-vmvn-bad.d: New test.
	* testsuite/gas/arm/mve-vmvn-bad.l: New test.
	* testsuite/gas/arm/mve-vmvn-bad.s: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.d: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.l: New test.
	* testsuite/gas/arm/mve-vqabsneg-bad.s: New test.

[-- Attachment #2: 25.patch --]
[-- Type: text/x-patch, Size: 8927 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1819b7bf078721aecd44a7a4c429b357b478657b..4615f10246ca227257d76962a0e86557d9d9186f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -18489,9 +18489,16 @@ neon_move_immediate (void)
 static void
 do_neon_mvn (void)
 {
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+    return;
+
   if (inst.operands[1].isreg)
     {
-      enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+      enum neon_shape rs;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	rs = neon_select_shape (NS_QQ, NS_NULL);
+      else
+	rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
 
       NEON_ENCODE (INTEGER, inst);
       inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
@@ -18507,6 +18514,13 @@ do_neon_mvn (void)
     }
 
   neon_dp_fixup (&inst);
+
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    {
+      constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
+      constraint ((inst.instruction & 0xd00) == 0xd00,
+		  _("immediate value out of range"));
+    }
 }
 
 /* Encode instructions of form:
@@ -19453,7 +19467,14 @@ do_neon_zip_uzp (void)
 static void
 do_neon_sat_abs_neg (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+    return;
+
+  enum neon_shape rs;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    rs = neon_select_shape (NS_QQ, NS_NULL);
+  else
+    rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
   struct neon_type_el et = neon_check_type (2, rs,
     N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
   neon_two_same (neon_quad (rs), 1, et.size);
@@ -24060,7 +24081,6 @@ static const struct asm_opcode insns[] =
   /* CVT with optional immediate for fixed-point variant.  */
  nUF(vcvtq,     _vcvt,    3, (RNQ, RNQ, oI32b), neon_cvt),
 
- nUF(vmvn,      _vmvn,    2, (RNDQ, RNDQ_Ibig), neon_mvn),
  nUF(vmvnq,     _vmvn,    2, (RNQ,  RNDQ_Ibig), neon_mvn),
 
   /* Data processing, three registers of different lengths.  */
@@ -24114,9 +24134,7 @@ static const struct asm_opcode insns[] =
  NUF(vuzp,      1b20100, 2, (RNDQ, RNDQ),     neon_zip_uzp),
  NUF(vuzpq,     1b20100, 2, (RNQ,  RNQ),      neon_zip_uzp),
   /* VQABS / VQNEG. Types S8 S16 S32.  */
- NUF(vqabs,     1b00700, 2, (RNDQ, RNDQ),     neon_sat_abs_neg),
  NUF(vqabsq,    1b00700, 2, (RNQ,  RNQ),      neon_sat_abs_neg),
- NUF(vqneg,     1b00780, 2, (RNDQ, RNDQ),     neon_sat_abs_neg),
  NUF(vqnegq,    1b00780, 2, (RNQ,  RNQ),      neon_sat_abs_neg),
   /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32.  */
  NUF(vpadal,    1b00600, 2, (RNDQ, RNDQ),     neon_pair_long),
@@ -24777,6 +24795,9 @@ static const struct asm_opcode insns[] =
  mnUF(vmax,      _vmax,    3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
  MNUF(vqadd,     0000010,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
  MNUF(vqsub,     0000210,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
+ mnUF(vmvn,      _vmvn,    2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
+ MNUF(vqabs,     1b00700,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
+ MNUF(vqneg,     1b00780,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.d b/gas/testsuite/gas/arm/mve-vmvn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..3b06d63fcc1b807c81ea2bb7312cb8677187c73e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VMVN instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vmvn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.l b/gas/testsuite/gas/arm/mve-vmvn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..8073a68ea80cfc39a6d92dba7637fc174de47be2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.l
@@ -0,0 +1,20 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: invalid instruction shape -- `vmvn.i16 d0,d1'
+[^:]*:11: Error: immediate out of range -- `vmvn.i32 q0,#0x1ef'
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:12: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:16: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:18: Error: syntax error -- `vmvneq q0,q1'
+[^:]*:19: Error: vector predicated instruction should be in VPT/VPST block -- `vmvnt q0,q1'
+[^:]*:21: Error: instruction missing MVE vector predication code -- `vmvn q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vmvn-bad.s b/gas/testsuite/gas/arm/mve-vmvn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..5b8f127abf1e57a45caabef0f888de4a84514a8a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vmvn-bad.s
@@ -0,0 +1,21 @@
+.macro cond lastop
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vmvn.i16 q0, \lastop
+.endr
+.endm
+
+.syntax unified
+.thumb
+vmvn.i16 d0, d1
+vmvn.i32 q0, #0x1ef
+cond q1
+cond #0
+it eq
+vmvneq q0, q1
+vmvneq q0, q1
+vpst
+vmvneq q0, q1
+vmvnt q0, q1
+vpst
+vmvn q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.d b/gas/testsuite/gas/arm/mve-vqabsneg-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..30c9cd6c6477c2584c597a9db7c4d49992b20d85
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQABS and VQNEG instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqabsneg-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.l b/gas/testsuite/gas/arm/mve-vqabsneg-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..ea9891e317cf80c319bda84389e3ee0cec41fb50
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqabs.u8 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqneg.u16 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqabs.s64 q0,q1'
+[^:]*:13: Error: bad instruction `vqnegs.s64 q0,q1'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:18: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:19: Error: syntax error -- `vqabseq.s32 q0,q1'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vqabst.s32 q0,q1'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vqabs.s32 q0,q1'
+[^:]*:24: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:25: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:26: Error: syntax error -- `vqnegeq.s32 q0,q1'
+[^:]*:27: Error: vector predicated instruction should be in VPT/VPST block -- `vqnegt.s32 q0,q1'
+[^:]*:29: Error: instruction missing MVE vector predication code -- `vqneg.s32 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vqabsneg-bad.s b/gas/testsuite/gas/arm/mve-vqabsneg-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..af760904b2489614df19508e3bae817b22ebec6a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqabsneg-bad.s
@@ -0,0 +1,29 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqabs.u8 q0, q1
+vqneg.u16 q0, q1
+vqabs.s64 q0, q1
+vqnegs.s64 q0, q1
+cond vqabs
+cond vqneg
+it eq
+vqabseq.s32 q0, q1
+vqabseq.s32 q0, q1
+vqabseq.s32 q0, q1
+vqabst.s32 q0, q1
+vpst
+vqabs.s32 q0, q1
+it eq
+vqnegeq.s32 q0, q1
+vqnegeq.s32 q0, q1
+vqnegeq.s32 q0, q1
+vqnegt.s32 q0, q1
+vpst
+vqneg.s32 q0, q1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (25 preceding siblings ...)
  2019-05-01 17:17 ` [PATCH 26/57][Arm][GAS] Add support for MVE instructions: vpnot and vpsel Andre Vieira (lists)
@ 2019-05-01 17:18 ` Andre Vieira (lists)
  2019-05-01 17:19 ` [PATCH 28/57][Arm][GAS] Add support for MVE instructions: vqdmlah, vqrdmlah, vqdmlash, vqrdmlash, vqdmulh and vqrdmulh Andre Vieira (lists)
                   ` (33 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:18 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 590 bytes --]

Hi,

This patch adds support for MVE instructions VQDMLADH, VQRDMLADH, 
VQDMLSDH, and VQRDMLSDH.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vqdmladh): New encoding function.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vqdmladh-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmladh-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmladh-bad.s: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.s: New test.

[-- Attachment #2: 27.patch --]
[-- Type: text/x-patch, Size: 15386 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b5c263688134bcd733c5ba8f93fe003268859abd..abe37b72eacd9c2b4ea2fae113dcd9ab339cb2f5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -17308,6 +17308,28 @@ do_mve_vmulh (void)
   mve_encode_qqq (et.type == NT_unsigned, et.size);
 }
 
+
+static void
+do_mve_vqdmladh (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQQ, 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;
+
+  if (et.size == 32
+      && (inst.operands[0].reg == inst.operands[1].reg
+	  || inst.operands[0].reg == inst.operands[2].reg))
+    as_tsktsk (BAD_MVE_SRCDEST);
+
+  mve_encode_qqq (0, et.size);
+}
+
+
 static void
 do_mve_vmull (void)
 {
@@ -24746,6 +24768,15 @@ static const struct asm_opcode insns[] =
  mToC("vpnot",	  fe310f4d,	0, (),				mve_vpnot),
  mToC("vpsel",	  fe310f01,	3, (RMQ, RMQ, RMQ),		mve_vpsel),
 
+ mToC("vqdmladh",  ee000e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmladhx", ee001e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmladh", ee000e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmladhx",ee001e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmlsdh",  fe000e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmlsdhx", fe001e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmlsdh", fe000e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmlsdhx",fe001e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.d b/gas/testsuite/gas/arm/mve-vqdmladh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..5d37855f075011e8c19deab4e42007cb9e15ad3f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMLADH and VQRDMLADH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmladh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.l b/gas/testsuite/gas/arm/mve-vqdmladh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..96057b8daf64b113188c4b1411372d71d4606f97
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmladh.u32 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmladh.s64 q0,q1,q2'
+[^:]*:12: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:13: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmladhx.u32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmladhx.s64 q0,q1,q2'
+[^:]*:16: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:17: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:18: Error: bad type in SIMD instruction -- `vqrdmladh.u32 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqrdmladh.s64 q0,q1,q2'
+[^:]*:20: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:21: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:22: Error: bad type in SIMD instruction -- `vqrdmladhx.u32 q0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqrdmladhx.s64 q0,q1,q2'
+[^:]*:24: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:25: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*: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 -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:32: Error: syntax error -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:34: Error: syntax error -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmladht.s32 q0,q1,q2'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vqdmladh.s32 q0,q1,q2'
+[^:]*:39: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:40: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmladhxt.s32 q0,q1,q2'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vqdmladhx.s32 q0,q1,q2'
+[^:]*:47: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:48: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:50: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmladht.s32 q0,q1,q2'
+[^:]*:53: Error: instruction missing MVE vector predication code -- `vqrdmladh.s32 q0,q1,q2'
+[^:]*:55: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:56: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:58: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmladhxt.s32 q0,q1,q2'
+[^:]*:61: Error: instruction missing MVE vector predication code -- `vqrdmladhx.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.s b/gas/testsuite/gas/arm/mve-vqdmladh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..7cedb3934b7247e336695caddd792509099073fd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.s
@@ -0,0 +1,61 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmladh.u32 q0, q1, q2
+vqdmladh.s64 q0, q1, q2
+vqdmladh.s32 q0, q0, q2
+vqdmladh.s32 q0, q1, q0
+vqdmladhx.u32 q0, q1, q2
+vqdmladhx.s64 q0, q1, q2
+vqdmladhx.s32 q0, q0, q2
+vqdmladhx.s32 q0, q1, q0
+vqrdmladh.u32 q0, q1, q2
+vqrdmladh.s64 q0, q1, q2
+vqrdmladh.s32 q0, q0, q2
+vqrdmladh.s32 q0, q1, q0
+vqrdmladhx.u32 q0, q1, q2
+vqrdmladhx.s64 q0, q1, q2
+vqrdmladhx.s32 q0, q0, q2
+vqrdmladhx.s32 q0, q1, q0
+cond vqdmladh
+cond vqdmladhx
+cond vqrdmladh
+cond vqrdmladhx
+it eq
+vqdmladheq.s32 q0, q1, q2
+vqdmladheq.s32 q0, q1, q2
+vpst
+vqdmladheq.s32 q0, q1, q2
+vqdmladht.s32 q0, q1, q2
+vpst
+vqdmladh.s32 q0, q1, q2
+it eq
+vqdmladhxeq.s32 q0, q1, q2
+vqdmladhxeq.s32 q0, q1, q2
+vpst
+vqdmladhxeq.s32 q0, q1, q2
+vqdmladhxt.s32 q0, q1, q2
+vpst
+vqdmladhx.s32 q0, q1, q2
+it eq
+vqrdmladheq.s32 q0, q1, q2
+vqrdmladheq.s32 q0, q1, q2
+vpst
+vqrdmladheq.s32 q0, q1, q2
+vqrdmladht.s32 q0, q1, q2
+vpst
+vqrdmladh.s32 q0, q1, q2
+it eq
+vqrdmladhxeq.s32 q0, q1, q2
+vqrdmladhxeq.s32 q0, q1, q2
+vpst
+vqrdmladhxeq.s32 q0, q1, q2
+vqrdmladhxt.s32 q0, q1, q2
+vpst
+vqrdmladhx.s32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6da0050fa526bf150830e1f70ee41b6df1413dd0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMLSDH and VQRDMLSDH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmlsdh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..465476ccc1377d71aea25e42154cb87c6ac9e863
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmlsdh.u32 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmlsdh.s64 q0,q1,q2'
+[^:]*:12: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:13: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmlsdhx.u32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmlsdhx.s64 q0,q1,q2'
+[^:]*:16: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:17: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:18: Error: bad type in SIMD instruction -- `vqrdmlsdh.u32 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqrdmlsdh.s64 q0,q1,q2'
+[^:]*:20: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:21: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:22: Error: bad type in SIMD instruction -- `vqrdmlsdhx.u32 q0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqrdmlsdhx.s64 q0,q1,q2'
+[^:]*:24: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:25: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*: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 -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:32: Error: syntax error -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:34: Error: syntax error -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmlsdht.s32 q0,q1,q2'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vqdmlsdh.s32 q0,q1,q2'
+[^:]*:39: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:40: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmlsdhxt.s32 q0,q1,q2'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vqdmlsdhx.s32 q0,q1,q2'
+[^:]*:47: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:48: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:50: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmlsdht.s32 q0,q1,q2'
+[^:]*:53: Error: instruction missing MVE vector predication code -- `vqrdmlsdh.s32 q0,q1,q2'
+[^:]*:55: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:56: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:58: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmlsdhxt.s32 q0,q1,q2'
+[^:]*:61: Error: instruction missing MVE vector predication code -- `vqrdmlsdhx.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..4c047a9373aa4b2e6195f0de932117becefde092
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s
@@ -0,0 +1,61 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmlsdh.u32 q0, q1, q2
+vqdmlsdh.s64 q0, q1, q2
+vqdmlsdh.s32 q0, q0, q2
+vqdmlsdh.s32 q0, q1, q0
+vqdmlsdhx.u32 q0, q1, q2
+vqdmlsdhx.s64 q0, q1, q2
+vqdmlsdhx.s32 q0, q0, q2
+vqdmlsdhx.s32 q0, q1, q0
+vqrdmlsdh.u32 q0, q1, q2
+vqrdmlsdh.s64 q0, q1, q2
+vqrdmlsdh.s32 q0, q0, q2
+vqrdmlsdh.s32 q0, q1, q0
+vqrdmlsdhx.u32 q0, q1, q2
+vqrdmlsdhx.s64 q0, q1, q2
+vqrdmlsdhx.s32 q0, q0, q2
+vqrdmlsdhx.s32 q0, q1, q0
+cond vqdmlsdh
+cond vqdmlsdhx
+cond vqrdmlsdh
+cond vqrdmlsdhx
+it eq
+vqdmlsdheq.s32 q0, q1, q2
+vqdmlsdheq.s32 q0, q1, q2
+vpst
+vqdmlsdheq.s32 q0, q1, q2
+vqdmlsdht.s32 q0, q1, q2
+vpst
+vqdmlsdh.s32 q0, q1, q2
+it eq
+vqdmlsdhxeq.s32 q0, q1, q2
+vqdmlsdhxeq.s32 q0, q1, q2
+vpst
+vqdmlsdhxeq.s32 q0, q1, q2
+vqdmlsdhxt.s32 q0, q1, q2
+vpst
+vqdmlsdhx.s32 q0, q1, q2
+it eq
+vqrdmlsdheq.s32 q0, q1, q2
+vqrdmlsdheq.s32 q0, q1, q2
+vpst
+vqrdmlsdheq.s32 q0, q1, q2
+vqrdmlsdht.s32 q0, q1, q2
+vpst
+vqrdmlsdh.s32 q0, q1, q2
+it eq
+vqrdmlsdhxeq.s32 q0, q1, q2
+vqrdmlsdhxeq.s32 q0, q1, q2
+vpst
+vqrdmlsdhxeq.s32 q0, q1, q2
+vqrdmlsdhxt.s32 q0, q1, q2
+vpst
+vqrdmlsdhx.s32 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 28/57][Arm][GAS] Add support for MVE instructions: vqdmlah, vqrdmlah, vqdmlash, vqrdmlash, vqdmulh and vqrdmulh
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (26 preceding siblings ...)
  2019-05-01 17:18 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
@ 2019-05-01 17:19 ` Andre Vieira (lists)
  2019-05-01 17:30 ` [PATCH 27/57][Arm][GAS] Add support for MVE instructions: vqdmladh, vqrdmladh, vqdmlsdh and vqrdmlsdh Andre Vieira (lists)
                   ` (32 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:19 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

Hi,

This patch adds support for MVE instructions VQDMLAH, VQRDMLAH, 
VQDMLASH, VQRDMLASH, VQDMULH, and VQRDMULH

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): Add new operand.
	(parse_operands): Handle new operand.
	(mve_encode_qqr): Handle new instructions.
	(do_neon_qdmulh): Add support for MVE variants.
	(do_neon_qrdmlah): Likewise.
	(do_mve_vqdmlah): New encoding function.
         (insns): Change entries and add new entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vqdmulh-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmulh-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmulh-bad.s: New test.

[-- Attachment #2: 28.patch --]
[-- Type: text/x-patch, Size: 14318 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index abe37b72eacd9c2b4ea2fae113dcd9ab339cb2f5..a4b79dc9d4edf131608fe28a56c2d12080c59724 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6957,6 +6957,9 @@ enum operand_parse_code
   OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
 			  scalar, or ARM register.  */
   OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar.  */
+  OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register.  */
+  OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
+			register.  */
   OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar.  */
   OP_RND_RNSC,  /* Neon D reg, or Neon scalar.  */
   OP_VMOV,      /* Neon VMOV operands.  */
@@ -7361,6 +7364,13 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  }
 	  break;
 
+	case OP_RNDQMQ_RNSC_RR:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
+	  break;
+	try_rndq_rnsc_rr:
+	case OP_RNDQ_RNSC_RR:
+	  po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
+	  break;
 	case OP_RNDQMQ_RNSC:
 	  po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
 	  break;
@@ -15996,6 +16006,15 @@ mve_encode_qqr (int size, int U, int fp)
       /* vqsub.  */
       else if (((unsigned)inst.instruction) == 0x210)
 	inst.instruction = 0xee001f60;
+      /* vqrdmlah.  */
+      else if (((unsigned)inst.instruction) == 0x3000b10)
+	inst.instruction = 0xee000e40;
+      /* vqdmulh.  */
+      else if (((unsigned)inst.instruction) == 0x0000b00)
+	inst.instruction = 0xee010e60;
+      /* vqrdmulh.  */
+      else if (((unsigned)inst.instruction) == 0x1000b00)
+	inst.instruction = 0xfe010e60;
 
       /* Set U-bit.  */
       inst.instruction |= U << 28;
@@ -17184,8 +17203,12 @@ do_neon_mul (void)
 static void
 do_neon_qdmulh (void)
 {
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+   return;
+
   if (inst.operands[2].isscalar)
     {
+      constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
       enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
       struct neon_type_el et = neon_check_type (3, rs,
 	N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
@@ -17194,12 +17217,27 @@ do_neon_qdmulh (void)
     }
   else
     {
-      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_S16 | N_S32 | N_KEY);
+      enum neon_shape rs;
+      struct neon_type_el et;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
+	  et = neon_check_type (3, rs,
+	    N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
+	}
+      else
+	{
+	  rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+	  et = neon_check_type (3, rs,
+	    N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
+	}
+
       NEON_ENCODE (INTEGER, inst);
-      /* The U bit (rounding) comes from bit mask.  */
-      neon_three_same (neon_quad (rs), 0, et.size);
+      if (rs == NS_QQR)
+	mve_encode_qqr (et.size, 0, 0);
+      else
+	/* The U bit (rounding) comes from bit mask.  */
+	neon_three_same (neon_quad (rs), 0, et.size);
     }
 }
 
@@ -17308,6 +17346,20 @@ do_mve_vmulh (void)
   mve_encode_qqq (et.type == NT_unsigned, et.size);
 }
 
+static void
+do_mve_vqdmlah (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
+}
 
 static void
 do_mve_vqdmladh (void)
@@ -17559,32 +17611,45 @@ do_mve_vmaxv (void)
 static void
 do_neon_qrdmlah (void)
 {
-  /* Check we're on the correct architecture.  */
-  if (!mark_feature_used (&fpu_neon_ext_armv8))
-    inst.error =
-      _("instruction form not available on this architecture.");
-  else if (!mark_feature_used (&fpu_neon_ext_v8_1))
-    {
-      as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
-      record_feature_use (&fpu_neon_ext_v8_1);
-    }
-
-  if (inst.operands[2].isscalar)
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+   return;
+  if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
     {
-      enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
-      struct neon_type_el et = neon_check_type (3, rs,
-	N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
-      NEON_ENCODE (SCALAR, inst);
-      neon_mul_mac (et, neon_quad (rs));
+      /* Check we're on the correct architecture.  */
+      if (!mark_feature_used (&fpu_neon_ext_armv8))
+	inst.error
+	  = _("instruction form not available on this architecture.");
+      else if (!mark_feature_used (&fpu_neon_ext_v8_1))
+	{
+	  as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
+	  record_feature_use (&fpu_neon_ext_v8_1);
+	}
+	if (inst.operands[2].isscalar)
+	  {
+	    enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
+	    struct neon_type_el et = neon_check_type (3, rs,
+	      N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
+	    NEON_ENCODE (SCALAR, inst);
+	    neon_mul_mac (et, neon_quad (rs));
+	  }
+	else
+	  {
+	    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_S16 | N_S32 | N_KEY);
+	    NEON_ENCODE (INTEGER, inst);
+	    /* The U bit (rounding) comes from bit mask.  */
+	    neon_three_same (neon_quad (rs), 0, et.size);
+	  }
     }
   else
     {
-      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_S16 | N_S32 | N_KEY);
+      enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
+      struct neon_type_el et
+	= neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+
       NEON_ENCODE (INTEGER, inst);
-      /* The U bit (rounding) comes from bit mask.  */
-      neon_three_same (neon_quad (rs), 0, et.size);
+      mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
     }
 }
 
@@ -24071,9 +24136,7 @@ static const struct asm_opcode insns[] =
   /* VMUL takes I8 I16 I32 F32 P8.  */
  nUF(vmulq,     _vmul,     3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_mul),
   /* VQD{R}MULH takes S16 S32.  */
- nUF(vqdmulh,   _vqdmulh,  3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
  nUF(vqdmulhq,  _vqdmulh,  3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_qdmulh),
- nUF(vqrdmulh,  _vqrdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
  nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_qdmulh),
  NUF(vacge,     0000e10,  3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
  NUF(vacgeq,    0000e10,  3, (RNQ,  oRNQ,  RNQ),  neon_fcmp_absolute),
@@ -24088,7 +24151,6 @@ static const struct asm_opcode insns[] =
  NUF(vrsqrts,   0200f10,  3, (RNDQ, oRNDQ, RNDQ), neon_step),
  NUF(vrsqrtsq,  0200f10,  3, (RNQ,  oRNQ,  RNQ),  neon_step),
  /* ARM v8.1 extension.  */
- nUF (vqrdmlah,  _vqrdmlah, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
  nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_qrdmlah),
  nUF (vqrdmlsh,  _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
  nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ,  oRNQ,  RNDQ_RNSC), neon_qrdmlah),
@@ -24776,6 +24838,9 @@ static const struct asm_opcode insns[] =
  mToC("vqdmlsdhx", fe001e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
  mToC("vqrdmlsdh", fe000e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
  mToC("vqrdmlsdhx",fe001e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmlah",   ee000e60,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
+ mToC("vqdmlash",  ee001e60,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
+ mToC("vqrdmlash", ee001e40,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
@@ -24859,6 +24924,9 @@ static const struct asm_opcode insns[] =
  mnUF(vmvn,      _vmvn,    2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
  MNUF(vqabs,     1b00700,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
  MNUF(vqneg,     1b00780,  2, (RNDQMQ, RNDQMQ),     neon_sat_abs_neg),
+ mnUF(vqrdmlah,  _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
+ mnUF(vqdmulh,   _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
+ mnUF(vqrdmulh,  _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vqdmulh-bad.d b/gas/testsuite/gas/arm/mve-vqdmulh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..cdf63ba933e9d0d65ff8287b060f7fc358dc5f4b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmulh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMULH and VQRDMULH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmulh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmulh-bad.l b/gas/testsuite/gas/arm/mve-vqdmulh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..01e824efbf0a759c20ea32502f2856fdb6d2d4eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmulh-bad.l
@@ -0,0 +1,57 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmulh.s64 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmulh.u8 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqrdmulh.s64 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vqrdmulh.u8 q0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmulh.s64 q0,q1,r2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmulh.u8 q0,q1,r2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqrdmulh.s64 q0,q1,r2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vqrdmulh.u8 q0,q1,r2'
+[^:]*:18: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:20: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:21: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vqdmulheq.s8 q0,q1,q2'
+[^:]*:28: Error: syntax error -- `vqdmulheq.s8 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vqdmulheq.s8 q0,q1,q2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmulht.s8 q0,q1,q2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vqdmulh.s8 q0,q1,q2'
+[^:]*:35: Error: syntax error -- `vqrdmulheq.s8 q0,q1,q2'
+[^:]*:36: Error: syntax error -- `vqrdmulheq.s8 q0,q1,q2'
+[^:]*:38: Error: syntax error -- `vqrdmulheq.s8 q0,q1,q2'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmulht.s8 q0,q1,q2'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vqrdmulh.s8 q0,q1,q2'
+[^:]*:43: Error: syntax error -- `vqdmulheq.s8 q0,q1,r2'
+[^:]*:44: Error: syntax error -- `vqdmulheq.s8 q0,q1,r2'
+[^:]*:46: Error: syntax error -- `vqdmulheq.s8 q0,q1,r2'
+[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmulht.s8 q0,q1,r2'
+[^:]*:49: Error: instruction missing MVE vector predication code -- `vqdmulh.s8 q0,q1,r2'
+[^:]*:51: Error: syntax error -- `vqrdmulheq.s8 q0,q1,r2'
+[^:]*:52: Error: syntax error -- `vqrdmulheq.s8 q0,q1,r2'
+[^:]*:54: Error: syntax error -- `vqrdmulheq.s8 q0,q1,r2'
+[^:]*:55: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmulht.s8 q0,q1,r2'
+[^:]*:57: Error: instruction missing MVE vector predication code -- `vqrdmulh.s8 q0,q1,r2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmulh-bad.s b/gas/testsuite/gas/arm/mve-vqdmulh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..db44de6d4d25288b18067a7fdeac1f904d5b4ade
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmulh-bad.s
@@ -0,0 +1,57 @@
+.macro cond op, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmulh.s64 q0, q1, q2
+vqdmulh.u8 q0, q1, q2
+vqrdmulh.s64 q0, q1, q2
+vqrdmulh.u8 q0, q1, q2
+vqdmulh.s64 q0, q1, r2
+vqdmulh.u8 q0, q1, r2
+vqrdmulh.s64 q0, q1, r2
+vqrdmulh.u8 q0, q1, r2
+vqdmulh.s8 q0, q1, sp
+vqdmulh.s8 q0, q1, pc
+vqrdmulh.s8 q0, q1, sp
+vqrdmulh.s8 q0, q1, pc
+cond vqdmulh, q2
+cond vqrdmulh, q2
+cond vqdmulh, r2
+cond vqrdmulh, r2
+it eq
+vqdmulheq.s8 q0, q1, q2
+vqdmulheq.s8 q0, q1, q2
+vpst
+vqdmulheq.s8 q0, q1, q2
+vqdmulht.s8 q0, q1, q2
+vpst
+vqdmulh.s8 q0, q1, q2
+it eq
+vqrdmulheq.s8 q0, q1, q2
+vqrdmulheq.s8 q0, q1, q2
+vpst
+vqrdmulheq.s8 q0, q1, q2
+vqrdmulht.s8 q0, q1, q2
+vpst
+vqrdmulh.s8 q0, q1, q2
+it eq
+vqdmulheq.s8 q0, q1, r2
+vqdmulheq.s8 q0, q1, r2
+vpst
+vqdmulheq.s8 q0, q1, r2
+vqdmulht.s8 q0, q1, r2
+vpst
+vqdmulh.s8 q0, q1, r2
+it eq
+vqrdmulheq.s8 q0, q1, r2
+vqrdmulheq.s8 q0, q1, r2
+vpst
+vqrdmulheq.s8 q0, q1, r2
+vqrdmulht.s8 q0, q1, r2
+vpst
+vqrdmulh.s8 q0, q1, r2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 27/57][Arm][GAS] Add support for MVE instructions: vqdmladh, vqrdmladh, vqdmlsdh and vqrdmlsdh
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (27 preceding siblings ...)
  2019-05-01 17:19 ` [PATCH 28/57][Arm][GAS] Add support for MVE instructions: vqdmlah, vqrdmlah, vqdmlash, vqrdmlash, vqdmulh and vqrdmulh Andre Vieira (lists)
@ 2019-05-01 17:30 ` Andre Vieira (lists)
  2019-05-01 17:31 ` [PATCH 29/57][Arm][GAS] Add support for MVE instructions: vqdmullt and vqdmullb Andre Vieira (lists)
                   ` (31 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:30 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 700 bytes --]

(resending this one because I forgot to change the subject so its easier 
to find, ignore the duplicate one!)
Hi,

This patch adds support for MVE instructions VQDMLADH, VQRDMLADH, 
VQDMLSDH, and VQRDMLSDH.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vqdmladh): New encoding function.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vqdmladh-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmladh-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmladh-bad.s: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmlsdh-bad.s: New test.

[-- Attachment #2: 27.patch --]
[-- Type: text/x-patch, Size: 15386 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b5c263688134bcd733c5ba8f93fe003268859abd..abe37b72eacd9c2b4ea2fae113dcd9ab339cb2f5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -17308,6 +17308,28 @@ do_mve_vmulh (void)
   mve_encode_qqq (et.type == NT_unsigned, et.size);
 }
 
+
+static void
+do_mve_vqdmladh (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQQ, 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;
+
+  if (et.size == 32
+      && (inst.operands[0].reg == inst.operands[1].reg
+	  || inst.operands[0].reg == inst.operands[2].reg))
+    as_tsktsk (BAD_MVE_SRCDEST);
+
+  mve_encode_qqq (0, et.size);
+}
+
+
 static void
 do_mve_vmull (void)
 {
@@ -24746,6 +24768,15 @@ static const struct asm_opcode insns[] =
  mToC("vpnot",	  fe310f4d,	0, (),				mve_vpnot),
  mToC("vpsel",	  fe310f01,	3, (RMQ, RMQ, RMQ),		mve_vpsel),
 
+ mToC("vqdmladh",  ee000e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmladhx", ee001e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmladh", ee000e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmladhx",ee001e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmlsdh",  fe000e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqdmlsdhx", fe001e00,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmlsdh", fe000e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+ mToC("vqrdmlsdhx",fe001e01,	3, (RMQ, RMQ, RMQ),		mve_vqdmladh),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.d b/gas/testsuite/gas/arm/mve-vqdmladh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..5d37855f075011e8c19deab4e42007cb9e15ad3f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMLADH and VQRDMLADH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmladh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.l b/gas/testsuite/gas/arm/mve-vqdmladh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..96057b8daf64b113188c4b1411372d71d4606f97
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmladh.u32 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmladh.s64 q0,q1,q2'
+[^:]*:12: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:13: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmladhx.u32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmladhx.s64 q0,q1,q2'
+[^:]*:16: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:17: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:18: Error: bad type in SIMD instruction -- `vqrdmladh.u32 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqrdmladh.s64 q0,q1,q2'
+[^:]*:20: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:21: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:22: Error: bad type in SIMD instruction -- `vqrdmladhx.u32 q0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqrdmladhx.s64 q0,q1,q2'
+[^:]*:24: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:25: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*: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 -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:32: Error: syntax error -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:34: Error: syntax error -- `vqdmladheq.s32 q0,q1,q2'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmladht.s32 q0,q1,q2'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vqdmladh.s32 q0,q1,q2'
+[^:]*:39: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:40: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqdmladhxeq.s32 q0,q1,q2'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmladhxt.s32 q0,q1,q2'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vqdmladhx.s32 q0,q1,q2'
+[^:]*:47: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:48: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:50: Error: syntax error -- `vqrdmladheq.s32 q0,q1,q2'
+[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmladht.s32 q0,q1,q2'
+[^:]*:53: Error: instruction missing MVE vector predication code -- `vqrdmladh.s32 q0,q1,q2'
+[^:]*:55: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:56: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:58: Error: syntax error -- `vqrdmladhxeq.s32 q0,q1,q2'
+[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmladhxt.s32 q0,q1,q2'
+[^:]*:61: Error: instruction missing MVE vector predication code -- `vqrdmladhx.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmladh-bad.s b/gas/testsuite/gas/arm/mve-vqdmladh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..7cedb3934b7247e336695caddd792509099073fd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmladh-bad.s
@@ -0,0 +1,61 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmladh.u32 q0, q1, q2
+vqdmladh.s64 q0, q1, q2
+vqdmladh.s32 q0, q0, q2
+vqdmladh.s32 q0, q1, q0
+vqdmladhx.u32 q0, q1, q2
+vqdmladhx.s64 q0, q1, q2
+vqdmladhx.s32 q0, q0, q2
+vqdmladhx.s32 q0, q1, q0
+vqrdmladh.u32 q0, q1, q2
+vqrdmladh.s64 q0, q1, q2
+vqrdmladh.s32 q0, q0, q2
+vqrdmladh.s32 q0, q1, q0
+vqrdmladhx.u32 q0, q1, q2
+vqrdmladhx.s64 q0, q1, q2
+vqrdmladhx.s32 q0, q0, q2
+vqrdmladhx.s32 q0, q1, q0
+cond vqdmladh
+cond vqdmladhx
+cond vqrdmladh
+cond vqrdmladhx
+it eq
+vqdmladheq.s32 q0, q1, q2
+vqdmladheq.s32 q0, q1, q2
+vpst
+vqdmladheq.s32 q0, q1, q2
+vqdmladht.s32 q0, q1, q2
+vpst
+vqdmladh.s32 q0, q1, q2
+it eq
+vqdmladhxeq.s32 q0, q1, q2
+vqdmladhxeq.s32 q0, q1, q2
+vpst
+vqdmladhxeq.s32 q0, q1, q2
+vqdmladhxt.s32 q0, q1, q2
+vpst
+vqdmladhx.s32 q0, q1, q2
+it eq
+vqrdmladheq.s32 q0, q1, q2
+vqrdmladheq.s32 q0, q1, q2
+vpst
+vqrdmladheq.s32 q0, q1, q2
+vqrdmladht.s32 q0, q1, q2
+vpst
+vqrdmladh.s32 q0, q1, q2
+it eq
+vqrdmladhxeq.s32 q0, q1, q2
+vqrdmladhxeq.s32 q0, q1, q2
+vpst
+vqrdmladhxeq.s32 q0, q1, q2
+vqrdmladhxt.s32 q0, q1, q2
+vpst
+vqrdmladhx.s32 q0, q1, q2
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6da0050fa526bf150830e1f70ee41b6df1413dd0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMLSDH and VQRDMLSDH instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmlsdh-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..465476ccc1377d71aea25e42154cb87c6ac9e863
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmlsdh.u32 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmlsdh.s64 q0,q1,q2'
+[^:]*:12: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:13: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmlsdhx.u32 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmlsdhx.s64 q0,q1,q2'
+[^:]*:16: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:17: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:18: Error: bad type in SIMD instruction -- `vqrdmlsdh.u32 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqrdmlsdh.s64 q0,q1,q2'
+[^:]*:20: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:21: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:22: Error: bad type in SIMD instruction -- `vqrdmlsdhx.u32 q0,q1,q2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqrdmlsdhx.s64 q0,q1,q2'
+[^:]*:24: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:25: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*: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 -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:32: Error: syntax error -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:34: Error: syntax error -- `vqdmlsdheq.s32 q0,q1,q2'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmlsdht.s32 q0,q1,q2'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vqdmlsdh.s32 q0,q1,q2'
+[^:]*:39: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:40: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmlsdhxt.s32 q0,q1,q2'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vqdmlsdhx.s32 q0,q1,q2'
+[^:]*:47: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:48: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:50: Error: syntax error -- `vqrdmlsdheq.s32 q0,q1,q2'
+[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmlsdht.s32 q0,q1,q2'
+[^:]*:53: Error: instruction missing MVE vector predication code -- `vqrdmlsdh.s32 q0,q1,q2'
+[^:]*:55: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:56: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:58: Error: syntax error -- `vqrdmlsdhxeq.s32 q0,q1,q2'
+[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vqrdmlsdhxt.s32 q0,q1,q2'
+[^:]*:61: Error: instruction missing MVE vector predication code -- `vqrdmlsdhx.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..4c047a9373aa4b2e6195f0de932117becefde092
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmlsdh-bad.s
@@ -0,0 +1,61 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, q2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmlsdh.u32 q0, q1, q2
+vqdmlsdh.s64 q0, q1, q2
+vqdmlsdh.s32 q0, q0, q2
+vqdmlsdh.s32 q0, q1, q0
+vqdmlsdhx.u32 q0, q1, q2
+vqdmlsdhx.s64 q0, q1, q2
+vqdmlsdhx.s32 q0, q0, q2
+vqdmlsdhx.s32 q0, q1, q0
+vqrdmlsdh.u32 q0, q1, q2
+vqrdmlsdh.s64 q0, q1, q2
+vqrdmlsdh.s32 q0, q0, q2
+vqrdmlsdh.s32 q0, q1, q0
+vqrdmlsdhx.u32 q0, q1, q2
+vqrdmlsdhx.s64 q0, q1, q2
+vqrdmlsdhx.s32 q0, q0, q2
+vqrdmlsdhx.s32 q0, q1, q0
+cond vqdmlsdh
+cond vqdmlsdhx
+cond vqrdmlsdh
+cond vqrdmlsdhx
+it eq
+vqdmlsdheq.s32 q0, q1, q2
+vqdmlsdheq.s32 q0, q1, q2
+vpst
+vqdmlsdheq.s32 q0, q1, q2
+vqdmlsdht.s32 q0, q1, q2
+vpst
+vqdmlsdh.s32 q0, q1, q2
+it eq
+vqdmlsdhxeq.s32 q0, q1, q2
+vqdmlsdhxeq.s32 q0, q1, q2
+vpst
+vqdmlsdhxeq.s32 q0, q1, q2
+vqdmlsdhxt.s32 q0, q1, q2
+vpst
+vqdmlsdhx.s32 q0, q1, q2
+it eq
+vqrdmlsdheq.s32 q0, q1, q2
+vqrdmlsdheq.s32 q0, q1, q2
+vpst
+vqrdmlsdheq.s32 q0, q1, q2
+vqrdmlsdht.s32 q0, q1, q2
+vpst
+vqrdmlsdh.s32 q0, q1, q2
+it eq
+vqrdmlsdhxeq.s32 q0, q1, q2
+vqrdmlsdhxeq.s32 q0, q1, q2
+vpst
+vqrdmlsdhxeq.s32 q0, q1, q2
+vqrdmlsdhxt.s32 q0, q1, q2
+vpst
+vqrdmlsdhx.s32 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 29/57][Arm][GAS] Add support for MVE instructions: vqdmullt and vqdmullb
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (28 preceding siblings ...)
  2019-05-01 17:30 ` [PATCH 27/57][Arm][GAS] Add support for MVE instructions: vqdmladh, vqrdmladh, vqdmlsdh and vqrdmlsdh Andre Vieira (lists)
@ 2019-05-01 17:31 ` Andre Vieira (lists)
  2019-05-01 17:32 ` [PATCH 31/57][Arm][GAS] Add support for MVE instructions: vshrn[tb], vrshrn[tb], vqshrn[tb], vqshrun[tb], vqrshrn[tb] and vqrshrun[tb] Andre Vieira (lists)
                   ` (30 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:31 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 491 bytes --]

Hi,

This patch adds support for MVE instructions VQDMULLT and VQDMULLB.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): Add new operand.
	(parse_operands): Handle new operand.
	(do_mve_vqdmull): New encoding function.
         (insns): Add entry for MVE mnemonics.
	* testsuite/gas/arm/mve-vqdmull-bad.d: New test.
	* testsuite/gas/arm/mve-vqdmull-bad.l: New test.
	* testsuite/gas/arm/mve-vqdmull-bad.s: New test.

[-- Attachment #2: 29.patch --]
[-- Type: text/x-patch, Size: 8702 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a684f949c961d9a6c5a80578bfdc9864718e4a38..6c4b11ced574ffc49dabde7f84edd0682982292b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6926,6 +6926,7 @@ enum operand_parse_code
 		   GPR (no SP/SP)  */
   OP_RMQ,	/* MVE vector register.  */
   OP_RMQRZ,	/* MVE vector or ARM register including ZR.  */
+  OP_RMQRR,     /* MVE vector or ARM register.  */
 
   /* New operands for Armv8.1-M Mainline.  */
   OP_LR,	/* ARM LR register */
@@ -7284,6 +7285,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_reg_or_fail (REG_TYPE_NSDQ);
 	  inst.error = 0;
 	  break;
+	case OP_RMQRR:
+	  po_reg_or_goto (REG_TYPE_RN, try_rmq);
+	  break;
+	try_rmq:
 	case OP_RMQ:
 	  po_reg_or_fail (REG_TYPE_MQ);
 	  break;
@@ -17285,6 +17290,35 @@ do_mve_vhcadd (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vqdmull (void)
+{
+  enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
+
+  if (et.size == 32
+      && (inst.operands[0].reg == inst.operands[1].reg
+	  || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
+    as_tsktsk (BAD_MVE_SRCDEST);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (rs == NS_QQQ)
+    {
+      mve_encode_qqq (et.size == 32, 64);
+      inst.instruction |= 1;
+    }
+  else
+    {
+      mve_encode_qqr (64, et.size == 32, 0);
+      inst.instruction |= 0x3 << 5;
+    }
+}
+
 static void
 do_mve_vadc (void)
 {
@@ -24841,6 +24875,8 @@ static const struct asm_opcode insns[] =
  mToC("vqdmlah",   ee000e60,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
  mToC("vqdmlash",  ee001e60,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
  mToC("vqrdmlash", ee001e40,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
+ mToC("vqdmullt",  ee301f00,	3, (RMQ, RMQ, RMQRR),		mve_vqdmull),
+ mToC("vqdmullb",  ee300f00,	3, (RMQ, RMQ, RMQRR),		mve_vqdmull),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
diff --git a/gas/testsuite/gas/arm/mve-vqdmull-bad.d b/gas/testsuite/gas/arm/mve-vqdmull-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..4eb6fb2dfc665ee696426b1b2a5fff616f2da173
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmull-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQDMULLT and VQDMULLB instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqdmull-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqdmull-bad.l b/gas/testsuite/gas/arm/mve-vqdmull-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..1ddc335a7ffc90c63147c046824b650a682abbac
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmull-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqdmullt.s8 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqdmullt.u8 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqdmullt.i16 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vqdmullt.s64 q0,q1,q2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vqdmullb.s8 q0,q1,q2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqdmullb.u8 q0,q1,q2'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqdmullb.i16 q0,q1,q2'
+[^:]*:17: Error: bad type in SIMD instruction -- `vqdmullb.s64 q0,q1,q2'
+[^:]*:18: Error: bad type in SIMD instruction -- `vqdmullt.s8 q0,q1,r2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqdmullt.u8 q0,q1,r2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vqdmullt.i16 q0,q1,r2'
+[^:]*:21: Error: bad type in SIMD instruction -- `vqdmullt.s64 q0,q1,r2'
+[^:]*:22: Error: bad type in SIMD instruction -- `vqdmullb.s8 q0,q1,r2'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqdmullb.u8 q0,q1,r2'
+[^:]*:24: Error: bad type in SIMD instruction -- `vqdmullb.i16 q0,q1,r2'
+[^:]*:25: Error: bad type in SIMD instruction -- `vqdmullb.s64 q0,q1,r2'
+[^:]*:26: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:27: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:28: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:29: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:30: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:31: Warning: 32-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:32: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:34: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:35: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:41: Error: syntax error -- `vqdmullteq.s32 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqdmullteq.s32 q0,q1,q2'
+[^:]*:44: Error: syntax error -- `vqdmullteq.s32 q0,q1,q2'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmulltt.s32 q0,q1,q2'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vqdmullt.s32 q0,q1,q2'
+[^:]*:49: Error: syntax error -- `vqdmullbeq.s32 q0,q1,q2'
+[^:]*:50: Error: syntax error -- `vqdmullbeq.s32 q0,q1,q2'
+[^:]*:52: Error: syntax error -- `vqdmullbeq.s32 q0,q1,q2'
+[^:]*:53: Error: vector predicated instruction should be in VPT/VPST block -- `vqdmullbt.s32 q0,q1,q2'
+[^:]*:55: Error: instruction missing MVE vector predication code -- `vqdmullb.s32 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqdmull-bad.s b/gas/testsuite/gas/arm/mve-vqdmull-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..fac7d5f157c6b1caf70acada5db48127bd8eec26
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqdmull-bad.s
@@ -0,0 +1,55 @@
+.macro cond op, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqdmullt.s8 q0, q1, q2
+vqdmullt.u8 q0, q1, q2
+vqdmullt.i16 q0, q1, q2
+vqdmullt.s64 q0, q1, q2
+vqdmullb.s8 q0, q1, q2
+vqdmullb.u8 q0, q1, q2
+vqdmullb.i16 q0, q1, q2
+vqdmullb.s64 q0, q1, q2
+vqdmullt.s8 q0, q1, r2
+vqdmullt.u8 q0, q1, r2
+vqdmullt.i16 q0, q1, r2
+vqdmullt.s64 q0, q1, r2
+vqdmullb.s8 q0, q1, r2
+vqdmullb.u8 q0, q1, r2
+vqdmullb.i16 q0, q1, r2
+vqdmullb.s64 q0, q1, r2
+vqdmullt.s32 q0, q0, q2
+vqdmullt.s32 q0, q1, q0
+vqdmullb.s32 q0, q0, q2
+vqdmullb.s32 q0, q1, q0
+vqdmullt.s32 q0, q0, r2
+vqdmullb.s32 q0, q0, r2
+vqdmullt.s16 q0, q0, sp
+vqdmullt.s16 q0, q0, pc
+vqdmullb.s16 q0, q0, sp
+vqdmullb.s16 q0, q0, pc
+cond vqdmullt, q2
+cond vqdmullb, q2
+cond vqdmullt, r2
+cond vqdmullb, r2
+it eq
+vqdmullteq.s32 q0, q1, q2
+vqdmullteq.s32 q0, q1, q2
+vpst
+vqdmullteq.s32 q0, q1, q2
+vqdmulltt.s32 q0, q1, q2
+vpst
+vqdmullt.s32 q0, q1, q2
+it eq
+vqdmullbeq.s32 q0, q1, q2
+vqdmullbeq.s32 q0, q1, q2
+vpst
+vqdmullbeq.s32 q0, q1, q2
+vqdmullbt.s32 q0, q1, q2
+vpst
+vqdmullb.s32 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 31/57][Arm][GAS] Add support for MVE instructions: vshrn[tb], vrshrn[tb], vqshrn[tb], vqshrun[tb], vqrshrn[tb] and vqrshrun[tb]
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (29 preceding siblings ...)
  2019-05-01 17:31 ` [PATCH 29/57][Arm][GAS] Add support for MVE instructions: vqdmullt and vqdmullb Andre Vieira (lists)
@ 2019-05-01 17:32 ` Andre Vieira (lists)
  2019-05-01 17:32 ` [PATCH 30/57][Arm][GAS] Add support for MVE instructions: vqmovnt, vqmovnb, vqmovunt, vqmovunb, vqrshl and vrshl Andre Vieira (lists)
                   ` (29 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:32 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 884 bytes --]

Hi,

This patch adds support for MVE instructions VSHRNT, VSHRNB, VRSHRNT, 
VRSHRNB, VQSHRUNT, VQSHRUNT, VQRSHRNT, VQRSHRNB, VQRSHRUNT, and VQRSHRUNB.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vshrnt, M_MNEM_vshrnb, M_MNEM_vrshrnt,
         M_MNEM_vqshrnt, M_MNEM_vqshrnb, M_MNEM_vqshrunt, M_MNEM_vqshrunb,
         M_MNEM_vrshrnb, M_MNEM_vqrshrnt, M_MNEM_vqrshrnb, M_MNEM_vqrshrunt,
         M_MNEM_vqrshrunb): New instruction encodings.
	(do_mve_vshrn): New encoding function.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vqrshrn-bad.d: New test.
	* testsuite/gas/arm/mve-vqrshrn-bad.l: New test.
	* testsuite/gas/arm/mve-vqrshrn-bad.s: New test.
	* testsuite/gas/arm/mve-vshrn-bad.d: New test.
	* testsuite/gas/arm/mve-vshrn-bad.l: New test.
	* testsuite/gas/arm/mve-vshrn-bad.s: New test.

[-- Attachment #2: 31.patch --]
[-- Type: text/x-patch, Size: 17347 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 9cf70bfe5f9c8bbe3445ad4b07d1a5d1f02de32b..af7723f8ba5577156544166a392a3a94b26bcdb5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14209,6 +14209,18 @@ do_t_loloop (void)
 #define M_MNEM_vqmovnb	  0xee330e01
 #define M_MNEM_vqmovunt	  0xee311e81
 #define M_MNEM_vqmovunb	  0xee310e81
+#define M_MNEM_vshrnt	    0xee801fc1
+#define M_MNEM_vshrnb	    0xee800fc1
+#define M_MNEM_vrshrnt	    0xfe801fc1
+#define M_MNEM_vqshrnt	    0xee801f40
+#define M_MNEM_vqshrnb	    0xee800f40
+#define M_MNEM_vqshrunt	    0xee801fc0
+#define M_MNEM_vqshrunb	    0xee800fc0
+#define M_MNEM_vrshrnb	    0xfe800fc1
+#define M_MNEM_vqrshrnt	    0xee801f41
+#define M_MNEM_vqrshrnb	    0xee800f41
+#define M_MNEM_vqrshrunt    0xfe801fc0
+#define M_MNEM_vqrshrunb    0xfe800fc0
 
 /* Neon instruction encoder helpers.  */
 
@@ -15753,6 +15765,58 @@ do_mve_vmlas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vshrn (void)
+{
+  unsigned types;
+  switch (inst.instruction)
+    {
+    case M_MNEM_vshrnt:
+    case M_MNEM_vshrnb:
+    case M_MNEM_vrshrnt:
+    case M_MNEM_vrshrnb:
+      types = N_I16 | N_I32;
+      break;
+    case M_MNEM_vqshrnt:
+    case M_MNEM_vqshrnb:
+    case M_MNEM_vqrshrnt:
+    case M_MNEM_vqrshrnb:
+      types = N_U16 | N_U32 | N_S16 | N_S32;
+      break;
+    case M_MNEM_vqshrunt:
+    case M_MNEM_vqshrunb:
+    case M_MNEM_vqrshrunt:
+    case M_MNEM_vqrshrunb:
+      types = N_S16 | N_S32;
+      break;
+    default:
+      abort ();
+    }
+
+  struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  unsigned Qd = inst.operands[0].reg;
+  unsigned Qm = inst.operands[1].reg;
+  unsigned imm = inst.operands[2].imm;
+  constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
+	      et.size == 16
+	      ? _("immediate operand expected in the range [1,8]")
+	      : _("immediate operand expected in the range [1,16]"));
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (Qd) << 22;
+  inst.instruction |= (et.size - imm) << 16;
+  inst.instruction |= LOW4 (Qd) << 12;
+  inst.instruction |= HI1 (Qm) << 5;
+  inst.instruction |= LOW4 (Qm);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vqmovn (void)
 {
@@ -24949,6 +25013,19 @@ static const struct asm_opcode insns[] =
  mCEF(vqmovunt,	  _vqmovunt,	2, (RMQ, RMQ),			mve_vqmovn),
  mCEF(vqmovunb,	  _vqmovunb,	2, (RMQ, RMQ),			mve_vqmovn),
 
+ mCEF(vshrnt,	  _vshrnt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vshrnb,	  _vshrnb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vrshrnt,	  _vrshrnt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vrshrnb,	  _vrshrnb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqshrnt,	  _vqrshrnt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqshrnb,	  _vqrshrnb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqshrunt,	  _vqrshrunt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqshrunb,	  _vqrshrunb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqrshrnt,	  _vqrshrnt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqrshrnb,	  _vqrshrnb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqrshrunt,  _vqrshrunt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+ mCEF(vqrshrunb,  _vqrshrunb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vqrshrn-bad.d b/gas/testsuite/gas/arm/mve-vqrshrn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6673336252e16c3bf90fbb580af3a2f663d1194c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshrn-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQRSHRNT, VQRSHRNB, VQRHSRUNT and MVQRSHRUNB instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqrshrn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqrshrn-bad.l b/gas/testsuite/gas/arm/mve-vqrshrn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..df4f79f836ef389ef9650b1a1567cea1b4086428
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshrn-bad.l
@@ -0,0 +1,71 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqrshrnt.s8 q0,q1,#1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqrshrnt.s64 q0,q1,#1'
+[^:]*:12: Error: immediate operand expected in the range \[1,8\] -- `vqrshrnt.s16 q0,q1,#0'
+[^:]*:13: Error: immediate operand expected in the range \[1,8\] -- `vqrshrnt.s16 q0,q1,#9'
+[^:]*:14: Error: immediate operand expected in the range \[1,16\] -- `vqrshrnt.s32 q0,q1,#0'
+[^:]*:15: Error: immediate operand expected in the range \[1,16\] -- `vqrshrnt.s32 q0,q1,#17'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqrshrnb.s8 q0,q1,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vqrshrnb.s64 q0,q1,#1'
+[^:]*:18: Error: immediate operand expected in the range \[1,8\] -- `vqrshrnb.s16 q0,q1,#0'
+[^:]*:19: Error: immediate operand expected in the range \[1,8\] -- `vqrshrnb.s16 q0,q1,#9'
+[^:]*:20: Error: immediate operand expected in the range \[1,16\] -- `vqrshrnb.s32 q0,q1,#0'
+[^:]*:21: Error: immediate operand expected in the range \[1,16\] -- `vqrshrnb.s32 q0,q1,#17'
+[^:]*:22: Error: bad type in SIMD instruction -- `vqrshrunt.s8 q0,q1,#1'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqrshrunt.s64 q0,q1,#1'
+[^:]*:24: Error: immediate operand expected in the range \[1,8\] -- `vqrshrunt.s16 q0,q1,#0'
+[^:]*:25: Error: immediate operand expected in the range \[1,8\] -- `vqrshrunt.s16 q0,q1,#9'
+[^:]*:26: Error: immediate operand expected in the range \[1,16\] -- `vqrshrunt.s32 q0,q1,#0'
+[^:]*:27: Error: immediate operand expected in the range \[1,16\] -- `vqrshrunt.s32 q0,q1,#17'
+[^:]*:28: Error: bad type in SIMD instruction -- `vqrshrunt.u16 q0,q1,#1'
+[^:]*:29: Error: bad type in SIMD instruction -- `vqrshrunb.s8 q0,q1,#1'
+[^:]*:30: Error: bad type in SIMD instruction -- `vqrshrunb.s64 q0,q1,#1'
+[^:]*:31: Error: immediate operand expected in the range \[1,8\] -- `vqrshrunb.s16 q0,q1,#0'
+[^:]*:32: Error: immediate operand expected in the range \[1,8\] -- `vqrshrunb.s16 q0,q1,#9'
+[^:]*:33: Error: immediate operand expected in the range \[1,16\] -- `vqrshrunb.s32 q0,q1,#0'
+[^:]*:34: Error: immediate operand expected in the range \[1,16\] -- `vqrshrunb.s32 q0,q1,#17'
+[^:]*:35: Error: bad type in SIMD instruction -- `vqrshrunb.u16 q0,q1,#1'
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:36: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:37: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:38: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:39: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:41: Error: syntax error -- `vqrshrnteq.s16 q0,q1,#1'
+[^:]*:42: Error: syntax error -- `vqrshrnteq.s16 q0,q1,#1'
+[^:]*:44: Error: syntax error -- `vqrshrnteq.s16 q0,q1,#1'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshrntt.s16 q0,q1,#1'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vqrshrnt.s16 q0,q1,#1'
+[^:]*:49: Error: syntax error -- `vqrshrnbeq.s16 q0,q1,#1'
+[^:]*:50: Error: syntax error -- `vqrshrnbeq.s16 q0,q1,#1'
+[^:]*:52: Error: syntax error -- `vqrshrnbeq.s16 q0,q1,#1'
+[^:]*:53: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshrnbt.s16 q0,q1,#1'
+[^:]*:55: Error: instruction missing MVE vector predication code -- `vqrshrnb.s16 q0,q1,#1'
+[^:]*:57: Error: syntax error -- `vqrshrunteq.s16 q0,q1,#1'
+[^:]*:58: Error: syntax error -- `vqrshrunteq.s16 q0,q1,#1'
+[^:]*:60: Error: syntax error -- `vqrshrunteq.s16 q0,q1,#1'
+[^:]*:61: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshruntt.s16 q0,q1,#1'
+[^:]*:63: Error: instruction missing MVE vector predication code -- `vqrshrunt.s16 q0,q1,#1'
+[^:]*:65: Error: syntax error -- `vqrshrunbeq.s16 q0,q1,#1'
+[^:]*:66: Error: syntax error -- `vqrshrunbeq.s16 q0,q1,#1'
+[^:]*:68: Error: syntax error -- `vqrshrunbeq.s16 q0,q1,#1'
+[^:]*:69: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshrunbt.s16 q0,q1,#1'
+[^:]*:71: Error: instruction missing MVE vector predication code -- `vqrshrunb.s16 q0,q1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vqrshrn-bad.s b/gas/testsuite/gas/arm/mve-vqrshrn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..1905943b4649066fa3af31de12ec48cd5dfed00e
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshrn-bad.s
@@ -0,0 +1,71 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q0, #1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqrshrnt.s8 q0, q1, #1
+vqrshrnt.s64 q0, q1, #1
+vqrshrnt.s16 q0, q1, #0
+vqrshrnt.s16 q0, q1, #9
+vqrshrnt.s32 q0, q1, #0
+vqrshrnt.s32 q0, q1, #17
+vqrshrnb.s8 q0, q1, #1
+vqrshrnb.s64 q0, q1, #1
+vqrshrnb.s16 q0, q1, #0
+vqrshrnb.s16 q0, q1, #9
+vqrshrnb.s32 q0, q1, #0
+vqrshrnb.s32 q0, q1, #17
+vqrshrunt.s8 q0, q1, #1
+vqrshrunt.s64 q0, q1, #1
+vqrshrunt.s16 q0, q1, #0
+vqrshrunt.s16 q0, q1, #9
+vqrshrunt.s32 q0, q1, #0
+vqrshrunt.s32 q0, q1, #17
+vqrshrunt.u16 q0, q1, #1
+vqrshrunb.s8 q0, q1, #1
+vqrshrunb.s64 q0, q1, #1
+vqrshrunb.s16 q0, q1, #0
+vqrshrunb.s16 q0, q1, #9
+vqrshrunb.s32 q0, q1, #0
+vqrshrunb.s32 q0, q1, #17
+vqrshrunb.u16 q0, q1, #1
+cond vqrshrnt
+cond vqrshrnb
+cond vqrshrunt
+cond vqrshrunb
+it eq
+vqrshrnteq.s16 q0, q1, #1
+vqrshrnteq.s16 q0, q1, #1
+vpst
+vqrshrnteq.s16 q0, q1, #1
+vqrshrntt.s16 q0, q1, #1
+vpst
+vqrshrnt.s16 q0, q1, #1
+it eq
+vqrshrnbeq.s16 q0, q1, #1
+vqrshrnbeq.s16 q0, q1, #1
+vpst
+vqrshrnbeq.s16 q0, q1, #1
+vqrshrnbt.s16 q0, q1, #1
+vpst
+vqrshrnb.s16 q0, q1, #1
+it eq
+vqrshrunteq.s16 q0, q1, #1
+vqrshrunteq.s16 q0, q1, #1
+vpst
+vqrshrunteq.s16 q0, q1, #1
+vqrshruntt.s16 q0, q1, #1
+vpst
+vqrshrunt.s16 q0, q1, #1
+it eq
+vqrshrunbeq.s16 q0, q1, #1
+vqrshrunbeq.s16 q0, q1, #1
+vpst
+vqrshrunbeq.s16 q0, q1, #1
+vqrshrunbt.s16 q0, q1, #1
+vpst
+vqrshrunb.s16 q0, q1, #1
diff --git a/gas/testsuite/gas/arm/mve-vshrn-bad.d b/gas/testsuite/gas/arm/mve-vshrn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..d63fa6f8e27da537f1a1f8444dd7ddf81248427c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshrn-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSHRN and VRSHRN instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshrn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshrn-bad.l b/gas/testsuite/gas/arm/mve-vshrn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..51bbf30d31c670056f26f39b7185d65640d097a3
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshrn-bad.l
@@ -0,0 +1,57 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vshrnt.i64 q0,q1,#1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vshrnb.i64 q0,q1,#1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vrshrnt.i64 q0,q1,#1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrshrnb.i64 q0,q1,#1'
+[^:]*:14: Error: immediate operand expected in the range \[1,8\] -- `vshrnt.i16 q0,q1,#0'
+[^:]*:15: Error: immediate operand expected in the range \[1,8\] -- `vshrnt.i16 q0,q1,#9'
+[^:]*:16: Error: immediate operand expected in the range \[1,16\] -- `vshrnt.i32 q0,q1,#0'
+[^:]*:17: Error: immediate operand expected in the range \[1,16\] -- `vshrnt.i32 q0,q1,#17'
+[^:]*:18: Error: immediate operand expected in the range \[1,8\] -- `vshrnb.i16 q0,q1,#0'
+[^:]*:19: Error: immediate operand expected in the range \[1,8\] -- `vshrnb.i16 q0,q1,#9'
+[^:]*:20: Error: immediate operand expected in the range \[1,16\] -- `vshrnb.i32 q0,q1,#0'
+[^:]*:21: Error: immediate operand expected in the range \[1,16\] -- `vshrnb.i32 q0,q1,#17'
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: 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
+[^:]*:25: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:27: Error: syntax error -- `vshrnteq.i32 q0,q1,#1'
+[^:]*:28: Error: syntax error -- `vshrnteq.i32 q0,q1,#1'
+[^:]*:30: Error: syntax error -- `vshrnteq.i32 q0,q1,#1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vshrntt.i32 q0,q1,#1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vshrnt.i32 q0,q1,#1'
+[^:]*:35: Error: syntax error -- `vshrnbeq.i32 q0,q1,#1'
+[^:]*:36: Error: syntax error -- `vshrnbeq.i32 q0,q1,#1'
+[^:]*:38: Error: syntax error -- `vshrnbeq.i32 q0,q1,#1'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vshrnbt.i32 q0,q1,#1'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vshrnb.i32 q0,q1,#1'
+[^:]*:43: Error: syntax error -- `vrshrnteq.i32 q0,q1,#1'
+[^:]*:44: Error: syntax error -- `vrshrnteq.i32 q0,q1,#1'
+[^:]*:46: Error: syntax error -- `vrshrnteq.i32 q0,q1,#1'
+[^:]*:47: Error: vector predicated instruction should be in VPT/VPST block -- `vrshrntt.i32 q0,q1,#1'
+[^:]*:49: Error: instruction missing MVE vector predication code -- `vrshrnt.i32 q0,q1,#1'
+[^:]*:51: Error: syntax error -- `vrshrnbeq.i32 q0,q1,#1'
+[^:]*:52: Error: syntax error -- `vrshrnbeq.i32 q0,q1,#1'
+[^:]*:54: Error: syntax error -- `vrshrnbeq.i32 q0,q1,#1'
+[^:]*:55: Error: vector predicated instruction should be in VPT/VPST block -- `vrshrnbt.i32 q0,q1,#1'
+[^:]*:57: Error: instruction missing MVE vector predication code -- `vrshrnb.i32 q0,q1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vshrn-bad.s b/gas/testsuite/gas/arm/mve-vshrn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..5faa09865f0ebdca16b6f8c2c47d04629ae0cc0f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshrn-bad.s
@@ -0,0 +1,57 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().i32 q0, q1, #1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshrnt.i64 q0, q1, #1
+vshrnb.i64 q0, q1, #1
+vrshrnt.i64 q0, q1, #1
+vrshrnb.i64 q0, q1, #1
+vshrnt.i16 q0, q1, #0
+vshrnt.i16 q0, q1, #9
+vshrnt.i32 q0, q1, #0
+vshrnt.i32 q0, q1, #17
+vshrnb.i16 q0, q1, #0
+vshrnb.i16 q0, q1, #9
+vshrnb.i32 q0, q1, #0
+vshrnb.i32 q0, q1, #17
+cond vshrnt
+cond vshrnb
+cond vrshrnt
+cond vrshrnb
+it eq
+vshrnteq.i32 q0, q1, #1
+vshrnteq.i32 q0, q1, #1
+vpst
+vshrnteq.i32 q0, q1, #1
+vshrntt.i32 q0, q1, #1
+vpst
+vshrnt.i32 q0, q1, #1
+it eq
+vshrnbeq.i32 q0, q1, #1
+vshrnbeq.i32 q0, q1, #1
+vpst
+vshrnbeq.i32 q0, q1, #1
+vshrnbt.i32 q0, q1, #1
+vpst
+vshrnb.i32 q0, q1, #1
+it eq
+vrshrnteq.i32 q0, q1, #1
+vrshrnteq.i32 q0, q1, #1
+vpst
+vrshrnteq.i32 q0, q1, #1
+vrshrntt.i32 q0, q1, #1
+vpst
+vrshrnt.i32 q0, q1, #1
+it eq
+vrshrnbeq.i32 q0, q1, #1
+vrshrnbeq.i32 q0, q1, #1
+vpst
+vrshrnbeq.i32 q0, q1, #1
+vrshrnbt.i32 q0, q1, #1
+vpst
+vrshrnb.i32 q0, q1, #1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 30/57][Arm][GAS] Add support for MVE instructions: vqmovnt, vqmovnb, vqmovunt, vqmovunb, vqrshl and vrshl
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (30 preceding siblings ...)
  2019-05-01 17:32 ` [PATCH 31/57][Arm][GAS] Add support for MVE instructions: vshrn[tb], vrshrn[tb], vqshrn[tb], vqshrun[tb], vqrshrn[tb] and vqrshrun[tb] Andre Vieira (lists)
@ 2019-05-01 17:32 ` Andre Vieira (lists)
  2019-05-01 17:33 ` [PATCH 32/57][Arm][GAS] Add support for MVE instructions: vrintn, vrintx, vrinta, vrintz, vrintm and vrintp Andre Vieira (lists)
                   ` (28 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:32 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 900 bytes --]

Hi,

This patch adds support for MVE instructions VQMOVNT, VQMOVNB, VQMOVUNT, 
VQMOVUNB, VQRSHL, and VRSHL.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (M_MNEM_vqmovnt, M_MNEM_vqmovnb,
         M_MNEM_vqmovunt, M_MNEM_vqmovunb): New instruction encodings.
	(do_mve_vqmovn): New encoding function.
	(do_neon_rshl): Change to accepte MVE variants.
         (insns): Change entries and add new for MVE mnemonics.
	* testsuite/gas/arm/mve-vqmovn-bad.d: New test.
	* testsuite/gas/arm/mve-vqmovn-bad.l: New test.
	* testsuite/gas/arm/mve-vqmovn-bad.s: New test.
	* testsuite/gas/arm/mve-vqrshl-bad.d: New test.
	* testsuite/gas/arm/mve-vqrshl-bad.l: New test.
	* testsuite/gas/arm/mve-vqrshl-bad.s: New test.
	* testsuite/gas/arm/mve-vrshl-bad.d: New test.
	* testsuite/gas/arm/mve-vrshl-bad.l: New test.
	* testsuite/gas/arm/mve-vrshl-bad.s: New test.

[-- Attachment #2: 30.patch --]
[-- Type: text/x-patch, Size: 18343 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 56e7fbd84592db148cdf8db0e44d9f391f161567..9cf70bfe5f9c8bbe3445ad4b07d1a5d1f02de32b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14205,6 +14205,10 @@ do_t_loloop (void)
 #define M_MNEM_vrmlsldavha  0xfe800e21
 #define M_MNEM_vrmlsldavhx  0xfe801e01
 #define M_MNEM_vrmlsldavhax 0xfe801e21
+#define M_MNEM_vqmovnt	  0xee331e01
+#define M_MNEM_vqmovnb	  0xee330e01
+#define M_MNEM_vqmovunt	  0xee311e81
+#define M_MNEM_vqmovunb	  0xee310e81
 
 /* Neon instruction encoder helpers.  */
 
@@ -15749,6 +15753,31 @@ do_mve_vmlas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vqmovn (void)
+{
+  struct neon_type_el et;
+  if (inst.instruction == M_MNEM_vqmovnt
+     || inst.instruction == M_MNEM_vqmovnb)
+    et = neon_check_type (2, NS_QQ, N_EQK,
+			  N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
+  else
+    et = neon_check_type (2, NS_QQ, N_EQK, 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;
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= (et.size == 32) << 18;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vpsel (void)
 {
@@ -16356,15 +16385,55 @@ do_neon_qshl_imm (void)
 static void
 do_neon_rshl (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_ALL | N_KEY);
+  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_QQR, NS_QQQ, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+      et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
+    }
+
   unsigned int tmp;
 
-  tmp = inst.operands[2].reg;
-  inst.operands[2].reg = inst.operands[1].reg;
-  inst.operands[1].reg = tmp;
-  neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+  if (rs == NS_QQR)
+    {
+      if (inst.operands[2].reg == REG_PC)
+	as_tsktsk (MVE_BAD_PC);
+      else if (inst.operands[2].reg == REG_SP)
+	as_tsktsk (MVE_BAD_SP);
+
+      constraint (inst.operands[0].reg != inst.operands[1].reg,
+		  _("invalid instruction shape"));
+
+      if (inst.instruction == 0x0000510)
+	/* We are dealing with vqrshl.  */
+	inst.instruction = 0xee331ee0;
+      else
+	/* We are dealing with vrshl.  */
+	inst.instruction = 0xee331e60;
+
+      inst.instruction |= (et.type == NT_unsigned) << 28;
+      inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+      inst.instruction |= neon_logbits (et.size) << 18;
+      inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+      inst.instruction |= inst.operands[2].reg;
+      inst.is_neon = 1;
+    }
+  else
+    {
+      tmp = inst.operands[2].reg;
+      inst.operands[2].reg = inst.operands[1].reg;
+      inst.operands[1].reg = tmp;
+      neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+    }
 }
 
 static int
@@ -24113,9 +24182,7 @@ static const struct asm_opcode insns[] =
   /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64.  */
  NUF(vqaddq,    0000010, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
  NUF(vqsubq,    0000210, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
- NUF(vrshl,     0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
  NUF(vrshlq,    0000500, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
- NUF(vqrshl,    0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
  NUF(vqrshlq,   0000510, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
   /* If not immediate, fall back to neon_dyadic_i64_su.
      shl_imm should accept I8 I16 I32 I64,
@@ -24877,6 +24944,10 @@ static const struct asm_opcode insns[] =
  mToC("vqrdmlash", ee001e40,	3, (RMQ, RMQ, RR),		mve_vqdmlah),
  mToC("vqdmullt",  ee301f00,	3, (RMQ, RMQ, RMQRR),		mve_vqdmull),
  mToC("vqdmullb",  ee300f00,	3, (RMQ, RMQ, RMQRR),		mve_vqdmull),
+ mCEF(vqmovnt,	  _vqmovnt,	2, (RMQ, RMQ),			mve_vqmovn),
+ mCEF(vqmovnb,	  _vqmovnb,	2, (RMQ, RMQ),			mve_vqmovn),
+ mCEF(vqmovunt,	  _vqmovunt,	2, (RMQ, RMQ),			mve_vqmovn),
+ mCEF(vqmovunb,	  _vqmovunb,	2, (RMQ, RMQ),			mve_vqmovn),
 
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
@@ -24963,6 +25034,8 @@ static const struct asm_opcode insns[] =
  mnUF(vqrdmlah,  _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
  mnUF(vqdmulh,   _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
  mnUF(vqrdmulh,  _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
+ MNUF(vqrshl,    0000510,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
+ MNUF(vrshl,     0000500,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vqmovn-bad.d b/gas/testsuite/gas/arm/mve-vqmovn-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..ebf6026841f93fdda790a9db4cbe4c16cf77b359
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqmovn-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQMOVNT and VQMOVNB instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqmovn-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqmovn-bad.l b/gas/testsuite/gas/arm/mve-vqmovn-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..f29c30a63001b07032678ea734b2a6704471a9dd
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqmovn-bad.l
@@ -0,0 +1,61 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqmovnt.s8 q0,q1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqmovnt.s64 q0,q1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqmovnt.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vqmovnb.u8 q0,q1'
+[^:]*:14: Error: bad type in SIMD instruction -- `vqmovnb.u64 q0,q1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqmovnb.i16 q0,q1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqmovunt.s8 q0,q1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vqmovunt.s64 q0,q1'
+[^:]*:18: Error: bad type in SIMD instruction -- `vqmovunt.i16 q0,q1'
+[^:]*:19: Error: bad type in SIMD instruction -- `vqmovunb.s8 q0,q1'
+[^:]*:20: Error: bad type in SIMD instruction -- `vqmovunb.s64 q0,q1'
+[^:]*:21: Error: bad type in SIMD instruction -- `vqmovunb.i16 q0,q1'
+[^:]*:22: Error: bad type in SIMD instruction -- `vqmovunt.u16 q0,q1'
+[^:]*:23: Error: bad type in SIMD instruction -- `vqmovunt.u32 q0,q1'
+[^:]*:24: Error: bad type in SIMD instruction -- `vqmovunb.u16 q0,q1'
+[^:]*:25: Error: bad type in SIMD instruction -- `vqmovunb.u32 q0,q1'
+[^:]*: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 -- `vqmovnteq.s16 q0,q1'
+[^:]*:32: Error: syntax error -- `vqmovnteq.s16 q0,q1'
+[^:]*:34: Error: syntax error -- `vqmovnteq.s16 q0,q1'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vqmovntt.s16 q0,q1'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vqmovnt.s16 q0,q1'
+[^:]*:39: Error: syntax error -- `vqmovnbeq.s16 q0,q1'
+[^:]*:40: Error: syntax error -- `vqmovnbeq.s16 q0,q1'
+[^:]*:42: Error: syntax error -- `vqmovnbeq.s16 q0,q1'
+[^:]*:43: Error: vector predicated instruction should be in VPT/VPST block -- `vqmovnbt.s16 q0,q1'
+[^:]*:45: Error: instruction missing MVE vector predication code -- `vqmovnb.s16 q0,q1'
+[^:]*:47: Error: syntax error -- `vqmovunteq.s16 q0,q1'
+[^:]*:48: Error: syntax error -- `vqmovunteq.s16 q0,q1'
+[^:]*:50: Error: syntax error -- `vqmovunteq.s16 q0,q1'
+[^:]*:51: Error: vector predicated instruction should be in VPT/VPST block -- `vqmovuntt.s16 q0,q1'
+[^:]*:53: Error: instruction missing MVE vector predication code -- `vqmovunt.s16 q0,q1'
+[^:]*:55: Error: syntax error -- `vqmovunbeq.s16 q0,q1'
+[^:]*:56: Error: syntax error -- `vqmovunbeq.s16 q0,q1'
+[^:]*:58: Error: syntax error -- `vqmovunbeq.s16 q0,q1'
+[^:]*:59: Error: vector predicated instruction should be in VPT/VPST block -- `vqmovunbt.s16 q0,q1'
+[^:]*:61: Error: instruction missing MVE vector predication code -- `vqmovunb.s16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vqmovn-bad.s b/gas/testsuite/gas/arm/mve-vqmovn-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..a59179cd40d01a366acb5baf31ae250a5c953a33
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqmovn-bad.s
@@ -0,0 +1,61 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqmovnt.s8 q0, q1
+vqmovnt.s64 q0, q1
+vqmovnt.i16 q0, q1
+vqmovnb.u8 q0, q1
+vqmovnb.u64 q0, q1
+vqmovnb.i16 q0, q1
+vqmovunt.s8 q0, q1
+vqmovunt.s64 q0, q1
+vqmovunt.i16 q0, q1
+vqmovunb.s8 q0, q1
+vqmovunb.s64 q0, q1
+vqmovunb.i16 q0, q1
+vqmovunt.u16 q0, q1
+vqmovunt.u32 q0, q1
+vqmovunb.u16 q0, q1
+vqmovunb.u32 q0, q1
+cond vqmovnt
+cond vqmovnb
+cond vqmovunt
+cond vqmovunb
+it eq
+vqmovnteq.s16 q0, q1
+vqmovnteq.s16 q0, q1
+vpst
+vqmovnteq.s16 q0, q1
+vqmovntt.s16 q0, q1
+vpst
+vqmovnt.s16 q0, q1
+it eq
+vqmovnbeq.s16 q0, q1
+vqmovnbeq.s16 q0, q1
+vpst
+vqmovnbeq.s16 q0, q1
+vqmovnbt.s16 q0, q1
+vpst
+vqmovnb.s16 q0, q1
+it eq
+vqmovunteq.s16 q0, q1
+vqmovunteq.s16 q0, q1
+vpst
+vqmovunteq.s16 q0, q1
+vqmovuntt.s16 q0, q1
+vpst
+vqmovunt.s16 q0, q1
+it eq
+vqmovunbeq.s16 q0, q1
+vqmovunbeq.s16 q0, q1
+vpst
+vqmovunbeq.s16 q0, q1
+vqmovunbt.s16 q0, q1
+vpst
+vqmovunb.s16 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vqrshl-bad.d b/gas/testsuite/gas/arm/mve-vqrshl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..d1185da045c1a72f7193b5da5b5fbb3b70a4ec1a
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshl-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQRSHL instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vqrshl-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqrshl-bad.l b/gas/testsuite/gas/arm/mve-vqrshl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..337cf17416d83c4e8dbb67d1d3c2055c82ae7adf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshl-bad.l
@@ -0,0 +1,32 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqrshl.s64 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqrshl.u64 q0,q1,q2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vqrshl.i32 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vqrshl.s64 q0,r2'
+[^:]*:14: Error: bad type in SIMD instruction -- `vqrshl.u64 q0,r2'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqrshl.i32 q0,r2'
+[^:]*:16: Error: invalid instruction shape -- `vqrshl.s32 q0,q1,r2'
+[^:]*:17: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:18: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Error: syntax error -- `vqrshleq.s32 q0,q1,q2'
+[^:]*:23: Error: syntax error -- `vqrshleq.s32 q0,q1,q2'
+[^:]*:25: Error: syntax error -- `vqrshleq.s32 q0,q1,q2'
+[^:]*:26: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshlt.s32 q0,q1,q2'
+[^:]*:28: Error: instruction missing MVE vector predication code -- `vqrshl.s32 q0,q1,q2'
+[^:]*:30: Error: syntax error -- `vqrshleq.s32 q0,r2'
+[^:]*:31: Error: syntax error -- `vqrshleq.s32 q0,r2'
+[^:]*:33: Error: syntax error -- `vqrshleq.s32 q0,r2'
+[^:]*:34: Error: vector predicated instruction should be in VPT/VPST block -- `vqrshlt.s32 q0,r2'
+[^:]*:36: Error: instruction missing MVE vector predication code -- `vqrshl.s32 q0,r2'
diff --git a/gas/testsuite/gas/arm/mve-vqrshl-bad.s b/gas/testsuite/gas/arm/mve-vqrshl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..fd4b5cc4efaccc43b26b7d6f9b0bdf3929bfc747
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqrshl-bad.s
@@ -0,0 +1,36 @@
+.macro cond lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vqrshl.s16 q0, q0, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqrshl.s64 q0, q1, q2
+vqrshl.u64 q0, q1, q2
+vqrshl.i32 q0, q1, q2
+vqrshl.s64 q0, r2
+vqrshl.u64 q0, r2
+vqrshl.i32 q0, r2
+vqrshl.s32 q0, q1, r2
+vqrshl.s32 q0, pc
+vqrshl.s32 q0, sp
+cond q2
+cond r2
+it eq
+vqrshleq.s32 q0, q1, q2
+vqrshleq.s32 q0, q1, q2
+vpst
+vqrshleq.s32 q0, q1, q2
+vqrshlt.s32 q0, q1, q2
+vpst
+vqrshl.s32 q0, q1, q2
+it eq
+vqrshleq.s32 q0, r2
+vqrshleq.s32 q0, r2
+vpst
+vqrshleq.s32 q0, r2
+vqrshlt.s32 q0, r2
+vpst
+vqrshl.s32 q0, r2
diff --git a/gas/testsuite/gas/arm/mve-vrshl-bad.d b/gas/testsuite/gas/arm/mve-vrshl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..163b3a98e84433bb84564f9d2a4abce322c6c724
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrshl-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VRSHL instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vrshl-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vrshl-bad.l b/gas/testsuite/gas/arm/mve-vrshl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5cb98c21e23ffc89d3dce812d88fee4836bbe27f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrshl-bad.l
@@ -0,0 +1,29 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vrshl.i16 q0,q1,q2'
+[^:]*:11: Error: bad type in SIMD instruction -- `vrshl.i16 q0,r2'
+[^:]*:12: Error: bad type in SIMD instruction -- `vrshl.s64 q0,q1,q2'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrshl.s64 q0,r2'
+[^:]*:14: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:15: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vrshleq.s32 q0,q1,q2'
+[^:]*:20: Error: syntax error -- `vrshleq.s32 q0,q1,q2'
+[^:]*:22: Error: syntax error -- `vrshleq.s32 q0,q1,q2'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vrshlt.s32 q0,q1,q2'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrshl.s32 q0,q1,q2'
+[^:]*:27: Error: syntax error -- `vrshleq.s32 q0,r2'
+[^:]*:28: Error: syntax error -- `vrshleq.s32 q0,r2'
+[^:]*:30: Error: syntax error -- `vrshleq.s32 q0,r2'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vrshlt.s32 q0,r2'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vrshl.s32 q0,r2'
diff --git a/gas/testsuite/gas/arm/mve-vrshl-bad.s b/gas/testsuite/gas/arm/mve-vrshl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..77ed167ab47c16238ce5b0f7acc55a089df942c0
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrshl-bad.s
@@ -0,0 +1,33 @@
+.macro cond lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vrshl.s32 q0, q0, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vrshl.i16 q0, q1, q2
+vrshl.i16 q0, r2
+vrshl.s64 q0, q1, q2
+vrshl.s64 q0, r2
+vrshl.s32 q0, sp
+vrshl.s32 q0, pc
+cond q2
+cond r2
+it eq
+vrshleq.s32 q0, q1, q2
+vrshleq.s32 q0, q1, q2
+vpst
+vrshleq.s32 q0, q1, q2
+vrshlt.s32 q0, q1, q2
+vpst
+vrshl.s32 q0, q1, q2
+it eq
+vrshleq.s32 q0, r2
+vrshleq.s32 q0, r2
+vpst
+vrshleq.s32 q0, r2
+vrshlt.s32 q0, r2
+vpst
+vrshl.s32 q0, r2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 32/57][Arm][GAS] Add support for MVE instructions: vrintn, vrintx, vrinta, vrintz, vrintm and vrintp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (31 preceding siblings ...)
  2019-05-01 17:32 ` [PATCH 30/57][Arm][GAS] Add support for MVE instructions: vqmovnt, vqmovnb, vqmovunt, vqmovunb, vqrshl and vrshl Andre Vieira (lists)
@ 2019-05-01 17:33 ` Andre Vieira (lists)
  2019-05-01 17:34 ` [PATCH 33/57][Arm][GAS] Add support for MVE instructions: vshr, vrshr, vsli, vsri, vrev16, vrev32 and vrev64 Andre Vieira (lists)
                   ` (27 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:33 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

Hi,

This patch adds support for MVE instructions VRINTN, VRINTX, VRINTA, 
VRINTZ, VRINTM, and VRINTP.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_vrint_1): Accept MVE variants.
         (insns): Change entries to accept MVE variants.
	* testsuite/gas/arm/mve-vrint-bad.d: New test.
	* testsuite/gas/arm/mve-vrint-bad.l: New test.
	* testsuite/gas/arm/mve-vrint-bad.s: New test.

[-- Attachment #2: 32.patch --]
[-- Type: text/x-patch, Size: 8473 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index af7723f8ba5577156544166a392a3a94b26bcdb5..7ee168120e14abb025483e2e8c4bfd2384d85d34 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -20419,12 +20419,11 @@ do_vrint_1 (enum neon_cvt_mode mode)
       if (et.type == NT_invtype)
 	return;
 
-      set_pred_insn_type (OUTSIDE_PRED_INSN);
-      NEON_ENCODE (FLOAT, inst);
-
-      if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
+      if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
 	return;
 
+      NEON_ENCODE (FLOAT, inst);
+
       inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
       inst.instruction |= HI1 (inst.operands[0].reg) << 22;
       inst.instruction |= LOW4 (inst.operands[1].reg);
@@ -23559,12 +23558,12 @@ static const struct asm_opcode insns[] =
   nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD),		vsel),
   nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD),		vsel),
   nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintr),
-  nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintz),
-  nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ),		vrintx),
-  nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ),		vrinta),
-  nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ),		vrintn),
-  nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ),		vrintp),
-  nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ),		vrintm),
+  mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ),		vrintz),
+  mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ),		vrintx),
+  mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ),		vrinta),
+  mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ),		vrintn),
+  mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ),		vrintp),
+  mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ),		vrintm),
 
   /* Crypto v1 extensions.  */
 #undef  ARM_VARIANT
diff --git a/gas/testsuite/gas/arm/mve-vrint-bad.d b/gas/testsuite/gas/arm/mve-vrint-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..081a00880eb27107f9435ee0a41d2cae7e3f5953
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrint-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VRINT instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vrint-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vrint-bad.l b/gas/testsuite/gas/arm/mve-vrint-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..1d68a82badabae2a56559f476b356fdec9713c48
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrint-bad.l
@@ -0,0 +1,80 @@
+[^:]*: Assembler messages:
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintn.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintn.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintx.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintx.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrinta.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrinta.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintz.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintz.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintm.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintm.f64 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintp.i16 q0,q1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrintp.f64 q0,q1'
+[^:]*:14: Error: invalid rounding mode -- `vrintr.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintneq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintneq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintneq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintnt.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrintn.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintxeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintxeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintxeq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintxt.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrintx.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintaeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintaeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintaeq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintat.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrinta.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintzeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintzeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintzeq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintzt.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrintz.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintmeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintmeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintmeq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintmt.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrintm.f16 q0,q1'
+[^:]*: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
+[^:]*:25: Error: syntax error -- `vrintpeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintpeq.f16 q0,q1'
+[^:]*:25: Error: syntax error -- `vrintpeq.f16 q0,q1'
+[^:]*:25: Error: vector predicated instruction should be in VPT/VPST block -- `vrintpt.f16 q0,q1'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vrintp.f16 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vrint-bad.s b/gas/testsuite/gas/arm/mve-vrint-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..7e9a531a2b1f3374bd3dfe41370d4ea43f5b2038
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrint-bad.s
@@ -0,0 +1,25 @@
+.macro cond, mode
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vrint\mode\().f16 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+.irp mode, n, x, a, z, m, p
+vrint\mode\().i16 q0, q1
+vrint\mode\().f64 q0, q1
+.endr
+vrintr.f16 q0, q1
+.irp mode, n, x, a, z, m, p
+cond \mode
+it eq
+vrint\mode\()eq.f16 q0, q1
+vrint\mode\()eq.f16 q0, q1
+vpst
+vrint\mode\()eq.f16 q0, q1
+vrint\mode\()t.f16 q0, q1
+vpst
+vrint\mode\().f16 q0, q1
+.endr

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 33/57][Arm][GAS] Add support for MVE instructions: vshr, vrshr, vsli, vsri, vrev16, vrev32 and vrev64
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (32 preceding siblings ...)
  2019-05-01 17:33 ` [PATCH 32/57][Arm][GAS] Add support for MVE instructions: vrintn, vrintx, vrinta, vrintz, vrintm and vrintp Andre Vieira (lists)
@ 2019-05-01 17:34 ` Andre Vieira (lists)
  2019-05-01 17:34 ` [PATCH 34/57][Arm][GAS] Add support for MVE instructions: vshl and vqshl Andre Vieira (lists)
                   ` (26 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:34 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 902 bytes --]

Hi,

This patch adds support for VSHR, VRSHR, VSLI, VSRI, VREV16, VREV32, and 
VREV64.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_neon_sli): Accept MVE variants.
	(do_neon_sri): Likewise.
	(do_neon_rev): Likewise.
	(do_neon_rshift_round_imm): Likewise.
         (insns): Likewise.
	* testsuite/gas/arm/mve-vrev-bad.d: New test.
	* testsuite/gas/arm/mve-vrev-bad.l: New test.
	* testsuite/gas/arm/mve-vrev-bad.s: New test.
	* testsuite/gas/arm/mve-vshr-bad.d: New test.
	* testsuite/gas/arm/mve-vshr-bad.l: New test.
	* testsuite/gas/arm/mve-vshr-bad.s: New test.
	* testsuite/gas/arm/mve-vsli-bad.d: New test.
	* testsuite/gas/arm/mve-vsli-bad.l: New test.
	* testsuite/gas/arm/mve-vsli-bad.s: New test.
	* testsuite/gas/arm/mve-vsri-bad.d: New test.
	* testsuite/gas/arm/mve-vsri-bad.l: New test.
	* testsuite/gas/arm/mve-vsri-bad.s: New test.

[-- Attachment #2: 33.patch --]
[-- Type: text/x-patch, Size: 19507 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7ee168120e14abb025483e2e8c4bfd2384d85d34..a249fede42404dfa5978235432a8fc913fa1b13e 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -17876,9 +17876,23 @@ do_neon_abs_neg (void)
 static void
 do_neon_sli (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-  struct neon_type_el et = neon_check_type (2, rs,
-    N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+  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_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+    }
+
+
   int imm = inst.operands[2].imm;
   constraint (imm < 0 || (unsigned)imm >= et.size,
 	      _("immediate out of range for insert"));
@@ -17888,9 +17902,22 @@ do_neon_sli (void)
 static void
 do_neon_sri (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-  struct neon_type_el et = neon_check_type (2, rs,
-    N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+  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_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+    }
+
   int imm = inst.operands[2].imm;
   constraint (imm < 1 || (unsigned)imm > et.size,
 	      _("immediate out of range for insert"));
@@ -19115,14 +19142,29 @@ do_neon_ext (void)
 static void
 do_neon_rev (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+   return;
+
+  enum neon_shape rs;
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+    rs = neon_select_shape (NS_QQ, NS_NULL);
+  else
+    rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
+
   struct neon_type_el et = neon_check_type (2, rs,
     N_EQK, N_8 | N_16 | N_32 | N_KEY);
+
   unsigned op = (inst.instruction >> 7) & 3;
   /* N (width of reversed regions) is encoded as part of the bitmask. We
      extract it here to check the elements to be reversed are smaller.
      Otherwise we'd get a reserved instruction.  */
   unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
+
+  if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
+      && inst.operands[0].reg == inst.operands[1].reg)
+    as_tsktsk (_("Warning: 64-bit element size and same destination and source"
+		 " operands makes instruction UNPREDICTABLE"));
+
   gas_assert (elsize != 0);
   constraint (et.size >= elsize,
 	      _("elements must be smaller than reversal region"));
@@ -19666,8 +19708,22 @@ do_mve_movl (void)
 static void
 do_neon_rshift_round_imm (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-  struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
+  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_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
+    }
   int imm = inst.operands[2].imm;
 
   /* imm == 0 case is encoded as VMOV for V{R}SHR.  */
@@ -24326,18 +24382,14 @@ static const struct asm_opcode insns[] =
   /* Data processing with two registers and a shift amount.  */
   /* Right shifts, and variants with rounding.
      Types accepted S8 S16 S32 S64 U8 U16 U32 U64.  */
- NUF(vshr,      0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
  NUF(vshrq,     0800010, 3, (RNQ,  oRNQ,  I64z), neon_rshift_round_imm),
- NUF(vrshr,     0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
  NUF(vrshrq,    0800210, 3, (RNQ,  oRNQ,  I64z), neon_rshift_round_imm),
  NUF(vsra,      0800110, 3, (RNDQ, oRNDQ, I64),  neon_rshift_round_imm),
  NUF(vsraq,     0800110, 3, (RNQ,  oRNQ,  I64),  neon_rshift_round_imm),
  NUF(vrsra,     0800310, 3, (RNDQ, oRNDQ, I64),  neon_rshift_round_imm),
  NUF(vrsraq,    0800310, 3, (RNQ,  oRNQ,  I64),  neon_rshift_round_imm),
   /* Shift and insert. Sizes accepted 8 16 32 64.  */
- NUF(vsli,      1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
  NUF(vsliq,     1800510, 3, (RNQ,  oRNQ,  I63), neon_sli),
- NUF(vsri,      1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
  NUF(vsriq,     1800410, 3, (RNQ,  oRNQ,  I64), neon_sri),
   /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64.  */
  NUF(vqshlu,    1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
@@ -24388,11 +24440,8 @@ static const struct asm_opcode insns[] =
 
   /* Two registers, miscellaneous.  */
   /* Reverse. Sizes 8 16 32 (must be < size in opcode).  */
- NUF(vrev64,    1b00000, 2, (RNDQ, RNDQ),     neon_rev),
  NUF(vrev64q,   1b00000, 2, (RNQ,  RNQ),      neon_rev),
- NUF(vrev32,    1b00080, 2, (RNDQ, RNDQ),     neon_rev),
  NUF(vrev32q,   1b00080, 2, (RNQ,  RNQ),      neon_rev),
- NUF(vrev16,    1b00100, 2, (RNDQ, RNDQ),     neon_rev),
  NUF(vrev16q,   1b00100, 2, (RNQ,  RNQ),      neon_rev),
   /* Vector replicate. Sizes 8 16 32.  */
  nCE(vdupq,     _vdup,    2, (RNQ,  RR_RNSC),  neon_dup),
@@ -25112,6 +25161,13 @@ static const struct asm_opcode insns[] =
  mnUF(vqrdmulh,  _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
  MNUF(vqrshl,    0000510,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
  MNUF(vrshl,     0000500,  3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
+ MNUF(vshr,      0800010,  3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
+ MNUF(vrshr,     0800210,  3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
+ MNUF(vsli,      1800510,  3, (RNDQMQ, oRNDQMQ, I63),  neon_sli),
+ MNUF(vsri,      1800410,  3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
+ MNUF(vrev64,    1b00000,  2, (RNDQMQ, RNDQMQ),     neon_rev),
+ MNUF(vrev32,    1b00080,  2, (RNDQMQ, RNDQMQ),     neon_rev),
+ MNUF(vrev16,    1b00100,  2, (RNDQMQ, RNDQMQ),     neon_rev),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vrev-bad.d b/gas/testsuite/gas/arm/mve-vrev-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..8051d7bd01d003ce4257894eb90755f13a6d16af
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrev-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VREV16, VREV32 and VREV64 instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vrev-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vrev-bad.l b/gas/testsuite/gas/arm/mve-vrev-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..028c2532762284ad7c0fdb4f7fd6a6868f6ed5a8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrev-bad.l
@@ -0,0 +1,38 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: elements must be smaller than reversal region -- `vrev16.16 q0,q1'
+[^:]*:11: Error: elements must be smaller than reversal region -- `vrev32.32 q0,q1'
+[^:]*:12: Error: elements must be smaller than reversal region -- `vrev64.64 q0,q1'
+[^:]*:13: Warning: 64-bit element size and same destination and source operands makes instruction UNPREDICTABLE
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: 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
+[^:]*:15: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:18: Error: syntax error -- `vrev16eq.8 q0,q1'
+[^:]*:19: Error: syntax error -- `vrev16eq.8 q0,q1'
+[^:]*:21: Error: syntax error -- `vrev16eq.8 q0,q1'
+[^:]*:22: Error: vector predicated instruction should be in VPT/VPST block -- `vrev16t.8 q0,q1'
+[^:]*:24: Error: instruction missing MVE vector predication code -- `vrev16.8 q0,q1'
+[^:]*:26: Error: syntax error -- `vrev32eq.8 q0,q1'
+[^:]*:27: Error: syntax error -- `vrev32eq.8 q0,q1'
+[^:]*:29: Error: syntax error -- `vrev32eq.8 q0,q1'
+[^:]*:30: Error: vector predicated instruction should be in VPT/VPST block -- `vrev32t.8 q0,q1'
+[^:]*:32: Error: instruction missing MVE vector predication code -- `vrev32.8 q0,q1'
+[^:]*:34: Error: syntax error -- `vrev64eq.8 q0,q1'
+[^:]*:35: Error: syntax error -- `vrev64eq.8 q0,q1'
+[^:]*:37: Error: syntax error -- `vrev64eq.8 q0,q1'
+[^:]*:38: Error: vector predicated instruction should be in VPT/VPST block -- `vrev64t.8 q0,q1'
+[^:]*:40: Error: instruction missing MVE vector predication code -- `vrev64.8 q0,q1'
diff --git a/gas/testsuite/gas/arm/mve-vrev-bad.s b/gas/testsuite/gas/arm/mve-vrev-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..b1b5acab71d43ef12d4a8d8a9b41006c892733c2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vrev-bad.s
@@ -0,0 +1,40 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().8 q0, q1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vrev16.16 q0, q1
+vrev32.32 q0, q1
+vrev64.64 q0, q1
+vrev64.8  q0, q0
+cond vrev16
+cond vrev32
+cond vrev64
+it eq
+vrev16eq.8 q0, q1
+vrev16eq.8 q0, q1
+vpst
+vrev16eq.8 q0, q1
+vrev16t.8 q0, q1
+vpst
+vrev16.8 q0, q1
+it eq
+vrev32eq.8 q0, q1
+vrev32eq.8 q0, q1
+vpst
+vrev32eq.8 q0, q1
+vrev32t.8 q0, q1
+vpst
+vrev32.8 q0, q1
+it eq
+vrev64eq.8 q0, q1
+vrev64eq.8 q0, q1
+vpst
+vrev64eq.8 q0, q1
+vrev64t.8 q0, q1
+vpst
+vrev64.8 q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vshr-bad.d b/gas/testsuite/gas/arm/mve-vshr-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..12a9937846b03dd0614304743ccfe368c88e7925
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshr-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSHR and VRSHR instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshr-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshr-bad.l b/gas/testsuite/gas/arm/mve-vshr-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..38fb370a6d7dc11ddbefabea0a45f347d277606b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshr-bad.l
@@ -0,0 +1,33 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vshr.s64 q0,q1,#1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vshr.i32 q0,q1,#1'
+[^:]*:12: Error: bad type in SIMD instruction -- `vrshr.u64 q0,q1,#1'
+[^:]*:13: Error: bad type in SIMD instruction -- `vrshr.i32 q0,q1,#1'
+[^:]*:14: Error: immediate out of range for shift -- `vshr.s8 q0,q1,#9'
+[^:]*:15: Error: immediate out of range for shift -- `vshr.u8 q0,q1,#9'
+[^:]*:16: Error: immediate out of range for shift -- `vshr.s16 q0,q1,#17'
+[^:]*:17: Error: immediate out of range for shift -- `vshr.u16 q0,q1,#17'
+[^:]*:18: Error: immediate out of range for shift -- `vshr.s32 q0,q1,#33'
+[^:]*:19: Error: immediate out of range for shift -- `vshr.u32 q0,q1,#33'
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Error: syntax error -- `vshreq.s32 q0,q1,#1'
+[^:]*:24: Error: syntax error -- `vshreq.s32 q0,q1,#1'
+[^:]*:26: Error: syntax error -- `vshreq.s32 q0,q1,#1'
+[^:]*:27: Error: vector predicated instruction should be in VPT/VPST block -- `vshrt.s32 q0,q1,#1'
+[^:]*:29: Error: instruction missing MVE vector predication code -- `vshr.s32 q0,q1,#1'
+[^:]*:31: Error: syntax error -- `vrshreq.s32 q0,q1,#1'
+[^:]*:32: Error: syntax error -- `vrshreq.s32 q0,q1,#1'
+[^:]*:34: Error: syntax error -- `vrshreq.s32 q0,q1,#1'
+[^:]*:35: Error: vector predicated instruction should be in VPT/VPST block -- `vrshrt.s32 q0,q1,#1'
+[^:]*:37: Error: instruction missing MVE vector predication code -- `vrshr.s32 q0,q1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vshr-bad.s b/gas/testsuite/gas/arm/mve-vshr-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..2ec9f57121cfc78e16673df3f03b3e11112ae8e8
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshr-bad.s
@@ -0,0 +1,37 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s32 q0, q1, #1
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshr.s64 q0, q1, #1
+vshr.i32 q0, q1, #1
+vrshr.u64 q0, q1, #1
+vrshr.i32 q0, q1, #1
+vshr.s8 q0, q1, #9
+vshr.u8 q0, q1, #9
+vshr.s16 q0, q1, #17
+vshr.u16 q0, q1, #17
+vshr.s32 q0, q1, #33
+vshr.u32 q0, q1, #33
+cond vshr
+cond vrshr
+it eq
+vshreq.s32 q0, q1, #1
+vshreq.s32 q0, q1, #1
+vpst
+vshreq.s32 q0, q1, #1
+vshrt.s32 q0, q1, #1
+vpst
+vshr.s32 q0, q1, #1
+it eq
+vrshreq.s32 q0, q1, #1
+vrshreq.s32 q0, q1, #1
+vpst
+vrshreq.s32 q0, q1, #1
+vrshrt.s32 q0, q1, #1
+vpst
+vrshr.s32 q0, q1, #1
diff --git a/gas/testsuite/gas/arm/mve-vsli-bad.d b/gas/testsuite/gas/arm/mve-vsli-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..a0a9a2a588209350f4d7d6c89b9a25871bd2d55b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsli-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSLI instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vsli-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vsli-bad.l b/gas/testsuite/gas/arm/mve-vsli-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..bde2a6d23b4df3b1ed05e83c6caea4ea0f067154
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsli-bad.l
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vsli.64 q0,q1,#1'
+[^:]*:11: Error: immediate out of range for insert -- `vsli.8 q0,q1,#8'
+[^:]*:12: Error: immediate out of range for insert -- `vsli.16 q0,q1,#16'
+[^:]*:13: Error: immediate out of range for insert -- `vsli.32 q0,q1,#32'
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: syntax error -- `vslieq.8 q0,q1,#2'
+[^:]*:17: Error: syntax error -- `vslieq.8 q0,q1,#2'
+[^:]*:19: Error: syntax error -- `vslieq.8 q0,q1,#2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vslit.8 q0,q1,#2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vsli.8 q0,q1,#2'
diff --git a/gas/testsuite/gas/arm/mve-vsli-bad.s b/gas/testsuite/gas/arm/mve-vsli-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..0bb17830cc32f3582a76a3f30afbcbbc794f35e1
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsli-bad.s
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vsli.16 q0, q1, #4
+.endr
+.endm
+
+.syntax unified
+.thumb
+vsli.64 q0, q1, #1
+vsli.8 q0, q1, #8
+vsli.16 q0, q1, #16
+vsli.32 q0, q1, #32
+cond
+it eq
+vslieq.8 q0, q1, #2
+vslieq.8 q0, q1, #2
+vpst
+vslieq.8 q0, q1, #2
+vslit.8 q0, q1, #2
+vpst
+vsli.8 q0, q1, #2
diff --git a/gas/testsuite/gas/arm/mve-vsri-bad.d b/gas/testsuite/gas/arm/mve-vsri-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..77e0a24a053d57d66983eb7abcfd96b83919619d
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsri-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSRI instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vsri-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vsri-bad.l b/gas/testsuite/gas/arm/mve-vsri-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..1d7df2072b5d5e1233c4e535d89e6e1b43ee4e5c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsri-bad.l
@@ -0,0 +1,19 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vsri.64 q0,q1,#1'
+[^:]*:11: Error: immediate out of range for insert -- `vsri.8 q0,q1,#0'
+[^:]*:12: Error: immediate out of range for insert -- `vsri.8 q0,q1,#9'
+[^:]*:13: Error: immediate out of range for insert -- `vsri.16 q0,q1,#0'
+[^:]*:14: Error: immediate out of range for insert -- `vsri.16 q0,q1,#17'
+[^:]*:15: Error: immediate out of range for insert -- `vsri.32 q0,q1,#0'
+[^:]*:16: Error: immediate out of range for insert -- `vsri.32 q0,q1,#33'
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:17: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:19: Error: syntax error -- `vsrieq.8 q0,q1,#2'
+[^:]*:20: Error: syntax error -- `vsrieq.8 q0,q1,#2'
+[^:]*:22: Error: syntax error -- `vsrieq.8 q0,q1,#2'
+[^:]*:23: Error: vector predicated instruction should be in VPT/VPST block -- `vsrit.8 q0,q1,#2'
+[^:]*:25: Error: instruction missing MVE vector predication code -- `vsri.8 q0,q1,#2'
diff --git a/gas/testsuite/gas/arm/mve-vsri-bad.s b/gas/testsuite/gas/arm/mve-vsri-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..4f07014f6321716b6ae1f3c96fadcf7555b97a4f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vsri-bad.s
@@ -0,0 +1,26 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vsri.16 q0, q1, #4
+.endr
+.endm
+
+.syntax unified
+.thumb
+vsri.64 q0, q1, #1
+vsri.8 q0, q1, #0
+vsri.8 q0, q1, #9
+vsri.16 q0, q1, #0
+vsri.16 q0, q1, #17
+vsri.32 q0, q1, #0
+vsri.32 q0, q1, #33
+cond
+it eq
+vsrieq.8 q0, q1, #2
+vsrieq.8 q0, q1, #2
+vpst
+vsrieq.8 q0, q1, #2
+vsrit.8 q0, q1, #2
+vpst
+vsri.8 q0, q1, #2
+

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 34/57][Arm][GAS] Add support for MVE instructions: vshl and vqshl
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (33 preceding siblings ...)
  2019-05-01 17:34 ` [PATCH 33/57][Arm][GAS] Add support for MVE instructions: vshr, vrshr, vsli, vsri, vrev16, vrev32 and vrev64 Andre Vieira (lists)
@ 2019-05-01 17:34 ` Andre Vieira (lists)
  2019-05-01 17:36 ` [PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp Andre Vieira (lists)
                   ` (25 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:34 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

Hi,

This patch adds support for MVE instructions VSHL and VQSHL.

gas/ChangeLog:

2019-01-02  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (enum operand_parse_code): Add new operand.
	(parse_operands): Handle new operand.
	(do_neon_shl_imm): Accept MVE variants.
	(do_neon_shl): Likewise.
	(do_neon_qshl_imm): Likewise.
	(do_neon_qshl): Likewise.
	(do_neon_qshlu_imm): Likewise.
         (insns): Likewise.
	* testsuite/gas/arm/mve-vqshl-bad.d: New test.
	* testsuite/gas/arm/mve-vqshl-bad.l: New test.
	* testsuite/gas/arm/mve-vqshl-bad.s: New test.
	* testsuite/gas/arm/mve-vshl-bad.d: New test.
	* testsuite/gas/arm/mve-vshl-bad.l: New test.
	* testsuite/gas/arm/mve-vshl-bad.s: New test.

[-- Attachment #2: 34.patch --]
[-- Type: text/x-patch, Size: 19386 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a249fede42404dfa5978235432a8fc913fa1b13e..53924bd1a76debe9ca9999eefe21a55881541dfb 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6968,6 +6968,8 @@ enum operand_parse_code
   /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN.  */
   OP_RNDQMQ_Ibig,
   OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift.  */
+  OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
+			ARM register.  */
   OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2.  */
   OP_VLDR,	/* VLDR operand.  */
 
@@ -7424,6 +7426,13 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  }
 	  break;
 
+	case OP_RNDQMQ_I63b_RR:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
+	  break;
+	try_rndq_i63b_rr:
+	  po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
+	  break;
+	try_rndq_i63b:
 	case OP_RNDQ_I63b:
 	  {
 	    po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
@@ -16381,12 +16390,25 @@ neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
 }
 
 static void
-do_neon_shl_imm (void)
+do_neon_shl (void)
 {
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+   return;
+
   if (!inst.operands[2].isreg)
     {
-      enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-      struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
+      enum neon_shape rs;
+      struct neon_type_el et;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  rs = neon_select_shape (NS_QQI, NS_NULL);
+	  et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
+	}
+      else
+	{
+	  rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+	  et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
+	}
       int imm = inst.operands[2].imm;
 
       constraint (imm < 0 || (unsigned)imm >= et.size,
@@ -16396,33 +16418,77 @@ do_neon_shl_imm (void)
     }
   else
     {
-      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_SU_ALL | N_KEY, N_EQK | N_SGN);
-      unsigned int tmp;
-
-      /* VSHL/VQSHL 3-register variants have syntax such as:
-	   vshl.xx Dd, Dm, Dn
-	 whereas other 3-register operations encoded by neon_three_same have
-	 syntax like:
-	   vadd.xx Dd, Dn, Dm
-	 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
-	 here.  */
-      tmp = inst.operands[2].reg;
-      inst.operands[2].reg = inst.operands[1].reg;
-      inst.operands[1].reg = tmp;
-      NEON_ENCODE (INTEGER, inst);
-      neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+      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);
+	  et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
+	}
+      else
+	{
+	  rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+	  et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
+	}
+
+
+      if (rs == NS_QQR)
+	{
+	  constraint (inst.operands[0].reg != inst.operands[1].reg,
+		       _("invalid instruction shape"));
+	  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 = 0xee311e60;
+	  inst.instruction |= (et.type == NT_unsigned) << 28;
+	  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+	  inst.instruction |= neon_logbits (et.size) << 18;
+	  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+	  inst.instruction |= inst.operands[2].reg;
+	  inst.is_neon = 1;
+	}
+      else
+	{
+	  unsigned int tmp;
+
+	  /* VSHL/VQSHL 3-register variants have syntax such as:
+	       vshl.xx Dd, Dm, Dn
+	     whereas other 3-register operations encoded by neon_three_same have
+	     syntax like:
+	       vadd.xx Dd, Dn, Dm
+	     (i.e. with Dn & Dm reversed). Swap operands[1].reg and
+	     operands[2].reg here.  */
+	  tmp = inst.operands[2].reg;
+	  inst.operands[2].reg = inst.operands[1].reg;
+	  inst.operands[1].reg = tmp;
+	  NEON_ENCODE (INTEGER, inst);
+	  neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+	}
     }
 }
 
 static void
-do_neon_qshl_imm (void)
+do_neon_qshl (void)
 {
+  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+   return;
+
   if (!inst.operands[2].isreg)
     {
-      enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-      struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
+      enum neon_shape rs;
+      struct neon_type_el et;
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  rs = neon_select_shape (NS_QQI, NS_NULL);
+	  et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
+	}
+      else
+	{
+	  rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+	  et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
+	}
       int imm = inst.operands[2].imm;
 
       constraint (imm < 0 || (unsigned)imm >= et.size,
@@ -16432,17 +16498,48 @@ do_neon_qshl_imm (void)
     }
   else
     {
-      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_SU_ALL | N_KEY, N_EQK | N_SGN);
-      unsigned int tmp;
+      enum neon_shape rs;
+      struct neon_type_el et;
 
-      /* See note in do_neon_shl_imm.  */
-      tmp = inst.operands[2].reg;
-      inst.operands[2].reg = inst.operands[1].reg;
-      inst.operands[1].reg = tmp;
-      NEON_ENCODE (INTEGER, inst);
-      neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
+	{
+	  rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
+	  et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
+	}
+      else
+	{
+	  rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+	  et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
+	}
+
+      if (rs == NS_QQR)
+	{
+	  constraint (inst.operands[0].reg != inst.operands[1].reg,
+		       _("invalid instruction shape"));
+	  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 = 0xee311ee0;
+	  inst.instruction |= (et.type == NT_unsigned) << 28;
+	  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+	  inst.instruction |= neon_logbits (et.size) << 18;
+	  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+	  inst.instruction |= inst.operands[2].reg;
+	  inst.is_neon = 1;
+	}
+      else
+	{
+	  unsigned int tmp;
+
+	  /* See note in do_neon_shl.  */
+	  tmp = inst.operands[2].reg;
+	  inst.operands[2].reg = inst.operands[1].reg;
+	  inst.operands[1].reg = tmp;
+	  NEON_ENCODE (INTEGER, inst);
+	  neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+	}
     }
 }
 
@@ -17927,9 +18024,23 @@ do_neon_sri (void)
 static void
 do_neon_qshlu_imm (void)
 {
-  enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
-  struct neon_type_el et = neon_check_type (2, rs,
-    N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
+  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_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
+    }
+  else
+    {
+      rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
+      et = neon_check_type (2, rs, N_EQK | N_UNS,
+			    N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
+    }
+
   int imm = inst.operands[2].imm;
   constraint (imm < 0 || (unsigned)imm >= et.size,
 	      _("immediate out of range for shift"));
@@ -24304,12 +24415,10 @@ static const struct asm_opcode insns[] =
  NUF(vrshlq,    0000500, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
  NUF(vqrshlq,   0000510, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
   /* If not immediate, fall back to neon_dyadic_i64_su.
-     shl_imm should accept I8 I16 I32 I64,
-     qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64.  */
- nUF(vshl,      _vshl,    3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
- nUF(vshlq,     _vshl,    3, (RNQ,  oRNQ,  RNDQ_I63b), neon_shl_imm),
- nUF(vqshl,     _vqshl,   3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
- nUF(vqshlq,    _vqshl,   3, (RNQ,  oRNQ,  RNDQ_I63b), neon_qshl_imm),
+     shl should accept I8 I16 I32 I64,
+     qshl should accept S8 S16 S32 S64 U8 U16 U32 U64.  */
+ nUF(vshlq,     _vshl,    3, (RNQ,  oRNQ,  RNDQ_I63b), neon_shl),
+ nUF(vqshlq,    _vqshl,   3, (RNQ,  oRNQ,  RNDQ_I63b), neon_qshl),
   /* Logic ops, types optional & ignored.  */
  nUF(vandq,     _vand,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
  nUF(vbicq,     _vbic,    3, (RNQ,  oRNQ,  RNDQ_Ibig), neon_logic),
@@ -24392,7 +24501,6 @@ static const struct asm_opcode insns[] =
  NUF(vsliq,     1800510, 3, (RNQ,  oRNQ,  I63), neon_sli),
  NUF(vsriq,     1800410, 3, (RNQ,  oRNQ,  I64), neon_sri),
   /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64.  */
- NUF(vqshlu,    1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
  NUF(vqshluq,   1800610, 3, (RNQ,  oRNQ,  I63), neon_qshlu_imm),
   /* Right shift immediate, saturating & narrowing, with rounding variants.
      Types accepted S16 S32 S64 U16 U32 U64.  */
@@ -25168,6 +25276,9 @@ static const struct asm_opcode insns[] =
  MNUF(vrev64,    1b00000,  2, (RNDQMQ, RNDQMQ),     neon_rev),
  MNUF(vrev32,    1b00080,  2, (RNDQMQ, RNDQMQ),     neon_rev),
  MNUF(vrev16,    1b00100,  2, (RNDQMQ, RNDQMQ),     neon_rev),
+ mnUF(vshl,	 _vshl,    3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
+ mnUF(vqshl,     _vqshl,   3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
+ MNUF(vqshlu,    1800610,  3, (RNDQMQ, oRNDQMQ, I63),		 neon_qshlu_imm),
 
 #undef	ARM_VARIANT
 #define ARM_VARIANT & arm_ext_v8_3
diff --git a/gas/testsuite/gas/arm/mve-vqshl-bad.d b/gas/testsuite/gas/arm/mve-vqshl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..5f6ba29601bab791a38cef8ad1e6fbf015674797
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqshl-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VQSHL instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vqshl-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vqshl-bad.l b/gas/testsuite/gas/arm/mve-vqshl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..9331fe6006e993da9bdef083218c0fd7e585800b
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqshl-bad.l
@@ -0,0 +1,45 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vqshl.s64 q0,q0,#0'
+[^:]*:11: Error: bad type in SIMD instruction -- `vqshl.i32 q0,q0,#0'
+[^:]*:12: Error: immediate out of range for shift -- `vqshl.s8 q0,q1,#8'
+[^:]*:13: Error: immediate out of range for shift -- `vqshl.u16 q0,q1,#16'
+[^:]*:14: Error: immediate out of range for shift -- `vqshl.s32 q0,q1,#32'
+[^:]*:15: Error: bad type in SIMD instruction -- `vqshl.s64 q0,r1'
+[^:]*:16: Error: bad type in SIMD instruction -- `vqshl.i16 q0,r1'
+[^:]*:17: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:18: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:19: Error: bad type in SIMD instruction -- `vqshl.s64 q0,q1,q2'
+[^:]*:20: Error: bad type in SIMD instruction -- `vqshl.i32 q0,q1,q2'
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Error: syntax error -- `vqshleq.s16 q0,q1,#0'
+[^:]*:26: Error: syntax error -- `vqshleq.s16 q0,q1,#0'
+[^:]*:28: Error: syntax error -- `vqshleq.s16 q0,q1,#0'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vqshlt.s16 q0,q1,#0'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vqshl.s16 q0,q1,#0'
+[^:]*:33: Error: syntax error -- `vqshleq.s16 q0,r1'
+[^:]*:34: Error: syntax error -- `vqshleq.s16 q0,r1'
+[^:]*:36: Error: syntax error -- `vqshleq.s16 q0,r1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vqshlt.s16 q0,r1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vqshl.s16 q0,r1'
+[^:]*:41: Error: syntax error -- `vqshleq.s16 q0,q1,q2'
+[^:]*:42: Error: syntax error -- `vqshleq.s16 q0,q1,q2'
+[^:]*:44: Error: syntax error -- `vqshleq.s16 q0,q1,q2'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vqshlt.s16 q0,q1,q2'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vqshl.s16 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vqshl-bad.s b/gas/testsuite/gas/arm/mve-vqshl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..e4a86578feb23f1b8d0a3099f4c2d8fa6ae4d494
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vqshl-bad.s
@@ -0,0 +1,48 @@
+.macro cond type, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vqshl.\type q0, q0, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vqshl.s64 q0, q0, #0
+vqshl.i32 q0, q0, #0
+vqshl.s8 q0, q1, #8
+vqshl.u16 q0, q1, #16
+vqshl.s32 q0, q1, #32
+vqshl.s64 q0, r1
+vqshl.i16 q0, r1
+vqshl.u16 q0, sp
+vqshl.s32 q0, pc
+vqshl.s64 q0, q1, q2
+vqshl.i32 q0, q1, q2
+cond u32, #0
+cond s8, r1
+cond s16, q2
+it eq
+vqshleq.s16 q0, q1, #0
+vqshleq.s16 q0, q1, #0
+vpst
+vqshleq.s16 q0, q1, #0
+vqshlt.s16 q0, q1, #0
+vpst
+vqshl.s16 q0, q1, #0
+it eq
+vqshleq.s16 q0, r1
+vqshleq.s16 q0, r1
+vpst
+vqshleq.s16 q0, r1
+vqshlt.s16 q0, r1
+vpst
+vqshl.s16 q0, r1
+it eq
+vqshleq.s16 q0, q1, q2
+vqshleq.s16 q0, q1, q2
+vpst
+vqshleq.s16 q0, q1, q2
+vqshlt.s16 q0, q1, q2
+vpst
+vqshl.s16 q0, q1, q2
+
diff --git a/gas/testsuite/gas/arm/mve-vshl-bad.d b/gas/testsuite/gas/arm/mve-vshl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..04d4a5dd587b565296d7296022243f77ae7d5249
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshl-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSHL instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshl-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshl-bad.l b/gas/testsuite/gas/arm/mve-vshl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..d3e4fc6237284fe4ae61aa1a26026762a1b683f2
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshl-bad.l
@@ -0,0 +1,44 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vshl.i64 q0,q0,#0'
+[^:]*:11: Error: immediate out of range for shift -- `vshl.i8 q0,q1,#8'
+[^:]*:12: Error: immediate out of range for shift -- `vshl.i16 q0,q1,#16'
+[^:]*:13: Error: immediate out of range for shift -- `vshl.i32 q0,q1,#32'
+[^:]*:14: Error: bad type in SIMD instruction -- `vshl.s64 q0,r1'
+[^:]*:15: Error: bad type in SIMD instruction -- `vshl.i16 q0,r1'
+[^:]*:16: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:18: Error: bad type in SIMD instruction -- `vshl.s64 q0,q1,q2'
+[^:]*:19: Error: bad type in SIMD instruction -- `vshl.i32 q0,q1,q2'
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:20: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:21: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Error: syntax error -- `vshleq.i16 q0,q1,#0'
+[^:]*:25: Error: syntax error -- `vshleq.i16 q0,q1,#0'
+[^:]*:27: Error: syntax error -- `vshleq.i16 q0,q1,#0'
+[^:]*:28: Error: vector predicated instruction should be in VPT/VPST block -- `vshlt.i16 q0,q1,#0'
+[^:]*:30: Error: instruction missing MVE vector predication code -- `vshl.i16 q0,q1,#0'
+[^:]*:32: Error: syntax error -- `vshleq.s16 q0,r1'
+[^:]*:33: Error: syntax error -- `vshleq.s16 q0,r1'
+[^:]*:35: Error: syntax error -- `vshleq.s16 q0,r1'
+[^:]*:36: Error: vector predicated instruction should be in VPT/VPST block -- `vshlt.s16 q0,r1'
+[^:]*:38: Error: instruction missing MVE vector predication code -- `vshl.s16 q0,r1'
+[^:]*:40: Error: syntax error -- `vshleq.s16 q0,q1,q2'
+[^:]*:41: Error: syntax error -- `vshleq.s16 q0,q1,q2'
+[^:]*:43: Error: syntax error -- `vshleq.s16 q0,q1,q2'
+[^:]*:44: Error: vector predicated instruction should be in VPT/VPST block -- `vshlt.s16 q0,q1,q2'
+[^:]*:46: Error: instruction missing MVE vector predication code -- `vshl.s16 q0,q1,q2'
diff --git a/gas/testsuite/gas/arm/mve-vshl-bad.s b/gas/testsuite/gas/arm/mve-vshl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..70a3f5918161843f05b715fc81acb73319b4d5b6
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshl-bad.s
@@ -0,0 +1,46 @@
+.macro cond type, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vshl.\type q0, q0, \lastreg
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshl.i64 q0, q0, #0
+vshl.i8 q0, q1, #8
+vshl.i16 q0, q1, #16
+vshl.i32 q0, q1, #32
+vshl.s64 q0, r1
+vshl.i16 q0, r1
+vshl.u16 q0, sp
+vshl.s32 q0, pc
+vshl.s64 q0, q1, q2
+vshl.i32 q0, q1, q2
+cond i32, #0
+cond s8, r1
+cond s16, q2
+it eq
+vshleq.i16 q0, q1, #0
+vshleq.i16 q0, q1, #0
+vpst
+vshleq.i16 q0, q1, #0
+vshlt.i16 q0, q1, #0
+vpst
+vshl.i16 q0, q1, #0
+it eq
+vshleq.s16 q0, r1
+vshleq.s16 q0, r1
+vpst
+vshleq.s16 q0, r1
+vshlt.s16 q0, r1
+vpst
+vshl.s16 q0, r1
+it eq
+vshleq.s16 q0, q1, q2
+vshleq.s16 q0, q1, q2
+vpst
+vshleq.s16 q0, q1, q2
+vshlt.s16 q0, q1, q2
+vpst
+vshl.s16 q0, q1, q2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 35/57][Arm][GAS] Add support for MVE instructions: vshlc and vshll
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (35 preceding siblings ...)
  2019-05-01 17:36 ` [PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp Andre Vieira (lists)
@ 2019-05-01 17:36 ` Andre Vieira (lists)
  2019-05-01 17:38 ` [PATCH 38/57][Arm][OBJDUMP] Disable the use of MVE reserved coproc numbers in coprocessor instructions Andre Vieira (lists)
                   ` (23 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:36 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

Hi,

This patch adds support for MVE instructions VSHLC, VSHLLT, and VSHLLB.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (do_mve_vshll): New encoding function.
	(do_mve_vshlc): Likewise.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-vshlc-bad.d: New test.
	* testsuite/gas/arm/mve-vshlc-bad.l: New test.
	* testsuite/gas/arm/mve-vshlc-bad.s: New test.
	* testsuite/gas/arm/mve-vshll-bad.d: New test.
	* testsuite/gas/arm/mve-vshll-bad.l: New test.
	* testsuite/gas/arm/mve-vshll-bad.s: New test.

[-- Attachment #2: 35.patch --]
[-- Type: text/x-patch, Size: 8794 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 53924bd1a76debe9ca9999eefe21a55881541dfb..b3e4228d62f6dd9f3f672dad8f407ef4aed2bf1f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15774,6 +15774,63 @@ do_mve_vmlas (void)
   inst.is_neon = 1;
 }
 
+static void
+do_mve_vshll (void)
+{
+  struct neon_type_el et
+    = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  int imm = inst.operands[2].imm;
+  constraint (imm < 1 || (unsigned)imm > et.size,
+	      _("immediate value out of range"));
+
+  if ((unsigned)imm == et.size)
+    {
+      inst.instruction |= neon_logbits (et.size) << 18;
+      inst.instruction |= 0x110001;
+    }
+  else
+    {
+      inst.instruction |= (et.size + imm) << 16;
+      inst.instruction |= 0x800140;
+    }
+
+  inst.instruction |= (et.type == NT_unsigned) << 28;
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+  inst.instruction |= LOW4 (inst.operands[1].reg);
+  inst.is_neon = 1;
+}
+
+static void
+do_mve_vshlc (void)
+{
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  if (inst.operands[1].reg == REG_PC)
+    as_tsktsk (MVE_BAD_PC);
+  else if (inst.operands[1].reg == REG_SP)
+    as_tsktsk (MVE_BAD_SP);
+
+  int imm = inst.operands[2].imm;
+  constraint (imm < 1 || imm > 32, _("immediate value out of range"));
+
+  inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+  inst.instruction |= (imm & 0x1f) << 16;
+  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+  inst.instruction |= inst.operands[1].reg;
+  inst.is_neon = 1;
+}
+
 static void
 do_mve_vshrn (void)
 {
@@ -25182,6 +25239,10 @@ static const struct asm_opcode insns[] =
  mCEF(vqrshrunt,  _vqrshrunt,	3, (RMQ, RMQ, I32z),	mve_vshrn),
  mCEF(vqrshrunb,  _vqrshrunb,	3, (RMQ, RMQ, I32z),	mve_vshrn),
 
+ mToC("vshlc",	    eea00fc0,	   3, (RMQ, RR, I32z),	    mve_vshlc),
+ mToC("vshllt",	    ee201e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
+ mToC("vshllb",	    ee200e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.d b/gas/testsuite/gas/arm/mve-vshlc-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..fcaafd3abb19f473e0b92537c43645e8bdedf6eb
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSHLC instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshlc-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.l b/gas/testsuite/gas/arm/mve-vshlc-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5aa4ef997b130b54d5968e669ca4109b265dcf11
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.l
@@ -0,0 +1,16 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: immediate value out of range -- `vshlc q0,r1,#0'
+[^:]*:11: Error: immediate value out of range -- `vshlc q0,r1,#33'
+[^:]*:12: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:13: Warning: instruction is UNPREDICTABLE with PC operand
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:16: Error: syntax error -- `vshlceq q0,r1,#2'
+[^:]*:17: Error: syntax error -- `vshlceq q0,r1,#2'
+[^:]*:19: Error: syntax error -- `vshlceq q0,r1,#2'
+[^:]*:20: Error: vector predicated instruction should be in VPT/VPST block -- `vshlct q0,r1,#2'
+[^:]*:22: Error: instruction missing MVE vector predication code -- `vshlc q0,r1,#2'
diff --git a/gas/testsuite/gas/arm/mve-vshlc-bad.s b/gas/testsuite/gas/arm/mve-vshlc-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..777fa76fd8f32a03dbff4a1c08d8a9307af09d23
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshlc-bad.s
@@ -0,0 +1,22 @@
+.macro cond
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+vshlc q0, r1, #2
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshlc q0, r1, #0
+vshlc q0, r1, #33
+vshlc q0, sp, #1
+vshlc q0, pc, #1
+cond
+it eq
+vshlceq q0, r1, #2
+vshlceq q0, r1, #2
+vpst
+vshlceq q0, r1, #2
+vshlct q0, r1, #2
+vpst
+vshlc q0, r1, #2
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.d b/gas/testsuite/gas/arm/mve-vshll-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..df0cfa350e7672bd37c5faefbff9ad792cf3118f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE VSHLLT and VSHLLB instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vshll-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.l b/gas/testsuite/gas/arm/mve-vshll-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..42152f48b2f42f926c7d8b9e81124a1f0c8f91d6
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.l
@@ -0,0 +1,35 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: bad type in SIMD instruction -- `vshllt.s32 q0,q1,#1'
+[^:]*:11: Error: bad type in SIMD instruction -- `vshllt.i8 q0,q1,#1'
+[^:]*:12: Error: immediate value out of range -- `vshllt.u8 q0,q1,#0'
+[^:]*:13: Error: immediate value out of range -- `vshllt.u8 q0,q1,#9'
+[^:]*:14: Error: immediate value out of range -- `vshllt.s16 q0,q1,#0'
+[^:]*:15: Error: immediate value out of range -- `vshllt.s16 q0,q1,#17'
+[^:]*:16: Error: bad type in SIMD instruction -- `vshllb.s32 q0,q1,#1'
+[^:]*:17: Error: bad type in SIMD instruction -- `vshllb.i8 q0,q1,#1'
+[^:]*:18: Error: immediate value out of range -- `vshllb.u8 q0,q1,#0'
+[^:]*:19: Error: immediate value out of range -- `vshllb.u8 q0,q1,#9'
+[^:]*:20: Error: immediate value out of range -- `vshllb.s16 q0,q1,#0'
+[^:]*:21: Error: immediate value out of range -- `vshllb.s16 q0,q1,#17'
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:25: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:26: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:28: Error: syntax error -- `vshllteq.s8 q0,q1,#1'
+[^:]*:29: Error: vector predicated instruction should be in VPT/VPST block -- `vshlltt.s8 q0,q1,#1'
+[^:]*:31: Error: instruction missing MVE vector predication code -- `vshllt.s8 q0,q1,#1'
+[^:]*:33: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:34: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:36: Error: syntax error -- `vshllbeq.s8 q0,q1,#1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vshllbt.s8 q0,q1,#1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vshllb.s8 q0,q1,#1'
diff --git a/gas/testsuite/gas/arm/mve-vshll-bad.s b/gas/testsuite/gas/arm/mve-vshll-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..01d52c65bbe4f8d0a20e2d6fd8cf9be5d16369f9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vshll-bad.s
@@ -0,0 +1,39 @@
+.macro cond op
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+\op\().s16 q0, q1, #4
+.endr
+.endm
+
+.syntax unified
+.thumb
+vshllt.s32 q0, q1, #1
+vshllt.i8 q0, q1, #1
+vshllt.u8 q0, q1, #0
+vshllt.u8 q0, q1, #9
+vshllt.s16 q0, q1, #0
+vshllt.s16 q0, q1, #17
+vshllb.s32 q0, q1, #1
+vshllb.i8 q0, q1, #1
+vshllb.u8 q0, q1, #0
+vshllb.u8 q0, q1, #9
+vshllb.s16 q0, q1, #0
+vshllb.s16 q0, q1, #17
+cond vshllt
+cond vshllb
+it eq
+vshllteq.s8 q0, q1, #1
+vshllteq.s8 q0, q1, #1
+vpst
+vshllteq.s8 q0, q1, #1
+vshlltt.s8 q0, q1, #1
+vpst
+vshllt.s8 q0, q1, #1
+it eq
+vshllbeq.s8 q0, q1, #1
+vshllbeq.s8 q0, q1, #1
+vpst
+vshllbeq.s8 q0, q1, #1
+vshllbt.s8 q0, q1, #1
+vpst
+vshllb.s8 q0, q1, #1

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (34 preceding siblings ...)
  2019-05-01 17:34 ` [PATCH 34/57][Arm][GAS] Add support for MVE instructions: vshl and vqshl Andre Vieira (lists)
@ 2019-05-01 17:36 ` Andre Vieira (lists)
  2019-05-01 17:36 ` [PATCH 35/57][Arm][GAS] Add support for MVE instructions: vshlc and vshll Andre Vieira (lists)
                   ` (24 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:36 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 565 bytes --]

Hi,

This patch adds support for MVE instructions WLSTP, DLSTP, LETP, and LCTP.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (T16_32_TAB): Add new instructions.
	(do_t_loloop): Changed to handle tail predication variants.
	(md_apply_fix): Likewise.
         (insns): Add entries for MVE mnemonics.
	* testsuite/gas/arm/mve-tailpredloop-bad.d: New test.
	* testsuite/gas/arm/mve-tailpredloop-bad.l: New test.
	* testsuite/gas/arm/mve-tailpredloop-bad.s: New test.
	* testsuite/gas/arm/mve-tailpredloop.d: New test.

[-- Attachment #2: 36.patch --]
[-- Type: text/x-patch, Size: 8344 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index b3e4228d62f6dd9f3f672dad8f407ef4aed2bf1f..6ace0adc5041d5333ed57c87db7ea6b00d8319ac 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -11137,9 +11137,11 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
   X(_cpy,   4600, ea4f0000),			\
   X(_dec_sp,80dd, f1ad0d00),			\
   X(_dls,   0000, f040e001),			\
+  X(_dlstp, 0000, f000e001),			\
   X(_eor,   4040, ea800000),			\
   X(_eors,  4040, ea900000),			\
   X(_inc_sp,00dd, f10d0d00),			\
+  X(_lctp,  0000, f00fe001),			\
   X(_ldmia, c800, e8900000),			\
   X(_ldr,   6800, f8500000),			\
   X(_ldrb,  7800, f8100000),			\
@@ -11150,6 +11152,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
   X(_ldr_pc2,4800, f85f0000),			\
   X(_ldr_sp,9800, f85d0000),			\
   X(_le,    0000, f00fc001),			\
+  X(_letp,  0000, f01fc001),			\
   X(_lsl,   0000, fa00f000),			\
   X(_lsls,  0000, fa10f000),			\
   X(_lsr,   0800, fa20f000),			\
@@ -11192,6 +11195,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
   X(_wfe,   bf20, f3af8002),			\
   X(_wfi,   bf30, f3af8003),			\
   X(_wls,   0000, f040c001),			\
+  X(_wlstp, 0000, f000c001),			\
   X(_sev,   bf40, f3af8004),                    \
   X(_sevl,  bf50, f3af8005),			\
   X(_udf,   de00, f7f0a000)
@@ -14117,38 +14121,6 @@ v8_1_loop_reloc (int is_le)
     }
 }
 
-/* To handle the Scalar Low Overhead Loop instructions
-   in Armv8.1-M Mainline.  */
-static void
-do_t_loloop (void)
-{
-  unsigned long insn = inst.instruction;
-
-  set_pred_insn_type (OUTSIDE_PRED_INSN);
-  inst.instruction = THUMB_OP32 (inst.instruction);
-
-  switch (insn)
-    {
-    case T_MNEM_le:
-      /* le <label>.  */
-      if (!inst.operands[0].present)
-	inst.instruction |= 1 << 21;
-
-      v8_1_loop_reloc (TRUE);
-      break;
-
-    case T_MNEM_wls:
-      v8_1_loop_reloc (FALSE);
-      /* Fall through.  */
-    case T_MNEM_dls:
-      constraint (inst.operands[1].isreg != 1, BAD_ARGS);
-      inst.instruction |= (inst.operands[1].reg << 16);
-      break;
-
-    default: abort();
-    }
-}
-
 /* MVE instruction encoder helpers.  */
 #define M_MNEM_vabav	0xee800f01
 #define M_MNEM_vmladav	  0xeef00e00
@@ -14447,6 +14419,8 @@ NEON_ENC_TAB
   X(2, (R, S), SINGLE),			\
   X(2, (F, R), SINGLE),			\
   X(2, (R, F), SINGLE),			\
+/* Used for MVE tail predicated loop instructions.  */\
+  X(2, (R, R), QUAD),			\
 /* Half float shape supported so far.  */\
   X (2, (H, D), MIXED),			\
   X (2, (D, H), MIXED),			\
@@ -15988,6 +15962,66 @@ do_mve_vcmul (void)
   inst.is_neon = 1;
 }
 
+/* To handle the Low Overhead Loop instructions
+   in Armv8.1-M Mainline and MVE.  */
+static void
+do_t_loloop (void)
+{
+  unsigned long insn = inst.instruction;
+
+  inst.instruction = THUMB_OP32 (inst.instruction);
+
+  if (insn == T_MNEM_lctp)
+    return;
+
+  set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
+
+  if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
+    {
+      struct neon_type_el et
+       = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
+      inst.instruction |= neon_logbits (et.size) << 20;
+      inst.is_neon = 1;
+    }
+
+  switch (insn)
+    {
+    case T_MNEM_letp:
+      constraint (!inst.operands[0].present,
+		  _("expected LR"));
+      /* fall through.  */
+    case T_MNEM_le:
+      /* le <label>.  */
+      if (!inst.operands[0].present)
+       inst.instruction |= 1 << 21;
+
+      v8_1_loop_reloc (TRUE);
+      break;
+
+    case T_MNEM_wls:
+    case T_MNEM_wlstp:
+      v8_1_loop_reloc (FALSE);
+      /* fall through.  */
+    case T_MNEM_dlstp:
+    case T_MNEM_dls:
+      constraint (inst.operands[1].isreg != 1, BAD_ARGS);
+
+      if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
+       constraint (inst.operands[1].reg == REG_PC, BAD_PC);
+      else if (inst.operands[1].reg == REG_PC)
+       as_tsktsk (MVE_BAD_PC);
+      if (inst.operands[1].reg == REG_SP)
+       as_tsktsk (MVE_BAD_SP);
+
+      inst.instruction |= (inst.operands[1].reg << 16);
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+
 static void
 do_vfp_nsyn_cmp (void)
 {
@@ -25243,6 +25277,11 @@ static const struct asm_opcode insns[] =
  mToC("vshllt",	    ee201e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
  mToC("vshllb",	    ee200e00,	   3, (RMQ, RMQ, I32),	    mve_vshll),
 
+ toU("dlstp",	_dlstp, 2, (LR, RR),      t_loloop),
+ toU("wlstp",	_wlstp, 3, (LR, RR, EXP), t_loloop),
+ toU("letp",	_letp,  2, (LR, EXP),	  t_loloop),
+ toU("lctp",	_lctp,  0, (),		  t_loloop),
+
 #undef THUMB_VARIANT
 #define THUMB_VARIANT & mve_fp_ext
  mToC("vcmul", ee300e00,   4, (RMQ, RMQ, RMQ, EXPi),		  mve_vcmul),
@@ -28644,9 +28683,10 @@ md_apply_fix (fixS *	fixP,
 	}
 
       bfd_vma insn = md_chars_to_number (buf, INSN_SIZE);
-      /* le lr, <label> or le <label> */
+      /* le lr, <label>, le <label> or letp lr, <label> */
       if (((insn & 0xffffffff) == 0xc001f00f)
-	  || ((insn & 0xffffffff) == 0xc001f02f))
+	  || ((insn & 0xffffffff) == 0xc001f02f)
+	  || ((insn & 0xffffffff) == 0xc001f01f))
 	value = -value;
 
       if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.d b/gas/testsuite/gas/arm/mve-tailpredloop-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..53c0abcba591bcd685d36d37161d6646348f055f
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.d
@@ -0,0 +1,5 @@
+#name: bad MVE WLSTP, DLSTP and LETP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-tailpredloop-bad.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.l b/gas/testsuite/gas/arm/mve-tailpredloop-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..5e9209ff3e3669b840dd3b7097a07d30f39206be
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.l
@@ -0,0 +1,26 @@
+[^:]*: Assembler messages:
+[^:]*: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: Error: r15 not allowed here -- `wlstp.8 lr,pc,.label'
+[^:]*:29: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:30: Error: r15 not allowed here -- `dlstp.16 lr,pc'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Error: ARM register expected -- `letp .label_back'
+[^:]*:34: Error: branch out of range or not a multiple of 2
+[^:]*:35: Error: branch out of range or not a multiple of 2
diff --git a/gas/testsuite/gas/arm/mve-tailpredloop-bad.s b/gas/testsuite/gas/arm/mve-tailpredloop-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..929722a99c2fae207344f0a5f8b0935efac8f814
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-tailpredloop-bad.s
@@ -0,0 +1,36 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+wlstp.8 lr, r0, .label
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+dlstp.8 lr, r0
+.endr
+.endm
+
+.macro cond3
+.irp cond, eq, ne, gt, ge, lt, le
+it \cond
+letp lr, .label_back
+.endr
+.endm
+
+.label_back:
+.syntax unified
+.thumb
+cond1
+cond2
+cond3
+wlstp.8 lr, pc, .label
+wlstp.8 lr, sp, .label
+dlstp.16 lr, pc
+dlstp.16 lr, sp
+.label:
+letp .label_back
+wlstp.8 lr, r0, .label
+letp lr, .label2
+.label2:

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 37/57][Arm][OBJDUMP] Add framework for MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (37 preceding siblings ...)
  2019-05-01 17:38 ` [PATCH 38/57][Arm][OBJDUMP] Disable the use of MVE reserved coproc numbers in coprocessor instructions Andre Vieira (lists)
@ 2019-05-01 17:38 ` Andre Vieira (lists)
  2019-05-01 17:39 ` [PATCH 39/57][Arm][OBJDUMP] Add support for MVE instructions: vpt, vpst and vcmp Andre Vieira (lists)
                   ` (21 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:38 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 2112 bytes --]

Hi,

This patch adds a framework to OBJDUMP to support MVE instructions.

Since MVE and NEON share some encoding space, but may need a slightly 
different decoding, we decided to split up instruction decoding based on 
whether '-marmv8.1-m.main' has been passed to OBJDUMP.  The new function 
'is_mve_architecture' will check this and direct 'print_insn_thumb32' to 
either use 'print_insn_neon' or 'print_insn_mve'.

This framework also includes helper functions to determine encoding 
conflicts, undefined encodings and unpredictable encodings.  These are 
further implemented for each relevant instruction in subsequent patches.

By encoding conflicts we refer to encodings where two different 
instructions have overlapping base opcodes, but can be distinguished 
based on specific operand values.  In the ISA specification such 
'conflicts' can be identified by looking for clauses that redirect you 
to 'Related Encodings' or specific instructions.  The VMLALDAV 
instruction is an example of the latter, where if RdaHi (bits 20-22) has 
value 7, then the encoding is actually to be decoded as the VMLADAV 
instruction.

This patch also sets force_thumb when passing '-marmv8.1-m.main' to 
objdump. This makes it unnecessary to use '-M force-thumb' when 
disassembling for non-elf targets.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): New enum.
	(enum mve_unpredictable): Likewise.
	(enum mve_undefined): Likewise.
	(struct mopcode32): New struct.
	(is_mve_okay_in_it): New function.
	(is_mve_architecture): Likewise.
	(arm_decode_field): Likewise.
	(arm_decode_field_multiple): Likewise.
	(is_mve_encoding_conflict): Likewise.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_unpredictable): Likewise.
	(print_insn_coprocessor_1): Use arm_decode_field_multiple.
	(print_insn_mve): New function.
	(print_insn_thumb32): Handle MVE architecture.
         (select_arm_features): Force thumb for Armv8.1-m Mainline.

[-- Attachment #2: 37.patch --]
[-- Type: text/x-patch, Size: 9456 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 15d4d7248ea66f4b61278c708b796b3a5a23570b..6452d7c514bea751430a4906fa0ad4c8c8a136e8 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -68,6 +68,23 @@ struct arm_private_data
   bfd_vma last_mapping_addr;
 };
 
+enum mve_instructions
+{
+  MVE_NONE
+};
+
+enum mve_unpredictable
+{
+  UNPRED_IT_BLOCK,		/* Unpredictable because mve insn in it block.
+				 */
+  UNPRED_NONE			/* No unpredictable behavior.  */
+};
+
+enum mve_undefined
+{
+  UNDEF_NONE			/* no undefined behavior.  */
+};
+
 struct opcode32
 {
   arm_feature_set arch;		/* Architecture defining this insn.  */
@@ -76,6 +93,18 @@ struct opcode32
   const char *  assembler;	/* How to disassemble this insn.  */
 };
 
+/* MVE opcodes.  */
+
+struct mopcode32
+{
+  arm_feature_set arch;		/* Architecture defining this insn.  */
+  enum mve_instructions mve_op;  /* Specific mve instruction for faster
+				    decoding.  */
+  unsigned long value;		/* If arch is 0 then value is a sentinel.  */
+  unsigned long mask;		/* Recognise insn if (op & mask) == value.  */
+  const char *  assembler;	/* How to disassemble this insn.  */
+};
+
 enum isa {
   ANY,
   T32,
@@ -1756,6 +1785,18 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_CORE_LOW (0), 0 ,0, 0}
 };
 
+/* mve opcode table.  */
+
+/* print_insn_mve recognizes the following format control codes:
+
+   %%			%
+
+   */
+
+static const struct mopcode32 mve_opcodes[] =
+{
+};
+
 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
    ordered: they must be searched linearly from the top to obtain a correct
    match.  */
@@ -3449,6 +3490,105 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
     }
 }
 
+/* Return TRUE if the MATCHED_INSN can be inside an IT block.  */
+
+static bfd_boolean
+is_mve_okay_in_it (enum mve_instructions matched_insn)
+{
+  return FALSE;
+}
+
+static bfd_boolean
+is_mve_architecture (struct disassemble_info *info)
+{
+  struct arm_private_data *private_data = info->private_data;
+  arm_feature_set allowed_arches = private_data->features;
+
+  arm_feature_set arm_ext_v8_1m_main
+    = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
+
+  if (ARM_CPU_HAS_FEATURE (arm_ext_v8_1m_main, allowed_arches)
+      && !ARM_CPU_IS_ANY (allowed_arches))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/* Decode a bitfield from opcode GIVEN, with starting bitfield = START
+   and ending bitfield = END.  END must be greater than START.  */
+
+static unsigned long
+arm_decode_field (unsigned long given, unsigned int start, unsigned int end)
+{
+  int bits = end - start;
+
+  if (bits < 0)
+    abort ();
+
+  return ((given >> start) & ((2ul << bits) - 1));
+}
+
+/* Decode a bitfield from opcode GIVEN, with multiple bitfields:
+   START:END and START2:END2.  END/END2 must be greater than
+   START/START2.  */
+
+static unsigned long
+arm_decode_field_multiple (unsigned long given, unsigned int start,
+			   unsigned int end, unsigned int start2,
+			   unsigned int end2)
+{
+  int bits = end - start;
+  int bits2 = end2 - start2;
+  unsigned long value = 0;
+  int width = 0;
+
+  if (bits2 < 0)
+    abort ();
+
+  value = arm_decode_field (given, start, end);
+  width += bits + 1;
+
+  value |= ((given >> start2) & ((2ul << bits2) - 1)) << width;
+  return value;
+}
+
+/* Return TRUE if the GIVEN encoding should not be decoded as MATCHED_INSN.
+   This helps us decode instructions that change mnemonic depending on specific
+   operand values/encodings.  */
+
+static bfd_boolean
+is_mve_encoding_conflict (unsigned long given,
+			  enum mve_instructions matched_insn)
+{
+  return FALSE;
+}
+
+/* Return FALSE if GIVEN is not an undefined encoding for MATCHED_INSN.
+   Otherwise, return TRUE and set UNDEFINED_CODE to give a reason as to why
+   this encoding is undefined.  */
+
+static bfd_boolean
+is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
+		  enum mve_undefined *undefined_code)
+{
+  *undefined_code = UNDEF_NONE;
+
+  return FALSE;
+}
+
+/* Return FALSE if GIVEN is not an unpredictable encoding for MATCHED_INSN.
+   Otherwise, return TRUE and set UNPREDICTABLE_CODE to give a reason as to
+   why this encoding is unpredictable.  */
+
+static bfd_boolean
+is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
+		      enum mve_unpredictable *unpredictable_code)
+{
+  *unpredictable_code = UNPRED_NONE;
+
+  return FALSE;
+}
+
 #define W_BIT 21
 #define I_BIT 22
 #define U_BIT 23
@@ -3459,6 +3599,43 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
 #define NEGATIVE_BIT_SET   ((given & (1 << U_BIT)) == 0)
 #define PRE_BIT_SET         (given & (1 << P_BIT))
 
+static void
+print_mve_undefined (struct disassemble_info *info,
+		     enum mve_undefined undefined_code)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  func (stream, "\t\tundefined instruction: ");
+
+  switch (undefined_code)
+    {
+    case UNDEF_NONE:
+      break;
+    }
+
+}
+
+static void
+print_mve_unpredictable (struct disassemble_info *info,
+			 enum mve_unpredictable unpredict_code)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  func (stream, "%s: ", UNPREDICTABLE_INSTRUCTION);
+
+  switch (unpredict_code)
+    {
+    case UNPRED_IT_BLOCK:
+      func (stream, "mve instruction in it block");
+      break;
+
+    case UNPRED_NONE:
+      break;
+    }
+}
+
 /* Print one coprocessor instruction on INFO->STREAM.
    Return TRUE if the instuction matched, FALSE if this is not a
    recognised coprocessor instruction.  */
@@ -3737,7 +3914,8 @@ print_insn_coprocessor_1 (const struct sopcode32 *opcodes,
 
 		case 'J':
 		  {
-		    int regno = ((given >> 19) & 0x8) | ((given >> 13) & 0x7);
+		    unsigned long regno
+		      = arm_decode_field_multiple (given, 13, 15, 22, 22);
 
 		    switch (regno)
 		      {
@@ -3760,7 +3938,7 @@ print_insn_coprocessor_1 (const struct sopcode32 *opcodes,
 			func (stream, "FPCXTS");
 			break;
 		      default:
-			func (stream, "<invalid reg %d>", regno);
+			func (stream, "<invalid reg %lu>", regno);
 			break;
 		      }
 		  }
@@ -4774,6 +4952,75 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
   return FALSE;
 }
 
+/* Print one mve instruction on INFO->STREAM.
+   Return TRUE if the instuction matched, FALSE if this is not a
+   recognised mve instruction.  */
+
+static bfd_boolean
+print_insn_mve (struct disassemble_info *info, long given)
+{
+  const struct mopcode32 *insn;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  for (insn = mve_opcodes; insn->assembler; insn++)
+    {
+      if (((given & insn->mask) == insn->value)
+	  && !is_mve_encoding_conflict (given, insn->mve_op))
+	{
+	  signed long value_in_comment = 0;
+	  bfd_boolean is_unpredictable = FALSE;
+	  bfd_boolean is_undefined = FALSE;
+	  const char *c;
+	  enum mve_unpredictable unpredictable_cond = UNPRED_NONE;
+	  enum mve_undefined undefined_cond = UNDEF_NONE;
+
+	  /* Most vector mve instruction are illegal in a it block.
+	     There are a few exceptions; check for them.  */
+	  if (ifthen_state && !is_mve_okay_in_it (insn->mve_op))
+	    {
+	      is_unpredictable = TRUE;
+	      unpredictable_cond = UNPRED_IT_BLOCK;
+	    }
+	  else if (is_mve_unpredictable (given, insn->mve_op,
+					 &unpredictable_cond))
+	    is_unpredictable = TRUE;
+
+	  if (is_mve_undefined (given, insn->mve_op, &undefined_cond))
+	    is_undefined = TRUE;
+
+	  for (c = insn->assembler; *c; c++)
+	    {
+	      if (*c == '%')
+		{
+		  switch (*++c)
+		    {
+		    case '%':
+		      func (stream, "%%");
+		      break;
+
+		    }
+		}
+	      else
+		func (stream, "%c", *c);
+	    }
+
+	  if (value_in_comment > 32 || value_in_comment < -16)
+	    func (stream, "\t; 0x%lx", value_in_comment);
+
+	  if (is_unpredictable)
+	    print_mve_unpredictable (info, unpredictable_cond);
+
+	  if (is_undefined)
+	    print_mve_undefined (info, undefined_cond);
+
+	  return TRUE;
+	}
+    }
+  return FALSE;
+}
+
+
 /* Return the name of a v7A special register.  */
 
 static const char *
@@ -5687,11 +5934,15 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
   const struct opcode32 *insn;
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
+  bfd_boolean is_mve = is_mve_architecture (info);
 
   if (print_insn_coprocessor (pc, info, given, TRUE))
     return;
 
-  if (print_insn_neon (info, given, TRUE))
+  if ((is_mve == FALSE) && print_insn_neon (info, given, TRUE))
+    return;
+
+  if (is_mve && print_insn_mve (info, given))
     return;
 
   if (print_insn_generic_coprocessor (pc, info, given, TRUE))
@@ -6739,7 +6990,10 @@ select_arm_features (unsigned long mach,
     case bfd_mach_arm_8R:	 ARM_SET_FEATURES (ARM_ARCH_V8R); break;
     case bfd_mach_arm_8M_BASE:	 ARM_SET_FEATURES (ARM_ARCH_V8M_BASE); break;
     case bfd_mach_arm_8M_MAIN:	 ARM_SET_FEATURES (ARM_ARCH_V8M_MAIN); break;
-    case bfd_mach_arm_8_1M_MAIN: ARM_SET_FEATURES (ARM_ARCH_V8_1M_MAIN); break;
+    case bfd_mach_arm_8_1M_MAIN:
+      ARM_SET_FEATURES (ARM_ARCH_V8_1M_MAIN);
+      force_thumb = 1;
+      break;
       /* If the machine type is unknown allow all architecture types and all
 	 extensions.  */
     case bfd_mach_arm_unknown:	 ARM_SET_FEATURES (ARM_FEATURE_ALL); break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 38/57][Arm][OBJDUMP] Disable the use of MVE reserved coproc numbers in coprocessor instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (36 preceding siblings ...)
  2019-05-01 17:36 ` [PATCH 35/57][Arm][GAS] Add support for MVE instructions: vshlc and vshll Andre Vieira (lists)
@ 2019-05-01 17:38 ` Andre Vieira (lists)
  2019-05-01 17:38 ` [PATCH 37/57][Arm][OBJDUMP] Add framework for MVE instructions Andre Vieira (lists)
                   ` (22 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:38 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 401 bytes --]

Hi,

This patch disables the use of coprocessor numbers 8, 14 and 15 in 
coprocessor instructions for Armv8.1-M Mainline, adding to the already 
disabled 9, 10 and 11, as mandated by the architecture.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* arm-dis.c (print_insn_coprocessor_1): Disable the use of coprocessors
         8, 14 and 15 for Armv8.1-M Mainline.

[-- Attachment #2: 38.patch --]
[-- Type: text/x-patch, Size: 717 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 28c7f16de4b39f6aa580a0a9f4d4d775e1c4b768..8cd3514e7e53fc3a61ee97c7df1988c11a8143d0 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -3782,6 +3782,13 @@ print_insn_coprocessor_1 (const struct sopcode32 *opcodes,
 	{
 	  if (cp_num == 9 || cp_num == 10 || cp_num == 11)
 	    is_unpredictable = TRUE;
+
+	  /* Armv8.1-M Mainline FP & MVE instructions.  */
+	  if (ARM_CPU_HAS_FEATURE (arm_ext_v8_1m_main, allowed_arches)
+	      && !ARM_CPU_IS_ANY (allowed_arches)
+	      && (cp_num == 8 || cp_num == 14 || cp_num == 15))
+	    continue;
+
 	}
       else if (insn->value == 0x0e000000     /* cdp  */
 	       || insn->value == 0xfe000000  /* cdp2  */

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 39/57][Arm][OBJDUMP] Add support for MVE instructions: vpt, vpst and vcmp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (38 preceding siblings ...)
  2019-05-01 17:38 ` [PATCH 37/57][Arm][OBJDUMP] Add framework for MVE instructions Andre Vieira (lists)
@ 2019-05-01 17:39 ` Andre Vieira (lists)
  2019-05-01 17:40 ` [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24] Andre Vieira (lists)
                   ` (20 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:39 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1453 bytes --]

Hi,

This patch adds support for MVE instructions VPT, VPST, and VCMP.

This patch also adds a framework to parse VPT/VPST blocks and 
instructions therein.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new values.
         (mve_opcodes): Add new instructions.
         (vec_condnames): New array with vector conditions.
         (mve_predicatenames): New array with predicate suffixes.
         (mve_vec_sizename): New array with vector sizes.
         (enum vpt_pred_state): New enum with vector predication states.
	(struct vpt_block): New struct type for vpt blocks.
         (vpt_block_state): Global struct to keep track of state.
	(mve_extract_pred_mask): New helper function.
	(num_instructions_vpt_block): Likewise.
	(mark_outside_vpt_block): Likewise.
	(mark_inside_vpt_block): Likewise.
	(invert_next_predicate_state): Likewise.
	(update_next_predicate_state): Likewise.
	(update_vpt_block_state): Likewise.
	(is_vpt_instruction): Likewise.
	(is_mve_encoding_conflict): Add entries for new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_unpredictable): Handle new cases.
	(print_instruction_predicate): Likewise.
	(print_mve_size): New function.
	(print_vec_condition): New function.
	(print_insn_mve): Handle vpt blocks and new print operands.

[-- Attachment #2: 39.patch --]
[-- Type: text/x-patch, Size: 20230 bytes --]

diff --git a/gas/testsuite/gas/arm/mve-vpst-bad.l b/gas/testsuite/gas/arm/mve-vpst-bad.l
index 35a56890c85fd44ac22e47ea97b3bddd6811f14e..9a396ae6459db53939d0cfc9f58358c965712697 100644
--- a/gas/testsuite/gas/arm/mve-vpst-bad.l
+++ b/gas/testsuite/gas/arm/mve-vpst-bad.l
@@ -16,4 +16,4 @@
 [^:]*:55: Warning: instruction is UNPREDICTABLE in an IT block
 [^:]*:62: Error: incorrect condition in VPT/VPST block -- `vaddt.i32 q0,q1,q2'
 [^:]*:65: Error: syntax error -- `vaddeq.i32 q0,q1,q2'
-[^:]*:68: Warning: section '.text' finished with an open VPT/VPST block.
+[^:]*:68: Warning: .* finished with an open VPT/VPST block.
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.l b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
index 28bd9d6047de0fc0592b7b75ee48f3b086f1f879..99036d29120aede14cd66217bf0564da42817bc3 100644
--- a/gas/testsuite/gas/arm/mve-vpt-bad-1.l
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
@@ -20,4 +20,4 @@
 [^:]*:23: Error: syntax error -- `vpteq.i8 eq,q0,q1'
 [^:]*:26: Warning: instruction is UNPREDICTABLE in a VPT block
 [^:]*:27: Warning: instruction is UNPREDICTABLE in a VPT block
-[^:]*:30: Warning: section '.text' finished with an open VPT/VPST block.
+[^:]*:30: Warning: .* finished with an open VPT/VPST block.
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.l b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
index 678a824eef64d15a7a1add12d84157f80f1555f7..9f11fe890fa00e60ae2f9d1712cd0e7f8b49dcb4 100644
--- a/gas/testsuite/gas/arm/mve-vpt-bad-2.l
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
@@ -17,5 +17,5 @@
 [^:]*:20: Error: syntax error -- `vpteq.f32 eq,q0,q1'
 [^:]*:23: Warning: instruction is UNPREDICTABLE in a VPT block
 [^:]*:24: Warning: instruction is UNPREDICTABLE in a VPT block
-[^:]*:27: Warning: section '.text' finished with an open VPT/VPST block.
+[^:]*:27: Warning: .* finished with an open VPT/VPST block.
 
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index ddf707d6b1f90e46b6e144c84cbf404ead00c806..84ee48d1f5005d16b097a4628d4d9ad252dc7ad5 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -21,6 +21,7 @@
    MA 02110-1301, USA.  */
 
 #include "sysdep.h"
+#include <assert.h>
 
 #include "disassemble.h"
 #include "opcode/arm.h"
@@ -69,6 +70,23 @@ struct arm_private_data
 
 enum mve_instructions
 {
+  MVE_VPST,
+  MVE_VPT_FP_T1,
+  MVE_VPT_FP_T2,
+  MVE_VPT_VEC_T1,
+  MVE_VPT_VEC_T2,
+  MVE_VPT_VEC_T3,
+  MVE_VPT_VEC_T4,
+  MVE_VPT_VEC_T5,
+  MVE_VPT_VEC_T6,
+  MVE_VCMP_FP_T1,
+  MVE_VCMP_FP_T2,
+  MVE_VCMP_VEC_T1,
+  MVE_VCMP_VEC_T2,
+  MVE_VCMP_VEC_T3,
+  MVE_VCMP_VEC_T4,
+  MVE_VCMP_VEC_T5,
+  MVE_VCMP_VEC_T6,
   MVE_NONE
 };
 
@@ -76,6 +94,10 @@ enum mve_unpredictable
 {
   UNPRED_IT_BLOCK,		/* Unpredictable because mve insn in it block.
 				 */
+  UNPRED_FCA_0_FCB_1,		/* Unpredictable because fcA = 0 and
+				   fcB = 1 (vpt).  */
+  UNPRED_R13,			/* Unpredictable because r13 (sp) or
+				   r15 (sp) used.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
@@ -1781,10 +1803,114 @@ static const struct opcode32 neon_opcodes[] =
 
    %%			%
 
-   */
+   %i			print MVE predicate(s) for vpt and vpst
+   %n			print vector comparison code for predicated instruction
+   %v			print vector predicate for instruction in predicated
+			block
+   %<bitfield>Q		print as a MVE Q register
+   %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
+			UNPREDICTABLE
+   %<bitfield>s		print size for vector predicate & non VMOV instructions
+*/
 
 static const struct mopcode32 mve_opcodes[] =
 {
+  /* MVE.  */
+
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPST,
+   0xfe310f4d, 0xffbf1fff,
+   "vpst%i"
+  },
+
+  /* Floating point VPT T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VPT_FP_T1,
+   0xee310f00, 0xefb10f50,
+   "vpt%i.f%28s\t%n, %17-19Q, %1-3,5Q"},
+  /* Floating point VPT T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VPT_FP_T2,
+   0xee310f40, 0xefb10f50,
+   "vpt%i.f%28s\t%n, %17-19Q, %0-3Z"},
+
+  /* Vector VPT T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T1,
+   0xfe010f00, 0xff811f51,
+   "vpt%i.i%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VPT T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T2,
+   0xfe010f01, 0xff811f51,
+   "vpt%i.u%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VPT T3.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T3,
+   0xfe011f00, 0xff811f50,
+   "vpt%i.s%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VPT T4.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T4,
+   0xfe010f40, 0xff811f70,
+   "vpt%i.i%20-21s\t%n, %17-19Q, %0-3Z"},
+  /* Vector VPT T5.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T5,
+   0xfe010f60, 0xff811f70,
+   "vpt%i.u%20-21s\t%n, %17-19Q, %0-3Z"},
+  /* Vector VPT T6.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPT_VEC_T6,
+   0xfe011f40, 0xff811f50,
+   "vpt%i.s%20-21s\t%n, %17-19Q, %0-3Z"},
+
+  /* Vector VCMP floating point T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMP_FP_T1,
+   0xee310f00, 0xeff1ef50,
+   "vcmp%v.f%28s\t%n, %17-19Q, %1-3,5Q"},
+
+  /* Vector VCMP floating point T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMP_FP_T2,
+   0xee310f40, 0xeff1ef50,
+   "vcmp%v.f%28s\t%n, %17-19Q, %0-3Z"},
+
+  /* Vector VCMP T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T1,
+   0xfe010f00, 0xffc1ff51,
+   "vcmp%v.i%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VCMP T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T2,
+   0xfe010f01, 0xffc1ff51,
+   "vcmp%v.u%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VCMP T3.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T3,
+   0xfe011f00, 0xffc1ff50,
+   "vcmp%v.s%20-21s\t%n, %17-19Q, %1-3,5Q"},
+  /* Vector VCMP T4.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T4,
+   0xfe010f40, 0xffc1ff70,
+   "vcmp%v.i%20-21s\t%n, %17-19Q, %0-3Z"},
+  /* Vector VCMP T5.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T5,
+   0xfe010f60, 0xffc1ff70,
+   "vcmp%v.u%20-21s\t%n, %17-19Q, %0-3Z"},
+  /* Vector VCMP T6.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCMP_VEC_T6,
+   0xfe011f40, 0xffc1ff50,
+   "vcmp%v.s%20-21s\t%n, %17-19Q, %0-3Z"},
+
+  {ARM_FEATURE_CORE_LOW (0),
+   MVE_NONE,
+   0x00000000, 0x00000000, 0}
 };
 
 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
@@ -3379,6 +3505,56 @@ static const char *const iwmmxt_cregnames[] =
   "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
 };
 
+static const char *const vec_condnames[] =
+{ "eq", "ne", "cs", "hi", "ge", "lt", "gt", "le"
+};
+
+static const char *const mve_predicatenames[] =
+{ "", "ttt", "tt", "tte", "t", "tee", "te", "tet", "",
+  "eee", "ee", "eet", "e", "ett", "et", "ete"
+};
+
+/* Names for 2-bit size field for mve vector isntructions.  */
+static const char *const mve_vec_sizename[] =
+  { "8", "16", "32", "64"};
+
+/* Indicates whether we are processing a then predicate,
+   else predicate or none at all.  */
+enum vpt_pred_state
+{
+  PRED_NONE,
+  PRED_THEN,
+  PRED_ELSE
+};
+
+/* Information used to process a vpt block and subsequent instructions.  */
+struct vpt_block
+{
+  /* Are we in a vpt block.  */
+  bfd_boolean in_vpt_block;
+
+  /* Next predicate state if in vpt block.  */
+  enum vpt_pred_state next_pred_state;
+
+  /* Mask from vpt/vpst instruction.  */
+  long predicate_mask;
+
+  /* Instruction number in vpt block.  */
+  long current_insn_num;
+
+  /* Number of instructions in vpt block..   */
+  long num_pred_insn;
+};
+
+static struct vpt_block vpt_block_state =
+{
+  FALSE,
+  PRED_NONE,
+  0,
+  0,
+  0
+};
+
 /* Default to GCC register name set.  */
 static unsigned int regname_selected = 1;
 
@@ -3401,6 +3577,113 @@ static bfd_vma ifthen_address;
 
 \f
 /* Functions.  */
+/* Extract the predicate mask for a VPT or VPST instruction.
+   The mask is composed of bits 13-15 (Mkl) and bit 22 (Mkh).  */
+
+static long
+mve_extract_pred_mask (long given)
+{
+  return ((given & 0x00400000) >> 19) | ((given & 0xe000) >> 13);
+}
+
+/* Return the number of instructions in a MVE predicate block.  */
+static long
+num_instructions_vpt_block (long given)
+{
+  long mask = mve_extract_pred_mask (given);
+  if (mask == 0)
+    return 0;
+
+  if (mask == 8)
+    return 1;
+
+  if ((mask & 7) == 4)
+    return 2;
+
+  if ((mask & 3) == 2)
+    return 3;
+
+  if ((mask & 1) == 1)
+    return 4;
+
+  return 0;
+}
+
+static void
+mark_outside_vpt_block (void)
+{
+  vpt_block_state.in_vpt_block = FALSE;
+  vpt_block_state.next_pred_state = PRED_NONE;
+  vpt_block_state.predicate_mask = 0;
+  vpt_block_state.current_insn_num = 0;
+  vpt_block_state.num_pred_insn = 0;
+}
+
+static void
+mark_inside_vpt_block (long given)
+{
+  vpt_block_state.in_vpt_block = TRUE;
+  vpt_block_state.next_pred_state = PRED_THEN;
+  vpt_block_state.predicate_mask = mve_extract_pred_mask (given);
+  vpt_block_state.current_insn_num = 0;
+  vpt_block_state.num_pred_insn = num_instructions_vpt_block (given);
+  assert (vpt_block_state.num_pred_insn >= 1);
+}
+
+static enum vpt_pred_state
+invert_next_predicate_state (enum vpt_pred_state astate)
+{
+  if (astate == PRED_THEN)
+    return PRED_ELSE;
+  else if (astate == PRED_ELSE)
+    return PRED_THEN;
+  else
+    return PRED_NONE;
+}
+
+static enum vpt_pred_state
+update_next_predicate_state (void)
+{
+  long pred_mask = vpt_block_state.predicate_mask;
+  long mask_for_insn = 0;
+
+  switch (vpt_block_state.current_insn_num)
+    {
+    case 1:
+      mask_for_insn = 8;
+      break;
+
+    case 2:
+      mask_for_insn = 4;
+      break;
+
+    case 3:
+      mask_for_insn = 2;
+      break;
+
+    case 4:
+      return PRED_NONE;
+    }
+
+  if (pred_mask & mask_for_insn)
+    return invert_next_predicate_state (vpt_block_state.next_pred_state);
+  else
+    return vpt_block_state.next_pred_state;
+}
+
+static void
+update_vpt_block_state (void)
+{
+  vpt_block_state.current_insn_num++;
+  if (vpt_block_state.current_insn_num == vpt_block_state.num_pred_insn)
+    {
+      /* No more instructions to process in vpt block.  */
+      mark_outside_vpt_block ();
+      return;
+    }
+
+  vpt_block_state.next_pred_state = update_next_predicate_state ();
+}
 
 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
    Returns pointer to following character of the format string and
@@ -3504,6 +3787,38 @@ is_mve_architecture (struct disassemble_info *info)
     return FALSE;
 }
 
+static bfd_boolean
+is_vpt_instruction (long given)
+{
+
+  /* If mkh:mkl is '0000' then its not a vpt/vpst instruction.  */
+  if ((given & 0x0040e000) == 0)
+    return FALSE;
+
+  /* VPT floating point T1 variant.  */
+  if (((given & 0xefb10f50) == 0xee310f00 && ((given & 0x1001) != 0x1))
+  /* VPT floating point T2 variant.  */
+      || ((given & 0xefb10f50) == 0xee310f40)
+  /* VPT vector T1 variant.  */
+      || ((given & 0xff811f51) == 0xfe010f00)
+  /* VPT vector T2 variant.  */
+      || ((given & 0xff811f51) == 0xfe010f01
+	  && ((given & 0x300000) != 0x300000))
+  /* VPT vector T3 variant.  */
+      || ((given & 0xff811f50) == 0xfe011f00)
+  /* VPT vector T4 variant.  */
+      || ((given & 0xff811f70) == 0xfe010f40)
+  /* VPT vector T5 variant.  */
+      || ((given & 0xff811f70) == 0xfe010f60)
+  /* VPT vector T6 variant.  */
+      || ((given & 0xff811f50) == 0xfe011f40)
+  /* VPST vector T variant.  */
+      || ((given & 0xffbf1fff) == 0xfe310f4d))
+    return TRUE;
+  else
+    return FALSE;
+}
+
 /* Decode a bitfield from opcode GIVEN, with starting bitfield = START
    and ending bitfield = END.  END must be greater than START.  */
 
@@ -3550,7 +3865,69 @@ static bfd_boolean
 is_mve_encoding_conflict (unsigned long given,
 			  enum mve_instructions matched_insn)
 {
-  return FALSE;
+  switch (matched_insn)
+    {
+    case MVE_VPST:
+      if (arm_decode_field_multiple (given, 13, 15, 22, 22) == 0)
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VPT_FP_T1:
+      if (arm_decode_field_multiple (given, 13, 15, 22, 22) == 0)
+	return TRUE;
+      if ((arm_decode_field (given, 12, 12) == 0)
+	  && (arm_decode_field (given, 0, 0) == 1))
+	return TRUE;
+      return FALSE;
+
+    case MVE_VPT_FP_T2:
+      if (arm_decode_field_multiple (given, 13, 15, 22, 22) == 0)
+	return TRUE;
+      if (arm_decode_field (given, 0, 3) == 0xd)
+	return TRUE;
+      return FALSE;
+
+    case MVE_VPT_VEC_T1:
+    case MVE_VPT_VEC_T2:
+    case MVE_VPT_VEC_T3:
+    case MVE_VPT_VEC_T4:
+    case MVE_VPT_VEC_T5:
+    case MVE_VPT_VEC_T6:
+      if (arm_decode_field_multiple (given, 13, 15, 22, 22) == 0)
+	return TRUE;
+      if (arm_decode_field (given, 20, 21) == 3)
+	return TRUE;
+      return FALSE;
+
+    case MVE_VCMP_FP_T1:
+      if ((arm_decode_field (given, 12, 12) == 0)
+	  && (arm_decode_field (given, 0, 0) == 1))
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VCMP_FP_T2:
+      if (arm_decode_field (given, 0, 3) == 0xd)
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VCMP_VEC_T1:
+    case MVE_VCMP_VEC_T2:
+    case MVE_VCMP_VEC_T3:
+    case MVE_VCMP_VEC_T4:
+    case MVE_VCMP_VEC_T5:
+    case MVE_VCMP_VEC_T6:
+      if (arm_decode_field (given, 20, 21) == 3)
+	return TRUE;
+      else
+	return FALSE;
+
+    default:
+      return FALSE;
+
+    }
 }
 
 /* Return FALSE if GIVEN is not an undefined encoding for MATCHED_INSN.
@@ -3576,18 +3953,37 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 {
   *unpredictable_code = UNPRED_NONE;
 
-  return FALSE;
-}
+  switch (matched_insn)
+    {
+    case MVE_VCMP_FP_T2:
+    case MVE_VPT_FP_T2:
+      if ((arm_decode_field (given, 12, 12) == 0)
+	  && (arm_decode_field (given, 5, 5) == 1))
+	{
+	  *unpredictable_code = UNPRED_FCA_0_FCB_1;
+	  return TRUE;
+	}
+      else
+	return FALSE;
 
-#define W_BIT 21
-#define I_BIT 22
-#define U_BIT 23
-#define P_BIT 24
+    case MVE_VPT_VEC_T4:
+    case MVE_VPT_VEC_T5:
+    case MVE_VPT_VEC_T6:
+    case MVE_VCMP_VEC_T4:
+    case MVE_VCMP_VEC_T5:
+    case MVE_VCMP_VEC_T6:
+      if (arm_decode_field (given, 0, 3) == 0xd)
+	{
+	  *unpredictable_code = UNPRED_R13;
+	  return TRUE;
+	}
+      else
+	return FALSE;
 
-#define WRITEBACK_BIT_SET   (given & (1 << W_BIT))
-#define IMMEDIATE_BIT_SET   (given & (1 << I_BIT))
-#define NEGATIVE_BIT_SET   ((given & (1 << U_BIT)) == 0)
-#define PRE_BIT_SET         (given & (1 << P_BIT))
+    default:
+      return FALSE;
+    }
+}
 
 static void
 print_mve_undefined (struct disassemble_info *info,
@@ -3621,11 +4017,154 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "mve instruction in it block");
       break;
 
+    case UNPRED_FCA_0_FCB_1:
+      func (stream, "condition bits, fca = 0 and fcb = 1");
+      break;
+
+    case UNPRED_R13:
+      func (stream, "use of r13 (sp)");
+      break;
+
     case UNPRED_NONE:
       break;
     }
 }
 
+static void
+print_instruction_predicate (struct disassemble_info *info)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  if (vpt_block_state.next_pred_state == PRED_THEN)
+    func (stream, "t");
+  else if (vpt_block_state.next_pred_state == PRED_ELSE)
+    func (stream, "e");
+}
+
+static void
+print_mve_size (struct disassemble_info *info,
+		unsigned long size,
+		enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (matched_insn)
+    {
+    case MVE_VCMP_VEC_T1:
+    case MVE_VCMP_VEC_T2:
+    case MVE_VCMP_VEC_T3:
+    case MVE_VCMP_VEC_T4:
+    case MVE_VCMP_VEC_T5:
+    case MVE_VCMP_VEC_T6:
+    case MVE_VPT_VEC_T1:
+    case MVE_VPT_VEC_T2:
+    case MVE_VPT_VEC_T3:
+    case MVE_VPT_VEC_T4:
+    case MVE_VPT_VEC_T5:
+    case MVE_VPT_VEC_T6:
+      if (size <= 3)
+	func (stream, "%s", mve_vec_sizename[size]);
+      else
+	func (stream, "<undef size>");
+      break;
+
+    case MVE_VCMP_FP_T1:
+    case MVE_VCMP_FP_T2:
+    case MVE_VPT_FP_T1:
+    case MVE_VPT_FP_T2:
+      if (size == 0)
+	func (stream, "32");
+      else if (size == 1)
+	func (stream, "16");
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+print_vec_condition (struct disassemble_info *info, long given,
+		     enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+  long vec_cond = 0;
+
+  switch (matched_insn)
+    {
+    case MVE_VPT_FP_T1:
+    case MVE_VCMP_FP_T1:
+      vec_cond = (((given & 0x1000) >> 10)
+		  | ((given & 1) << 1)
+		  | ((given & 0x0080) >> 7));
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_FP_T2:
+    case MVE_VCMP_FP_T2:
+      vec_cond = (((given & 0x1000) >> 10)
+		  | ((given & 0x0020) >> 4)
+		  | ((given & 0x0080) >> 7));
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T1:
+    case MVE_VCMP_VEC_T1:
+      vec_cond = (given & 0x0080) >> 7;
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T2:
+    case MVE_VCMP_VEC_T2:
+      vec_cond = 2 | ((given & 0x0080) >> 7);
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T3:
+    case MVE_VCMP_VEC_T3:
+      vec_cond = 4 | ((given & 1) << 1) | ((given & 0x0080) >> 7);
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T4:
+    case MVE_VCMP_VEC_T4:
+      vec_cond = (given & 0x0080) >> 7;
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T5:
+    case MVE_VCMP_VEC_T5:
+      vec_cond = 2 | ((given & 0x0080) >> 7);
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_VPT_VEC_T6:
+    case MVE_VCMP_VEC_T6:
+      vec_cond = 4 | ((given & 0x0020) >> 4) | ((given & 0x0080) >> 7);
+      func (stream, "%s",vec_condnames[vec_cond]);
+      break;
+
+    case MVE_NONE:
+    case MVE_VPST:
+    default:
+      break;
+    }
+}
+
+#define W_BIT 21
+#define I_BIT 22
+#define U_BIT 23
+#define P_BIT 24
+
+#define WRITEBACK_BIT_SET (given & (1 << W_BIT))
+#define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
+#define NEGATIVE_BIT_SET  ((given & (1 << U_BIT)) == 0)
+#define PRE_BIT_SET	  (given & (1 << P_BIT))
+
+
 /* Print one coprocessor instruction on INFO->STREAM.
    Return TRUE if the instuction matched, FALSE if this is not a
    recognised coprocessor instruction.  */
@@ -4975,6 +5514,62 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      func (stream, "%%");
 		      break;
 
+		    case 'c':
+		      if (ifthen_state)
+			func (stream, "%s", arm_conditional[IFTHEN_COND]);
+		      break;
+
+		    case 'i':
+		      {
+			long mve_mask = mve_extract_pred_mask (given);
+			func (stream, "%s", mve_predicatenames[mve_mask]);
+		      }
+		      break;
+
+		    case 'n':
+		      print_vec_condition (info, given, insn->mve_op);
+		      break;
+
+		    case 'v':
+		      print_instruction_predicate (info);
+		      break;
+
+		    case '0': case '1': case '2': case '3': case '4':
+		    case '5': case '6': case '7': case '8': case '9':
+		      {
+			int width;
+			unsigned long value;
+
+			c = arm_decode_bitfield (c, given, &value, &width);
+
+			switch (*c)
+			  {
+			  case 'Z':
+			    if (value == 13)
+			      is_unpredictable = TRUE;
+			    else if (value == 15)
+			      func (stream, "zr");
+			    else
+			      func (stream, "%s", arm_regnames[value]);
+			    break;
+			  case 's':
+			    print_mve_size (info,
+					    value,
+					    insn->mve_op);
+			    break;
+			  case 'Q':
+			    if (value & 0x8)
+			      func (stream, "<illegal reg q%ld.5>", value);
+			    else
+			      func (stream, "q%ld", value);
+			    break;
+			  default:
+			    abort ();
+			  }
+			break;
+		      default:
+			abort ();
+		      }
 		    }
 		}
 	      else
@@ -4990,6 +5585,13 @@ print_insn_mve (struct disassemble_info *info, long given)
 	  if (is_undefined)
 	    print_mve_undefined (info, undefined_cond);
 
+	  if ((vpt_block_state.in_vpt_block == FALSE)
+	      && !ifthen_state
+	      && (is_vpt_instruction (given) == TRUE))
+	    mark_inside_vpt_block (given);
+	  else if (vpt_block_state.in_vpt_block == TRUE)
+	    update_vpt_block_state ();
+
 	  return TRUE;
 	}
     }

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms, vhadd, vhsub and vrhadd
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (40 preceding siblings ...)
  2019-05-01 17:40 ` [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24] Andre Vieira (lists)
@ 2019-05-01 17:40 ` Andre Vieira (lists)
  2019-05-01 17:41 ` [PATCH 42/57][Arm][OBJDUMP] Add support for MVE instructions: vldr[bhw] and vstr[bhw] Andre Vieira (lists)
                   ` (18 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:40 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1106 bytes --]

Hi,

This patch adds support for MVE instructions VDUP, VEOR, VFMA, VFMS, 
VHADD, VHSUB, and VRHADD.

This patch also moves NEON's VDUP instruction to the 'neon_opcodes' 
table, since the 'coprocessor_opcodes' table is shared between MVE and 
NEON enabled targets, whereas we want the VDUP encoding (shared between 
the two architectures) to be handled differently.


opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new reasons.
	(enum mve_undefined): Likewise.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
         (coprocessor_opcodes): Move NEON VDUP from here...
         (neon_opcodes): ... to here.
         (mve_opcodes): Add new instructions.
	(print_mve_undefined):  Handle new reasons.
	(print_mve_unpredictable): Likewise.
	(print_mve_size): Handle new instructions.
	(print_insn_neon): Handle vdup.
	(print_insn_mve): Handle new operands.

[-- Attachment #2: 40.patch --]
[-- Type: text/x-patch, Size: 9705 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index cf7c533b9f6c4e099ee2d662d200df8d437762f5..89d15893f648295ae7840217bec9b35129e67922 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -88,6 +88,17 @@ enum mve_instructions
   MVE_VCMP_VEC_T4,
   MVE_VCMP_VEC_T5,
   MVE_VCMP_VEC_T6,
+  MVE_VDUP,
+  MVE_VEOR,
+  MVE_VFMAS_FP_SCALAR,
+  MVE_VFMA_FP_SCALAR,
+  MVE_VFMA_FP,
+  MVE_VFMS_FP,
+  MVE_VHADD_T1,
+  MVE_VHADD_T2,
+  MVE_VHSUB_T1,
+  MVE_VHSUB_T2,
+  MVE_VRHADD,
   MVE_NONE
 };
 
@@ -99,11 +110,13 @@ enum mve_unpredictable
 				   fcB = 1 (vpt).  */
   UNPRED_R13,			/* Unpredictable because r13 (sp) or
 				   r15 (sp) used.  */
+  UNPRED_R15,			/* Unpredictable because r15 (pc) is used.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
 enum mve_undefined
 {
+  UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -540,18 +553,6 @@ static const struct sopcode32 coprocessor_opcodes[] =
     0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
 
   /* Data transfer between ARM and NEON registers.  */
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
-  {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
   {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
   {ANY, ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1161,6 +1162,20 @@ static const struct opcode32 neon_opcodes[] =
     0xf2b00000, 0xffb00810,
     "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
 
+  /* Data transfer between ARM and NEON registers.  */
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0e800b10, 0x1ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0e800b30, 0x1ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0ea00b10, 0x1ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0ea00b30, 0x1ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0ec00b10, 0x1ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
+    0x0ee00b10, 0x1ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
+
   /* Move data element to all lanes.  */
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
@@ -1813,10 +1828,12 @@ static const struct opcode32 neon_opcodes[] =
 
    %%			%
 
+   %c			print condition code
    %i			print MVE predicate(s) for vpt and vpst
    %n			print vector comparison code for predicated instruction
    %v			print vector predicate for instruction in predicated
 			block
+   %<bitfield>r		print as an ARM register
    %<bitfield>Q		print as a MVE Q register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
@@ -1918,6 +1935,78 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe011f40, 0xffc1ff50,
    "vcmp%v.s%20-21s\t%n, %17-19Q, %0-3Z"},
 
+  /* Vector VDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VDUP,
+   0xeea00b10, 0xffb10f5f,
+   "vdup%v.%5,22s\t%17-19,7Q, %12-15r"},
+
+  /* Vector VEOR.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VEOR,
+   0xff000150, 0xffd11f51,
+   "veor%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VFMA, vector * scalar.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VFMA_FP_SCALAR,
+   0xee310e40, 0xefb11f70,
+   "vfma%v.f%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VFMA floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VFMA_FP,
+   0xef000c50, 0xffa11f51,
+   "vfma%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VFMS floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VFMS_FP,
+   0xef200c50, 0xffa11f51,
+   "vfms%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VFMAS, vector * scalar.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VFMAS_FP_SCALAR,
+   0xee311e40, 0xefb11f70,
+   "vfmas%v.f%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VHADD T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHADD_T1,
+   0xef000040, 0xef811f51,
+   "vhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VHADD T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHADD_T2,
+   0xee000f40, 0xef811f70,
+   "vhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VHSUB T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHSUB_T1,
+   0xef000240, 0xef811f51,
+   "vhsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VHSUB T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHSUB_T2,
+   0xee001f40, 0xef811f70,
+   "vhsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VDUP,
+   0xeea00b10, 0xffb10f5f,
+   "vdup%v.%5,22s\t%17-19,7Q, %12-15r"},
+
+  /* Vector VRHADD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRHADD,
+   0xef000140, 0xef811f51,
+   "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   {ARM_FEATURE_CORE_LOW (0),
    MVE_NONE,
    0x00000000, 0x00000000, 0}
@@ -3923,6 +4012,8 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VHADD_T2:
+    case MVE_VHSUB_T2:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
@@ -3950,7 +4041,31 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 {
   *undefined_code = UNDEF_NONE;
 
-  return FALSE;
+  switch (matched_insn)
+    {
+    case MVE_VDUP:
+      if (arm_decode_field_multiple (given, 5, 5, 22, 22) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VRHADD:
+    case MVE_VHADD_T1:
+    case MVE_VHSUB_T1:
+      if (arm_decode_field (given, 20, 21) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    default:
+      return FALSE;
+    }
 }
 
 /* Return FALSE if GIVEN is not an unpredictable encoding for MATCHED_INSN.
@@ -3990,6 +4105,43 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VDUP:
+      {
+	unsigned long gpr = arm_decode_field (given, 12, 15);
+	if (gpr == 0xd)
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if (gpr == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
+    case MVE_VFMA_FP_SCALAR:
+    case MVE_VFMAS_FP_SCALAR:
+    case MVE_VHADD_T2:
+    case MVE_VHSUB_T2:
+      {
+	unsigned long gpr = arm_decode_field (given, 0, 3);
+	if (gpr == 0xd)
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if (gpr == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4006,6 +4158,10 @@ print_mve_undefined (struct disassemble_info *info,
 
   switch (undefined_code)
     {
+    case UNDEF_SIZE_3:
+      func (stream, "size equals three");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4035,6 +4191,10 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of r13 (sp)");
       break;
 
+    case UNPRED_R15:
+      func (stream, "use of r15 (pc)");
+      break;
+
     case UNPRED_NONE:
       break;
     }
@@ -4068,12 +4228,17 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VCMP_VEC_T4:
     case MVE_VCMP_VEC_T5:
     case MVE_VCMP_VEC_T6:
+    case MVE_VHADD_T1:
+    case MVE_VHADD_T2:
+    case MVE_VHSUB_T1:
+    case MVE_VHSUB_T2:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
     case MVE_VPT_VEC_T4:
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
+    case MVE_VRHADD:
       if (size <= 3)
 	func (stream, "%s", mve_vec_sizename[size]);
       else
@@ -4082,6 +4247,10 @@ print_mve_size (struct disassemble_info *info,
 
     case MVE_VCMP_FP_T1:
     case MVE_VCMP_FP_T2:
+    case MVE_VFMA_FP_SCALAR:
+    case MVE_VFMA_FP:
+    case MVE_VFMS_FP:
+    case MVE_VFMAS_FP_SCALAR:
     case MVE_VPT_FP_T1:
     case MVE_VPT_FP_T2:
       if (size == 0)
@@ -4090,6 +4259,23 @@ print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VDUP:
+      switch (size)
+	{
+	case 0:
+	  func (stream, "32");
+	  break;
+	case 1:
+	  func (stream, "16");
+	  break;
+	case 2:
+	  func (stream, "8");
+	  break;
+	default:
+	  break;
+	}
+      break;
+
     default:
       break;
     }
@@ -5049,7 +5235,8 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 	}
       else if ((given & 0xff000000) == 0xf9000000)
 	given ^= 0xf9000000 ^ 0xf4000000;
-      else
+      /* vdup is also a valid neon instruction.  */
+      else if ((given & 0xff910f5f) != 0xee800b10)
 	return FALSE;
     }
 
@@ -5588,6 +5775,9 @@ print_insn_mve (struct disassemble_info *info, long given)
 					    value,
 					    insn->mve_op);
 			    break;
+			  case 'r':
+			    func (stream, "%s", arm_regnames[value]);
+			    break;
 			  case 'Q':
 			    if (value & 0x8)
 			      func (stream, "<illegal reg q%ld.5>", value);

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24]
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (39 preceding siblings ...)
  2019-05-01 17:39 ` [PATCH 39/57][Arm][OBJDUMP] Add support for MVE instructions: vpt, vpst and vcmp Andre Vieira (lists)
@ 2019-05-01 17:40 ` Andre Vieira (lists)
  2019-05-01 17:40 ` [PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms, vhadd, vhsub and vrhadd Andre Vieira (lists)
                   ` (19 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:40 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 636 bytes --]

Hi,

This patch adds support for the MVE deinterleaving loads and 
interleaving stores.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new reasons.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_unpredictable): Likewise.
         (mve_opcodes): Add new instructions.
	(print_mve_unpredictable): Handle new reasons.
	(print_mve_register_blocks): New print function.
	(print_mve_size): Handle new instructions.
	(print_insn_mve): Likewise.

[-- Attachment #2: 41.patch --]
[-- Type: text/x-patch, Size: 6859 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 89d15893f648295ae7840217bec9b35129e67922..2b8755ab1b5042562bf4f9c69b9ea5de5ee2011a 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -99,6 +99,10 @@ enum mve_instructions
   MVE_VHSUB_T1,
   MVE_VHSUB_T2,
   MVE_VRHADD,
+  MVE_VLD2,
+  MVE_VLD4,
+  MVE_VST2,
+  MVE_VST4,
   MVE_NONE
 };
 
@@ -111,6 +115,12 @@ enum mve_unpredictable
   UNPRED_R13,			/* Unpredictable because r13 (sp) or
 				   r15 (sp) used.  */
   UNPRED_R15,			/* Unpredictable because r15 (pc) is used.  */
+  UNPRED_Q_GT_4,		/* Unpredictable because
+				   vec reg start > 4 (vld4/st4).  */
+  UNPRED_Q_GT_6,		/* Unpredictable because
+				   vec reg start > 6 (vld2/st2).  */
+  UNPRED_R13_AND_WB,		/* Unpredictable becase gp reg = r13
+				   and WB bit = 1.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
@@ -1833,7 +1843,11 @@ static const struct opcode32 neon_opcodes[] =
    %n			print vector comparison code for predicated instruction
    %v			print vector predicate for instruction in predicated
 			block
+   %w			print writeback mode for MVE v{st,ld}[24]
+   %B			print v{st,ld}[24] any one operands
+
    %<bitfield>r		print as an ARM register
+   %<bitfield>d		print the bitfield in decimal
    %<bitfield>Q		print as a MVE Q register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
@@ -2007,6 +2021,42 @@ static const struct mopcode32 mve_opcodes[] =
    0xef000140, 0xef811f51,
    "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VLD2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLD2,
+   0xfc901e00, 0xff901e5f,
+   "vld2%5d.%7-8s\t%B, [%16-19r]%w"},
+
+  /* Vector VLD4.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLD4,
+   0xfc901e01, 0xff901e1f,
+   "vld4%5-6d.%7-8s\t%B, [%16-19r]%w"},
+
+  /* Vector VST2 no writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST2,
+   0xfc801e00, 0xffb01e5f,
+   "vst2%5d.%7-8s\t%B, [%16-19r]"},
+
+  /* Vector VST2 writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST2,
+   0xfca01e00, 0xffb01e5f,
+   "vst2%5d.%7-8s\t%B, [%16-19r]!"},
+
+  /* Vector VST4 no writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST4,
+   0xfc801e01, 0xffb01e1f,
+   "vst4%5-6d.%7-8s\t%B, [%16-19r]"},
+
+  /* Vector VST4 writeback.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VST4,
+   0xfca01e01, 0xffb01e1f,
+   "vst4%5-6d.%7-8s\t%B, [%16-19r]!"},
+
   {ARM_FEATURE_CORE_LOW (0),
    MVE_NONE,
    0x00000000, 0x00000000, 0}
@@ -4025,6 +4075,15 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VLD2:
+    case MVE_VLD4:
+    case MVE_VST2:
+    case MVE_VST4:
+      if (arm_decode_field (given, 7, 8) == 3)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4142,6 +4201,58 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VLD2:
+    case MVE_VST2:
+      {
+	unsigned long rn = arm_decode_field (given, 16, 19);
+
+	if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1))
+	  {
+	    *unpredictable_code = UNPRED_R13_AND_WB;
+	    return TRUE;
+	  }
+
+	if (rn == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 6)
+	  {
+	    *unpredictable_code = UNPRED_Q_GT_6;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VLD4:
+    case MVE_VST4:
+      {
+	unsigned long rn = arm_decode_field (given, 16, 19);
+
+	if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1))
+	  {
+	    *unpredictable_code = UNPRED_R13_AND_WB;
+	    return TRUE;
+	  }
+
+	if (rn == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 4)
+	  {
+	    *unpredictable_code = UNPRED_Q_GT_4;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4195,11 +4306,61 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of r15 (pc)");
       break;
 
+    case UNPRED_Q_GT_4:
+      func (stream, "start register block > r4");
+      break;
+
+    case UNPRED_Q_GT_6:
+      func (stream, "start register block > r6");
+      break;
+
+    case UNPRED_R13_AND_WB:
+      func (stream, "use of r13 and write back");
+      break;
+
     case UNPRED_NONE:
       break;
     }
 }
 
+/* Print register block operand for mve vld2/vld4/vst2/vld4.  */
+
+static void
+print_mve_register_blocks (struct disassemble_info *info,
+			   unsigned long given,
+			   enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  unsigned long q_reg_start = arm_decode_field_multiple (given,
+							 13, 15,
+							 22, 22);
+  switch (matched_insn)
+    {
+    case MVE_VLD2:
+    case MVE_VST2:
+      if (q_reg_start <= 6)
+	func (stream, "{q%ld, q%ld}", q_reg_start, q_reg_start + 1);
+      else
+	func (stream, "<illegal reg q%ld>", q_reg_start);
+      break;
+
+    case MVE_VLD4:
+    case MVE_VST4:
+      if (q_reg_start <= 4)
+	func (stream, "{q%ld, q%ld, q%ld, q%ld}", q_reg_start,
+	      q_reg_start + 1, q_reg_start + 2,
+	      q_reg_start + 3);
+      else
+	func (stream, "<illegal reg q%ld>", q_reg_start);
+      break;
+
+    default:
+      break;
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -4232,6 +4393,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VHADD_T2:
     case MVE_VHSUB_T1:
     case MVE_VHSUB_T2:
+    case MVE_VLD2:
+    case MVE_VLD4:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
@@ -4239,6 +4402,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
     case MVE_VRHADD:
+    case MVE_VST2:
+    case MVE_VST4:
       if (size <= 3)
 	func (stream, "%s", mve_vec_sizename[size]);
       else
@@ -5752,6 +5917,15 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_instruction_predicate (info);
 		      break;
 
+		    case 'w':
+		      if (arm_decode_field (given, 21, 21) == 1)
+			func (stream, "!");
+		      break;
+
+		    case 'B':
+		      print_mve_register_blocks (info, given, insn->mve_op);
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {
@@ -5778,6 +5952,10 @@ print_insn_mve (struct disassemble_info *info, long given)
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;
+			  case 'd':
+			    func (stream, "%ld", value);
+			    value_in_comment = value;
+			    break;
 			  case 'Q':
 			    if (value & 0x8)
 			      func (stream, "<illegal reg q%ld.5>", value);

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 42/57][Arm][OBJDUMP] Add support for MVE instructions: vldr[bhw] and vstr[bhw]
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (41 preceding siblings ...)
  2019-05-01 17:40 ` [PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms, vhadd, vhsub and vrhadd Andre Vieira (lists)
@ 2019-05-01 17:41 ` Andre Vieira (lists)
  2019-05-01 17:42 ` [PATCH 43/57][Arm][OBJDUMP] Add support for MVE instructions: scatter stores and gather loads Andre Vieira (lists)
                   ` (17 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:41 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 862 bytes --]

Hi,

This patch adds support for all MVE VLDR[bhw] and VSTR[bhw] instructions.

It adds an extra check to the 'print_insn_coprocessor_1' to skip a 
particular encoding that overlaps with VLDR and VSTR (system register).

Is this OK for trunk?

Cheers,
Andre

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_undefined): Add new reasons.
         (insns): Add new instructions.
	(is_mve_encoding_conflict):
	(print_mve_vld_str_addr): New print function.
	(is_mve_undefined): Handle new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_size): Likewise.
	(print_insn_coprocessor_1): Handle MVE VLDR, VSTR instructions.
	(print_insn_mve):  Handle new operands.

[-- Attachment #2: 42.patch --]
[-- Type: text/x-patch, Size: 9407 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 9d821d92093216c48bc94c1e82da92dc5fdd4139..218c730b72926b8e0d6232243f192910d7385165 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -103,6 +103,16 @@ enum mve_instructions
   MVE_VLD4,
   MVE_VST2,
   MVE_VST4,
+  MVE_VLDRB_T1,
+  MVE_VLDRH_T2,
+  MVE_VLDRB_T5,
+  MVE_VLDRH_T6,
+  MVE_VLDRW_T7,
+  MVE_VSTRB_T1,
+  MVE_VSTRH_T2,
+  MVE_VSTRB_T5,
+  MVE_VSTRH_T6,
+  MVE_VSTRW_T7,
   MVE_NONE
 };
 
@@ -127,6 +137,8 @@ enum mve_unpredictable
 enum mve_undefined
 {
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
+  UNDEF_SIZE_3,			/* undefined because size == 3.  */
+  UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1839,6 +1851,8 @@ static const struct opcode32 neon_opcodes[] =
    %%			%
 
    %c			print condition code
+   %d			print addr mode of MVE vldr[bhw] and vstr[bhw]
+   %u			print 'U' (unsigned) or 'S' for various mve instructions
    %i			print MVE predicate(s) for vpt and vpst
    %n			print vector comparison code for predicated instruction
    %v			print vector predicate for instruction in predicated
@@ -2033,6 +2047,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xfc901e01, 0xff901e1f,
    "vld4%5-6d.%7-8s\t%B, [%16-19r]%w"},
 
+  /* Vector VLDRB.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRB_T1,
+   0xec100e00, 0xee581e00,
+   "vldrb%v.%u%7-8s\t%13-15Q, %d"},
+
+  /* Vector VLDRH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRH_T2,
+   0xec180e00, 0xee581e00,
+   "vldrh%v.%u%7-8s\t%13-15Q, %d"},
+
+  /* Vector VLDRB unsigned, variant T5.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRB_T5,
+   0xec101e00, 0xfe101f80,
+   "vldrb%v.u8\t%13-15,22Q, %d"},
+
+  /* Vector VLDRH unsigned, variant T6.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRH_T6,
+   0xec101e80, 0xfe101f80,
+   "vldrh%v.u16\t%13-15,22Q, %d"},
+
+  /* Vector VLDRW unsigned, variant T7.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRW_T7,
+   0xec101f00, 0xfe101f80,
+   "vldrw%v.u32\t%13-15,22Q, %d"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -2057,6 +2101,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xfca01e01, 0xffb01e1f,
    "vst4%5-6d.%7-8s\t%B, [%16-19r]!"},
 
+  /* Vector VSTRB.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRB_T1,
+   0xec000e00, 0xfe581e00,
+   "vstrb%v.%7-8s\t%13-15Q, %d"},
+
+  /* Vector VSTRH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRH_T2,
+   0xec080e00, 0xfe581e00,
+   "vstrh%v.%7-8s\t%13-15Q, %d"},
+
+  /* Vector VSTRB variant T5.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRB_T5,
+   0xec001e00, 0xfe101f80,
+   "vstrb%v.8\t%13-15,22Q, %d"},
+
+  /* Vector VSTRH variant T6.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRH_T6,
+   0xec001e80, 0xfe101f80,
+   "vstrh%v.16\t%13-15,22Q, %d"},
+
+  /* Vector VSTRW variant T7.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRW_T7,
+   0xec001f00, 0xfe101f80,
+   "vstrw%v.32\t%13-15,22Q, %d"},
+
   {ARM_FEATURE_CORE_LOW (0),
    MVE_NONE,
    0x00000000, 0x00000000, 0}
@@ -4084,12 +4158,109 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VSTRB_T1:
+    case MVE_VSTRH_T2:
+      if ((arm_decode_field (given, 24, 24) == 0)
+	  && (arm_decode_field (given, 21, 21) == 0))
+	{
+	    return TRUE;
+	}
+      else if ((arm_decode_field (given, 7, 8) == 3))
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VSTRB_T5:
+    case MVE_VSTRH_T6:
+    case MVE_VSTRW_T7:
+      if ((arm_decode_field (given, 24, 24) == 0)
+	  && (arm_decode_field (given, 21, 21) == 0))
+	{
+	    return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
     }
 }
 
+static void
+print_mve_vld_str_addr (struct disassemble_info *info,
+			unsigned long given,
+			enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  unsigned long p, w, gpr, imm, add, mod_imm;
+
+  imm = arm_decode_field (given, 0, 6);
+  mod_imm = imm;
+
+  switch (matched_insn)
+    {
+    case MVE_VLDRB_T1:
+    case MVE_VSTRB_T1:
+      gpr = arm_decode_field (given, 16, 18);
+      break;
+
+    case MVE_VLDRH_T2:
+    case MVE_VSTRH_T2:
+      gpr = arm_decode_field (given, 16, 18);
+      mod_imm = imm << 1;
+      break;
+
+    case MVE_VLDRH_T6:
+    case MVE_VSTRH_T6:
+      gpr = arm_decode_field (given, 16, 19);
+      mod_imm = imm << 1;
+      break;
+
+    case MVE_VLDRW_T7:
+    case MVE_VSTRW_T7:
+      gpr = arm_decode_field (given, 16, 19);
+      mod_imm = imm << 2;
+      break;
+
+    case MVE_VLDRB_T5:
+    case MVE_VSTRB_T5:
+      gpr = arm_decode_field (given, 16, 19);
+      break;
+
+    default:
+      return;
+    }
+
+  p = arm_decode_field (given, 24, 24);
+  w = arm_decode_field (given, 21, 21);
+
+  add = arm_decode_field (given, 23, 23);
+
+  char * add_sub;
+
+  /* Don't print anything for '+' as it is implied.  */
+  if (add == 1)
+    add_sub = "";
+  else
+    add_sub = "-";
+
+  if (p == 1)
+    {
+      /* Offset mode.  */
+      if (w == 0)
+	func (stream, "[%s, #%s%lu]", arm_regnames[gpr], add_sub, mod_imm);
+      /* Pre-indexed mode.  */
+      else
+	func (stream, "[%s, #%s%lu]!", arm_regnames[gpr], add_sub, mod_imm);
+    }
+  else if ((p == 0) && (w == 1))
+    /* Post-index mode.  */
+    func (stream, "[%s], #%s%lu", arm_regnames[gpr], add_sub, mod_imm);
+}
+
 /* Return FALSE if GIVEN is not an undefined encoding for MATCHED_INSN.
    Otherwise, return TRUE and set UNDEFINED_CODE to give a reason as to why
    this encoding is undefined.  */
@@ -4122,6 +4293,42 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VLDRB_T1:
+      if (arm_decode_field (given, 7, 8) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VLDRH_T2:
+      if (arm_decode_field (given, 7, 8) <= 1)
+	{
+	  *undefined_code = UNDEF_SIZE_LE_1;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRB_T1:
+      if ((arm_decode_field (given, 7, 8) == 0))
+	{
+	  *undefined_code = UNDEF_SIZE_0;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRH_T2:
+      if ((arm_decode_field (given, 7, 8) <= 1))
+	{
+	  *undefined_code = UNDEF_SIZE_LE_1;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -4253,6 +4460,29 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	  return FALSE;
       }
 
+    case MVE_VLDRB_T5:
+    case MVE_VLDRH_T6:
+    case MVE_VLDRW_T7:
+    case MVE_VSTRB_T5:
+    case MVE_VSTRH_T6:
+    case MVE_VSTRW_T7:
+      {
+	unsigned long rn = arm_decode_field (given, 16, 19);
+
+	if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1))
+	  {
+	    *unpredictable_code = UNPRED_R13_AND_WB;
+	    return TRUE;
+	  }
+	else if (rn == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4269,10 +4499,18 @@ print_mve_undefined (struct disassemble_info *info,
 
   switch (undefined_code)
     {
+    case UNDEF_SIZE_0:
+      func (stream, "size equals zero");
+      break;
+
     case UNDEF_SIZE_3:
       func (stream, "size equals three");
       break;
 
+    case UNDEF_SIZE_LE_1:
+      func (stream, "size <= 1");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4395,6 +4633,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VHSUB_T2:
     case MVE_VLD2:
     case MVE_VLD4:
+    case MVE_VLDRB_T1:
+    case MVE_VLDRH_T2:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
@@ -4404,6 +4644,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VRHADD:
     case MVE_VST2:
     case MVE_VST4:
+    case MVE_VSTRB_T1:
+    case MVE_VSTRH_T2:
       if (size <= 3)
 	func (stream, "%s", mve_vec_sizename[size]);
       else
@@ -4657,6 +4899,15 @@ print_insn_coprocessor_1 (const struct sopcode32 *opcodes,
 	      && (cp_num == 8 || cp_num == 14 || cp_num == 15))
 	    continue;
 	}
+      else if ((insn->value == 0xec100f80      /* vldr (system register) */
+		|| insn->value == 0xec000f80)  /* vstr (system register) */
+	       && arm_decode_field (given, 24, 24) == 0
+	       && arm_decode_field (given, 21, 21) == 0)
+	/* If the P and W bits are both 0 then these encodings match the MVE
+	   VLDR and VSTR instructions, these are in a different table, so we
+	   don't let it match here.  */
+	continue;
+
 
       for (c = insn->assembler; *c; c++)
 	{
@@ -5902,6 +6153,10 @@ print_insn_mve (struct disassemble_info *info, long given)
 			func (stream, "%s", arm_conditional[IFTHEN_COND]);
 		      break;
 
+		    case 'd':
+		      print_mve_vld_str_addr (info, given, insn->mve_op);
+		      break;
+
 		    case 'i':
 		      {
 			long mve_mask = mve_extract_pred_mask (given);
@@ -5913,6 +6168,14 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_vec_condition (info, given, insn->mve_op);
 		      break;
 
+		    case 'u':
+		      {
+			if (arm_decode_field (given, 28, 28) == 0)
+			  func (stream, "s");
+			else
+			  func (stream, "u");
+		      }
+
 		    case 'v':
 		      print_instruction_predicate (info);
 		      break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 43/57][Arm][OBJDUMP] Add support for MVE instructions: scatter stores and gather loads
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (42 preceding siblings ...)
  2019-05-01 17:41 ` [PATCH 42/57][Arm][OBJDUMP] Add support for MVE instructions: vldr[bhw] and vstr[bhw] Andre Vieira (lists)
@ 2019-05-01 17:42 ` Andre Vieira (lists)
  2019-05-01 17:43 ` [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint Andre Vieira (lists)
                   ` (16 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:42 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 559 bytes --]

Hi,

This patch adds all MVE scatter store and gather load instructions.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new reasons.
	(enum mve_undefined): Likewise.
	(is_mve_undefined): Handle new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 43.patch --]
[-- Type: text/x-patch, Size: 12955 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 6d167ae0860910f59ff4ab20b4761af413d1d65b..2a89937b38eba5ceb70cc1a0c3a2ca8045431aae 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -112,6 +112,18 @@ enum mve_instructions
   MVE_VSTRB_T5,
   MVE_VSTRH_T6,
   MVE_VSTRW_T7,
+  MVE_VLDRB_GATHER_T1,
+  MVE_VLDRH_GATHER_T2,
+  MVE_VLDRW_GATHER_T3,
+  MVE_VLDRD_GATHER_T4,
+  MVE_VLDRW_GATHER_T5,
+  MVE_VLDRD_GATHER_T6,
+  MVE_VSTRB_SCATTER_T1,
+  MVE_VSTRH_SCATTER_T2,
+  MVE_VSTRW_SCATTER_T3,
+  MVE_VSTRD_SCATTER_T4,
+  MVE_VSTRW_SCATTER_T5,
+  MVE_VSTRD_SCATTER_T6,
   MVE_NONE
 };
 
@@ -130,6 +142,9 @@ enum mve_unpredictable
 				   vec reg start > 6 (vld2/st2).  */
   UNPRED_R13_AND_WB,		/* Unpredictable becase gp reg = r13
 				   and WB bit = 1.  */
+  UNPRED_Q_REGS_EQUAL,		/* Unpredictable because vector registers are
+				   equal.  */
+  UNPRED_OS,			/* Unpredictable because offset scaled == 1.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
@@ -138,6 +153,13 @@ enum mve_undefined
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
+  UNDEF_SIZE_NOT_2,		/* undefined because size != 2.  */
+  UNDEF_SIZE_NOT_3,		/* undefined because size != 3.  */
+  UNDEF_NOT_UNS_SIZE_0,		/* undefined because U == 0 and
+				   size == 0.  */
+  UNDEF_NOT_UNS_SIZE_1,		/* undefined because U == 0 and
+				   size == 1.  */
+  UNDEF_NOT_UNSIGNED,		/* undefined because U == 0.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1840,6 +1862,8 @@ static const struct opcode32 neon_opcodes[] =
 
    %%			%
 
+   %a			print '+' or '-' or imm offset in vldr[bhwd] and
+			vstr[bhwd]
    %c			print condition code
    %d			print addr mode of MVE vldr[bhw] and vstr[bhw]
    %u			print 'U' (unsigned) or 'S' for various mve instructions
@@ -1847,6 +1871,7 @@ static const struct opcode32 neon_opcodes[] =
    %n			print vector comparison code for predicated instruction
    %v			print vector predicate for instruction in predicated
 			block
+   %o			print offset scaled for vldr[hwd] and vstr[hwd]
    %w			print writeback mode for MVE v{st,ld}[24]
    %B			print v{st,ld}[24] any one operands
 
@@ -1856,7 +1881,8 @@ static const struct opcode32 neon_opcodes[] =
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
-*/
+   %<bitfield>i		print immediate for vstr/vldr reg +/- imm
+   */
 
 static const struct mopcode32 mve_opcodes[] =
 {
@@ -2037,6 +2063,42 @@ static const struct mopcode32 mve_opcodes[] =
    0xfc901e01, 0xff901e1f,
    "vld4%5-6d.%7-8s\t%B, [%16-19r]%w"},
 
+  /* Vector VLDRB gather load.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRB_GATHER_T1,
+   0xec900e00, 0xefb01e50,
+   "vldrb%v.%u%7-8s\t%13-15,22Q, [%16-19r, %1-3,5Q]"},
+
+  /* Vector VLDRH gather load.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRH_GATHER_T2,
+   0xec900e10, 0xefb01e50,
+   "vldrh%v.%u%7-8s\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VLDRW gather load.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRW_GATHER_T3,
+   0xfc900f40, 0xffb01fd0,
+   "vldrw%v.u32\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VLDRD gather load.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRD_GATHER_T4,
+   0xec900fd0, 0xefb01fd0,
+   "vldrd%v.u64\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VLDRW gather load.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRW_GATHER_T5,
+   0xfd101e00, 0xff111f00,
+   "vldrw%v.u32\t%13-15,22Q, [%17-19,7Q, #%a%0-6i]%w"},
+
+  /* Vector VLDRD gather load, variant T6.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VLDRD_GATHER_T6,
+   0xfd101f00, 0xff111f00,
+   "vldrd%v.u64\t%13-15,22Q, [%17-19,7Q, #%a%0-6i]%w"},
+
   /* Vector VLDRB.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VLDRB_T1,
@@ -2091,6 +2153,42 @@ static const struct mopcode32 mve_opcodes[] =
    0xfca01e01, 0xffb01e1f,
    "vst4%5-6d.%7-8s\t%B, [%16-19r]!"},
 
+  /* Vector VSTRB scatter store, T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRB_SCATTER_T1,
+   0xec800e00, 0xffb01e50,
+   "vstrb%v.%7-8s\t%13-15,22Q, [%16-19r, %1-3,5Q]"},
+
+  /* Vector VSTRH scatter store, T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRH_SCATTER_T2,
+   0xec800e10, 0xffb01e50,
+   "vstrh%v.%7-8s\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VSTRW scatter store, T3 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRW_SCATTER_T3,
+   0xec800e40, 0xffb01e50,
+   "vstrw%v.%7-8s\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VSTRD scatter store, T4 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRD_SCATTER_T4,
+   0xec800fd0, 0xffb01fd0,
+   "vstrd%v.64\t%13-15,22Q, [%16-19r, %1-3,5Q%o]"},
+
+  /* Vector VSTRW scatter store, T5 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRW_SCATTER_T5,
+   0xfd001e00, 0xff111f00,
+   "vstrw%v.32\t%13-15,22Q, [%17-19,7Q, #%a%0-6i]%w"},
+
+  /* Vector VSTRD scatter store, T6 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSTRD_SCATTER_T6,
+   0xfd001f00, 0xff111f00,
+   "vstrd%v.64\t%13-15,22Q, [%17-19,7Q, #%a%0-6i]%w"},
+
   /* Vector VSTRB.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VSTRB_T1,
@@ -4319,6 +4417,113 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VLDRB_GATHER_T1:
+      if (arm_decode_field (given, 7, 8) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else if ((arm_decode_field (given, 28, 28) == 0)
+	       && (arm_decode_field (given, 7, 8) == 0))
+	{
+	  *undefined_code = UNDEF_NOT_UNS_SIZE_0;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VLDRH_GATHER_T2:
+      if (arm_decode_field (given, 7, 8) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else if ((arm_decode_field (given, 28, 28) == 0)
+	       && (arm_decode_field (given, 7, 8) == 1))
+	{
+	  *undefined_code = UNDEF_NOT_UNS_SIZE_1;
+	  return TRUE;
+	}
+      else if (arm_decode_field (given, 7, 8) == 0)
+	{
+	  *undefined_code = UNDEF_SIZE_0;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VLDRW_GATHER_T3:
+      if (arm_decode_field (given, 7, 8) != 2)
+	{
+	  *undefined_code = UNDEF_SIZE_NOT_2;
+	  return TRUE;
+	}
+      else if (arm_decode_field (given, 28, 28) == 0)
+	{
+	  *undefined_code = UNDEF_NOT_UNSIGNED;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VLDRD_GATHER_T4:
+      if (arm_decode_field (given, 7, 8) != 3)
+	{
+	  *undefined_code = UNDEF_SIZE_NOT_3;
+	  return TRUE;
+	}
+      else if (arm_decode_field (given, 28, 28) == 0)
+	{
+	  *undefined_code = UNDEF_NOT_UNSIGNED;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRB_SCATTER_T1:
+      if (arm_decode_field (given, 7, 8) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRH_SCATTER_T2:
+      {
+	unsigned long size = arm_decode_field (given, 7, 8);
+	if (size == 3)
+	  {
+	    *undefined_code = UNDEF_SIZE_3;
+	    return TRUE;
+	  }
+	else if (size == 0)
+	  {
+	    *undefined_code = UNDEF_SIZE_0;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VSTRW_SCATTER_T3:
+      if (arm_decode_field (given, 7, 8) != 2)
+	{
+	  *undefined_code = UNDEF_SIZE_NOT_2;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRD_SCATTER_T4:
+      if (arm_decode_field (given, 7, 8) != 3)
+	{
+	  *undefined_code = UNDEF_SIZE_NOT_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -4473,6 +4678,77 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	  return FALSE;
       }
 
+    case MVE_VLDRB_GATHER_T1:
+      if (arm_decode_field (given, 0, 0) == 1)
+	{
+	  *unpredictable_code = UNPRED_OS;
+	  return TRUE;
+	}
+
+      /*  fall through.  */
+      /* To handle common code with T2-T4 variants.  */
+    case MVE_VLDRH_GATHER_T2:
+    case MVE_VLDRW_GATHER_T3:
+    case MVE_VLDRD_GATHER_T4:
+      {
+	unsigned long qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+
+	if (qd == qm)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQUAL;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field (given, 16, 19) == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
+    case MVE_VLDRW_GATHER_T5:
+    case MVE_VLDRD_GATHER_T6:
+      {
+	unsigned long qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long qm = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	if (qd == qm)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQUAL;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VSTRB_SCATTER_T1:
+      if (arm_decode_field (given, 16, 19) == 0xf)
+	{
+	  *unpredictable_code = UNPRED_R15;
+	  return TRUE;
+	}
+      else if (arm_decode_field (given, 0, 0) == 1)
+	{
+	  *unpredictable_code = UNPRED_OS;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VSTRH_SCATTER_T2:
+    case MVE_VSTRW_SCATTER_T3:
+    case MVE_VSTRD_SCATTER_T4:
+      if (arm_decode_field (given, 16, 19) == 0xf)
+	{
+	  *unpredictable_code = UNPRED_R15;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -4501,6 +4777,26 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "size <= 1");
       break;
 
+    case UNDEF_SIZE_NOT_2:
+      func (stream, "size not equal to 2");
+      break;
+
+    case UNDEF_SIZE_NOT_3:
+      func (stream, "size not equal to 3");
+      break;
+
+    case UNDEF_NOT_UNS_SIZE_0:
+      func (stream, "not unsigned and size = zero");
+      break;
+
+    case UNDEF_NOT_UNS_SIZE_1:
+      func (stream, "not unsigned and size = one");
+      break;
+
+    case UNDEF_NOT_UNSIGNED:
+      func (stream, "not unsigned");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4546,6 +4842,15 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of r13 and write back");
       break;
 
+    case UNPRED_Q_REGS_EQUAL:
+      func (stream,
+	    "same vector register used for destination and other operand");
+      break;
+
+    case UNPRED_OS:
+      func (stream, "use of offset scaled");
+      break;
+
     case UNPRED_NONE:
       break;
     }
@@ -4623,6 +4928,10 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VHSUB_T2:
     case MVE_VLD2:
     case MVE_VLD4:
+    case MVE_VLDRB_GATHER_T1:
+    case MVE_VLDRH_GATHER_T2:
+    case MVE_VLDRW_GATHER_T3:
+    case MVE_VLDRD_GATHER_T4:
     case MVE_VLDRB_T1:
     case MVE_VLDRH_T2:
     case MVE_VPT_VEC_T1:
@@ -4634,6 +4943,9 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VRHADD:
     case MVE_VST2:
     case MVE_VST4:
+    case MVE_VSTRB_SCATTER_T1:
+    case MVE_VSTRH_SCATTER_T2:
+    case MVE_VSTRW_SCATTER_T3:
     case MVE_VSTRB_T1:
     case MVE_VSTRH_T2:
       if (size <= 3)
@@ -6117,6 +6429,12 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      func (stream, "%%");
 		      break;
 
+		    case 'a':
+		      /* Don't print anything for '+' as it is implied.  */
+		      if (arm_decode_field (given, 23, 23) == 0)
+			func (stream, "-");
+		      break;
+
 		    case 'c':
 		      if (ifthen_state)
 			func (stream, "%s", arm_conditional[IFTHEN_COND]);
@@ -6137,6 +6455,17 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_vec_condition (info, given, insn->mve_op);
 		      break;
 
+		    case 'o':
+		      if (arm_decode_field (given, 0, 0) == 1)
+			{
+			  unsigned long size
+			    = arm_decode_field (given, 4, 4)
+			      | (arm_decode_field (given, 6, 6) << 1);
+
+			  func (stream, ", uxtw #%lu", size);
+			}
+		      break;
+
 		    case 'u':
 		      {
 			if (arm_decode_field (given, 28, 28) == 0)
@@ -6144,6 +6473,7 @@ print_insn_mve (struct disassemble_info *info, long given)
 			else
 			  func (stream, "u");
 		      }
+		      break;
 
 		    case 'v':
 		      print_instruction_predicate (info);
@@ -6181,6 +6511,30 @@ print_insn_mve (struct disassemble_info *info, long given)
 					    value,
 					    insn->mve_op);
 			    break;
+			  case 'i':
+			    {
+			      unsigned long imm
+				= arm_decode_field (given, 0, 6);
+			      unsigned long mod_imm = imm;
+
+			      switch (insn->mve_op)
+				{
+				case MVE_VLDRW_GATHER_T5:
+				case MVE_VSTRW_SCATTER_T5:
+				  mod_imm = mod_imm << 2;
+				  break;
+				case MVE_VSTRD_SCATTER_T6:
+				case MVE_VLDRD_GATHER_T6:
+				  mod_imm = mod_imm << 3;
+				  break;
+
+				default:
+				  break;
+				}
+
+			      func (stream, "%lu", mod_imm);
+			    }
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (43 preceding siblings ...)
  2019-05-01 17:42 ` [PATCH 43/57][Arm][OBJDUMP] Add support for MVE instructions: scatter stores and gather loads Andre Vieira (lists)
@ 2019-05-01 17:43 ` Andre Vieira (lists)
  2019-05-02  9:54   ` Nick Clifton
  2019-05-01 17:44 ` [PATCH 45/57][Arm][OBJDUMP] Add support for MVE instructions: vmov, vmvn, vorr, vorn, vmovx and vbic Andre Vieira (lists)
                   ` (15 subsequent siblings)
  60 siblings, 1 reply; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:43 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 663 bytes --]

Hi,

This patch adds support for MVE instructions VCVT and VRINT.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new reasons.
	(enum mve_undefined): Likewise.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_unpredictable): Likewise.
	(print_mve_rounding_mode): Likewise.
	(print_mve_vcvt_size): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 44.patch --]
[-- Type: text/x-patch, Size: 11836 bytes --]

diff --git a/gas/testsuite/gas/arm/mve-vrint-bad.l b/gas/testsuite/gas/arm/mve-vrint-bad.l
index 1d68a82badabae2a56559f476b356fdec9713c48..39fca355f6be2f7b8650867d20d590a4a992a18c 100644
--- a/gas/testsuite/gas/arm/mve-vrint-bad.l
+++ b/gas/testsuite/gas/arm/mve-vrint-bad.l
@@ -11,7 +11,7 @@
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintm.f64 q0,q1'
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintp.i16 q0,q1'
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintp.f64 q0,q1'
-[^:]*:14: Error: invalid rounding mode -- `vrintr.f16 q0,q1'
+[^:]*:14: Error: VFP single, double or Neon quad precision register expected -- `vrintr.f16 q0,q1'
 [^:]*: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
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index e10a5d7bba690f0749885e7839ee1772f0b44e09..c20a175f67a61532a692d185b5afd92ed9fe6563 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -124,6 +124,11 @@ enum mve_instructions
   MVE_VSTRD_SCATTER_T4,
   MVE_VSTRW_SCATTER_T5,
   MVE_VSTRD_SCATTER_T6,
+  MVE_VCVT_FP_FIX_VEC,
+  MVE_VCVT_BETWEEN_FP_INT,
+  MVE_VCVT_FP_HALF_FP,
+  MVE_VCVT_FROM_FP_TO_INT,
+  MVE_VRINT_FP,
   MVE_NONE
 };
 
@@ -145,12 +150,14 @@ enum mve_unpredictable
   UNPRED_Q_REGS_EQUAL,		/* Unpredictable because vector registers are
 				   equal.  */
   UNPRED_OS,			/* Unpredictable because offset scaled == 1.  */
+  UNPRED_GP_REGS_EQUAL,		/* Unpredictable because gp registers are the
+				   same.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
 enum mve_undefined
 {
-  UNDEF_SIZE_3,			/* undefined because size == 3.  */
+  UNDEF_SIZE_0,			/* undefined because size == 0.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
   UNDEF_SIZE_NOT_2,		/* undefined because size != 2.  */
@@ -160,6 +167,8 @@ enum mve_undefined
   UNDEF_NOT_UNS_SIZE_1,		/* undefined because U == 0 and
 				   size == 1.  */
   UNDEF_NOT_UNSIGNED,		/* undefined because U == 0.  */
+  UNDEF_VCVT_IMM6,		/* imm6 < 32.  */
+  UNDEF_VCVT_FSI_IMM6,		/* fsi = 0 and 32 >= imm6 <= 47.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1868,7 +1877,9 @@ static const struct opcode32 neon_opcodes[] =
    %d			print addr mode of MVE vldr[bhw] and vstr[bhw]
    %u			print 'U' (unsigned) or 'S' for various mve instructions
    %i			print MVE predicate(s) for vpt and vpst
+   %m			print rounding mode for vcvt and vrint
    %n			print vector comparison code for predicated instruction
+   %s			print size for various vcvt instructions
    %v			print vector predicate for instruction in predicated
 			block
    %o			print offset scaled for vldr[hwd] and vstr[hwd]
@@ -1882,7 +1893,8 @@ static const struct opcode32 neon_opcodes[] =
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
    %<bitfield>i		print immediate for vstr/vldr reg +/- imm
-   */
+   %<bitfield>k		print immediate for vector conversion instruction
+ */
 
 static const struct mopcode32 mve_opcodes[] =
 {
@@ -2051,6 +2063,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xef000140, 0xef811f51,
    "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_FIX_VEC,
+   0xef800c50, 0xef801cd1,
+   "vcvt%v.%s\t%13-15,22Q, %1-3,5Q, #%16-21k"},
+
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_BETWEEN_FP_INT,
+   0xffb30640, 0xffb31e51,
+   "vcvt%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT between single and half-precision float, bottom half.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_HALF_FP,
+   0xee3f0e01, 0xefbf1fd1,
+   "vcvtb%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT between single and half-precision float, top half.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_HALF_FP,
+   0xee3f1e01, 0xefbf1fd1,
+   "vcvtt%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FROM_FP_TO_INT,
+   0xffb30040, 0xffb31c51,
+   "vcvt%m%v.%s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VLD2.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VLD2,
@@ -2129,6 +2171,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VRINT floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VRINT_FP,
+   0xffb20440, 0xffb31c51,
+   "vrint%m%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -4269,6 +4317,9 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VCVT_FP_FIX_VEC:
+      return (arm_decode_field (given, 16, 21) & 0x38) == 0;
+
     default:
       return FALSE;
 
@@ -4524,6 +4575,43 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCVT_FP_FIX_VEC:
+      {
+	unsigned long imm6 = arm_decode_field (given, 16, 21);
+	if ((imm6 & 0x20) == 0)
+	  {
+	    *undefined_code = UNDEF_VCVT_IMM6;
+	    return TRUE;
+	  }
+
+	if ((arm_decode_field (given, 9, 9) == 0)
+	    && ((imm6 & 0x30) == 2))
+	  {
+	    *undefined_code = UNDEF_VCVT_FSI_IMM6;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
+    case MVE_VCVT_BETWEEN_FP_INT:
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long size = arm_decode_field (given, 18, 19);
+	if (size == 0)
+	  {
+	    *undefined_code = UNDEF_SIZE_0;
+	    return TRUE;
+	  }
+	else if (size == 3)
+	  {
+	    *undefined_code = UNDEF_SIZE_3;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4749,6 +4837,31 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCVT_BETWEEN_FP_INT:
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long rt = arm_decode_field (given, 0, 3);
+	unsigned long rt2 = arm_decode_field (given, 16, 19);
+
+	if ((rt == 0xd) || (rt2 == 0xd))
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if ((rt == 0xf) || (rt2 == 0xf))
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+	else if (rt == rt2)
+	  {
+	    *unpredictable_code = UNPRED_GP_REGS_EQUAL;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4797,6 +4910,14 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "not unsigned");
       break;
 
+    case UNDEF_VCVT_IMM6:
+      func (stream, "invalid imm6");
+      break;
+
+    case UNDEF_VCVT_FSI_IMM6:
+      func (stream, "fsi = 0 and invalid imm6");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4851,6 +4972,10 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of offset scaled");
       break;
 
+    case UNPRED_GP_REGS_EQUAL:
+      func (stream, "same general-purpose register used for both operands");
+      break;
+
     case UNPRED_NONE:
       break;
     }
@@ -4894,6 +5019,234 @@ print_mve_register_blocks (struct disassemble_info *info,
     }
 }
 
+static void
+print_mve_rounding_mode (struct disassemble_info *info,
+			 unsigned long given,
+			 enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (matched_insn)
+    {
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	switch (arm_decode_field (given, 8, 9))
+	  {
+	  case 0:
+	    func (stream, "a");
+	    break;
+
+	  case 1:
+	    func (stream, "n");
+	    break;
+
+	  case 2:
+	    func (stream, "p");
+	    break;
+
+	  case 3:
+	    func (stream, "m");
+	    break;
+
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    case MVE_VRINT_FP:
+      {
+	switch (arm_decode_field (given, 7, 9))
+	  {
+	  case 0:
+	    func (stream, "n");
+	    break;
+
+	  case 1:
+	    func (stream, "x");
+	    break;
+
+	  case 2:
+	    func (stream, "a");
+	    break;
+
+	  case 3:
+	    func (stream, "z");
+	    break;
+
+	  case 5:
+	    func (stream, "m");
+	    break;
+
+	  case 7:
+	    func (stream, "p");
+
+	  case 4:
+	  case 6:
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+print_mve_vcvt_size (struct disassemble_info *info,
+		     unsigned long given,
+		     enum mve_instructions matched_insn)
+{
+  unsigned long mode = 0;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (matched_insn)
+    {
+    case MVE_VCVT_FP_FIX_VEC:
+      {
+	mode = (((given & 0x200) >> 7)
+		| ((given & 0x10000000) >> 27)
+		| ((given & 0x100) >> 8));
+
+	switch (mode)
+	  {
+	  case 0:
+	    func (stream, "f16.s16");
+	    break;
+
+	  case 1:
+	    func (stream, "s16.f16");
+	    break;
+
+	  case 2:
+	    func (stream, "f16.u16");
+	    break;
+
+	  case 3:
+	    func (stream, "u16.f16");
+	    break;
+
+	  case 4:
+	    func (stream, "f32.s32");
+	    break;
+
+	  case 5:
+	    func (stream, "s32.f32");
+	    break;
+
+	  case 6:
+	    func (stream, "f32.u32");
+	    break;
+
+	  case 7:
+	    func (stream, "u32.f32");
+	    break;
+
+	  default:
+	    break;
+	  }
+	break;
+      }
+    case MVE_VCVT_BETWEEN_FP_INT:
+      {
+	unsigned long size = arm_decode_field (given, 18, 19);
+	unsigned long op = arm_decode_field (given, 7, 8);
+
+	if (size == 1)
+	  {
+	    switch (op)
+	      {
+	      case 0:
+		func (stream, "f16.s16");
+		break;
+
+	      case 1:
+		func (stream, "f16.u16");
+		break;
+
+	      case 2:
+		func (stream, "s16.f16");
+		break;
+
+	      case 3:
+		func (stream, "u16.f16");
+		break;
+
+	      default:
+		break;
+	      }
+	  }
+	else if (size == 2)
+	  {
+	    switch (op)
+	      {
+	      case 0:
+		func (stream, "f32.s32");
+		break;
+
+	      case 1:
+		func (stream, "f32.u32");
+		break;
+
+	      case 2:
+		func (stream, "s32.f32");
+		break;
+
+	      case 3:
+		func (stream, "u32.f32");
+		break;
+	      }
+	  }
+      }
+      break;
+
+    case MVE_VCVT_FP_HALF_FP:
+      {
+	unsigned long op = arm_decode_field (given, 28, 28);
+	if (op == 0)
+	  func (stream, "f16.f32");
+	else if (op == 1)
+	  func (stream, "f32.f16");
+      }
+      break;
+
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long size = arm_decode_field_multiple (given, 7, 7, 18, 19);
+
+	switch (size)
+	  {
+	  case 2:
+	    func (stream, "s16.f16");
+	    break;
+
+	  case 3:
+	    func (stream, "u16.f16");
+	    break;
+
+	  case 4:
+	    func (stream, "s32.f32");
+	    break;
+
+	  case 5:
+	    func (stream, "u32.f32");
+	    break;
+
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -4941,6 +5294,7 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
     case MVE_VRHADD:
+    case MVE_VRINT_FP:
     case MVE_VST2:
     case MVE_VST4:
     case MVE_VSTRB_SCATTER_T1:
@@ -6466,6 +6820,14 @@ print_insn_mve (struct disassemble_info *info, long given)
 			}
 		      break;
 
+		    case 'm':
+		      print_mve_rounding_mode (info, given, insn->mve_op);
+		      break;
+
+		    case 's':
+		      print_mve_vcvt_size (info, given, insn->mve_op);
+		      break;
+
 		    case 'u':
 		      {
 			if (arm_decode_field (given, 28, 28) == 0)
@@ -6535,6 +6897,9 @@ print_insn_mve (struct disassemble_info *info, long given)
 			      func (stream, "%lu", mod_imm);
 			    }
 			    break;
+			  case 'k':
+			    func (stream, "%lu", 64 - value);
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 45/57][Arm][OBJDUMP] Add support for MVE instructions: vmov, vmvn, vorr, vorn, vmovx and vbic
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (44 preceding siblings ...)
  2019-05-01 17:43 ` [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint Andre Vieira (lists)
@ 2019-05-01 17:44 ` Andre Vieira (lists)
  2019-05-01 17:44 ` [PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull, vqmovn, vqmovun and vmovn Andre Vieira (lists)
                   ` (14 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:44 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

Hello,

This patch adds support for MVE instructions: VMOV, VMVN, VORR, VORN, 
VMOVX, and VBIC.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_unpredictable): Add new reasons.
	(enum mve_undefined): Likewise.
	(is_mve_okay_in_it): Handle new isntructions.
	(is_mve_encoding_conflict): Likewise.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_vmov_index): Likewise.
	(print_simd_imm8): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 45.patch --]
[-- Type: text/x-patch, Size: 19452 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 0e3c6b63932ce58526a18981f50718436890d695..eb468afc2bc15725709bf9033e0b1288545429b4 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -129,6 +129,21 @@ enum mve_instructions
   MVE_VCVT_FP_HALF_FP,
   MVE_VCVT_FROM_FP_TO_INT,
   MVE_VRINT_FP,
+  MVE_VMOV_HFP_TO_GP,
+  MVE_VMOV_GP_TO_VEC_LANE,
+  MVE_VMOV_IMM_TO_VEC,
+  MVE_VMOV_VEC_TO_VEC,
+  MVE_VMOV2_VEC_LANE_TO_GP,
+  MVE_VMOV2_GP_TO_VEC_LANE,
+  MVE_VMOV_VEC_LANE_TO_GP,
+  MVE_VMVN_IMM,
+  MVE_VMVN_REG,
+  MVE_VORR_IMM,
+  MVE_VORR_REG,
+  MVE_VORN,
+  MVE_VBIC_IMM,
+  MVE_VBIC_REG,
+  MVE_VMOVX,
   MVE_NONE
 };
 
@@ -152,12 +167,17 @@ enum mve_unpredictable
   UNPRED_OS,			/* Unpredictable because offset scaled == 1.  */
   UNPRED_GP_REGS_EQUAL,		/* Unpredictable because gp registers are the
 				   same.  */
+  UNPRED_Q_REGS_EQ_AND_SIZE_1,	/* Unpredictable because q regs equal and
+				   size = 1.  */
+  UNPRED_Q_REGS_EQ_AND_SIZE_2,	/* Unpredictable because q regs equal and
+				   size = 2.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
 enum mve_undefined
 {
   UNDEF_SIZE_0,			/* undefined because size == 0.  */
+  UNDEF_SIZE_2,			/* undefined because size == 2.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
   UNDEF_SIZE_NOT_2,		/* undefined because size != 2.  */
@@ -169,6 +189,12 @@ enum mve_undefined
   UNDEF_NOT_UNSIGNED,		/* undefined because U == 0.  */
   UNDEF_VCVT_IMM6,		/* imm6 < 32.  */
   UNDEF_VCVT_FSI_IMM6,		/* fsi = 0 and 32 >= imm6 <= 47.  */
+  UNDEF_BAD_OP1_OP2,		/* undefined with op2 = 2 and
+				   op1 == (0 or 1).  */
+  UNDEF_BAD_U_OP1_OP2,		/* undefined with U = 1 and
+				   op2 == 0 and op1 == (0 or 1).  */
+  UNDEF_OP_0_BAD_CMODE,		/* undefined because op == 0 and cmode
+				   in {0xx1, x0x1}.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1885,15 +1911,19 @@ static const struct opcode32 neon_opcodes[] =
    %o			print offset scaled for vldr[hwd] and vstr[hwd]
    %w			print writeback mode for MVE v{st,ld}[24]
    %B			print v{st,ld}[24] any one operands
+   %E			print vmov, vmvn, vorr, vbic encoded constant
+   %N			print generic index for vmov
 
    %<bitfield>r		print as an ARM register
    %<bitfield>d		print the bitfield in decimal
    %<bitfield>Q		print as a MVE Q register
+   %<bitfield>F		print as a MVE S register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
    %<bitfield>i		print immediate for vstr/vldr reg +/- imm
    %<bitfield>k		print immediate for vector conversion instruction
+   %<bitfield>x		print the bitfield in hex.
  */
 
 static const struct mopcode32 mve_opcodes[] =
@@ -1948,6 +1978,18 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe011f40, 0xff811f50,
    "vpt%i.s%20-21s\t%n, %17-19Q, %0-3Z"},
 
+  /* Vector VBIC immediate.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VBIC_IMM,
+   0xef800070, 0xefb81070,
+   "vbic%v.i%8-11s\t%13-15,22Q, %E"},
+
+  /* Vector VBIC register.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VBIC_REG,
+   0xef100150, 0xffb11f51,
+   "vbic%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VCMP floating point T1.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMP_FP_T1,
@@ -2171,6 +2213,103 @@ static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VMOV between gpr and half precision register, op == 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMOV_HFP_TO_GP,
+   0xee000910, 0xfff00f7f,
+   "vmov.f16\t%7,16-19F, %12-15r"},
+
+  /* Vector VMOV between gpr and half precision register, op == 1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMOV_HFP_TO_GP,
+   0xee100910, 0xfff00f7f,
+   "vmov.f16\t%12-15r, %7,16-19F"},
+
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMOV_GP_TO_VEC_LANE,
+   0xee000b10, 0xff900f1f,
+   "vmov%c.%5-6,21-22s\t%17-19,7Q[%N], %12-15r"},
+
+  /* Vector VORR immediate to vector.
+     NOTE: MVE_VORR_IMM must appear in the table
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VORR_IMM,
+   0xef800050, 0xefb810f0,
+   "vorr%v.i%8-11s\t%13-15,22Q, %E"},
+
+  /* Vector VMOV immediate to vector,
+     cmode == 11x1 -> VMVN which is UNDEFINED
+     for such a cmode.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMVN_IMM, 0xef800d50, 0xefb81dd0, UNDEFINED_INSTRUCTION},
+
+  /* Vector VMOV immediate to vector.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV_IMM_TO_VEC,
+   0xef800050, 0xefb810d0,
+   "vmov%v.%5,8-11s\t%13-15,22Q, %E"},
+
+  /* Vector VMOV two 32-bit lanes to two gprs, idx = 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV2_VEC_LANE_TO_GP,
+   0xec000f00, 0xffb01ff0,
+   "vmov%c\t%0-3r, %16-19r, %13-15,22Q[2], %13-15,22Q[0]"},
+
+  /* Vector VMOV two 32-bit lanes to two gprs, idx = 1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV2_VEC_LANE_TO_GP,
+   0xec000f10, 0xffb01ff0,
+   "vmov%c\t%0-3r, %16-19r, %13-15,22Q[3], %13-15,22Q[1]"},
+
+  /* Vector VMOV Two gprs to two 32-bit lanes, idx = 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV2_GP_TO_VEC_LANE,
+   0xec100f00, 0xffb01ff0,
+   "vmov%c\t%13-15,22Q[2], %13-15,22Q[0], %0-3r, %16-19r"},
+
+  /* Vector VMOV Two gprs to two 32-bit lanes, idx = 1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOV2_GP_TO_VEC_LANE,
+   0xec100f10, 0xffb01ff0,
+   "vmov%c\t%13-15,22Q[2], %13-15,22Q[0], %0-3r, %16-19r"},
+
+  /* Vector VMOV Vector lane to gpr.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMOV_VEC_LANE_TO_GP,
+   0xee100b10, 0xff100f1f,
+   "vmov%c.%u%5-6,21-22s\t%12-15r, %17-19,7Q[%N]"},
+
+  /* Floating point move extract.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMOVX,
+   0xfeb00a40, 0xffbf0fd0,
+   "vmovx.f16\t%22,12-15F, %5,0-3F"},
+
+  /* Vector VMVN immediate to vector.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMVN_IMM,
+   0xef800070, 0xefb810f0,
+   "vmvn%v.i%8-11s\t%13-15,22Q, %E"},
+
+  /* Vector VMVN register.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMVN_REG,
+   0xffb005c0, 0xffbf1fd1,
+   "vmvn%v\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VORN, vector bitwise or not.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VORN,
+   0xef300150, 0xffb11f51,
+   "vorn%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VORR register.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VORR_REG,
+   0xef200150, 0xffb11f51,
+   "vorr%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
@@ -4127,7 +4266,16 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
 static bfd_boolean
 is_mve_okay_in_it (enum mve_instructions matched_insn)
 {
-  return FALSE;
+  switch (matched_insn)
+    {
+    case MVE_VMOV_GP_TO_VEC_LANE:
+    case MVE_VMOV2_VEC_LANE_TO_GP:
+    case MVE_VMOV2_GP_TO_VEC_LANE:
+    case MVE_VMOV_VEC_LANE_TO_GP:
+      return TRUE;
+    default:
+      return FALSE;
+    }
 }
 
 static bfd_boolean
@@ -4323,6 +4471,40 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VBIC_IMM:
+    case MVE_VORR_IMM:
+      {
+	unsigned long cmode = arm_decode_field (given, 8, 11);
+
+	if ((cmode & 1) == 0)
+	  return TRUE;
+	else if ((cmode & 0xc) == 0xc)
+	  return TRUE;
+	else
+	  return FALSE;
+      }
+
+    case MVE_VMVN_IMM:
+      {
+	unsigned long cmode = arm_decode_field (given, 8, 11);
+
+	if ((cmode & 9) == 1)
+	  return TRUE;
+	else if ((cmode & 5) == 1)
+	  return TRUE;
+	else if ((cmode & 0xe) == 0xe)
+	  return TRUE;
+	else
+	  return FALSE;
+      }
+
+    case MVE_VMOV_IMM_TO_VEC:
+      if ((arm_decode_field (given, 5, 5) == 1)
+	  && (arm_decode_field (given, 8, 11) != 0xe))
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4615,6 +4797,67 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	  return FALSE;
       }
 
+    case MVE_VMOV_VEC_LANE_TO_GP:
+      {
+	unsigned long op1 = arm_decode_field (given, 21, 22);
+	unsigned long op2 = arm_decode_field (given, 5, 6);
+	unsigned long u = arm_decode_field (given, 23, 23);
+
+	if ((op2 == 0) && (u == 1))
+	  {
+	    if ((op1 == 0) || (op1 == 1))
+	      {
+		*undefined_code = UNDEF_BAD_U_OP1_OP2;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+	else if (op2 == 2)
+	  {
+	    if ((op1 == 0) || (op1 == 1))
+	      {
+		*undefined_code = UNDEF_BAD_OP1_OP2;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+
+	return FALSE;
+      }
+
+    case MVE_VMOV_GP_TO_VEC_LANE:
+      if (arm_decode_field (given, 5, 6) == 2)
+	{
+	  unsigned long op1 = arm_decode_field (given, 21, 22);
+	  if ((op1 == 0) || (op1 == 1))
+	    {
+	      *undefined_code = UNDEF_BAD_OP1_OP2;
+	      return TRUE;
+	    }
+	  else
+	    return FALSE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VMOV_IMM_TO_VEC:
+      if (arm_decode_field (given, 5, 5) == 0)
+      {
+	unsigned long cmode = arm_decode_field (given, 8, 11);
+
+	if (((cmode & 9) == 1) || ((cmode & 5) == 1))
+	  {
+	    *undefined_code = UNDEF_OP_0_BAD_CMODE;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -4840,6 +5083,8 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VMOV2_VEC_LANE_TO_GP:
+    case MVE_VMOV2_GP_TO_VEC_LANE:
     case MVE_VCVT_BETWEEN_FP_INT:
     case MVE_VCVT_FROM_FP_TO_INT:
       {
@@ -4865,11 +5110,224 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMOV_HFP_TO_GP:
+    case MVE_VMOV_GP_TO_VEC_LANE:
+    case MVE_VMOV_VEC_LANE_TO_GP:
+      {
+	unsigned long rda = arm_decode_field (given, 12, 15);
+	if (rda == 0xd)
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if (rda == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
     default:
       return FALSE;
     }
 }
 
+static void
+print_mve_vmov_index (struct disassemble_info *info, unsigned long given)
+{
+  unsigned long op1 = arm_decode_field (given, 21, 22);
+  unsigned long op2 = arm_decode_field (given, 5, 6);
+  unsigned long h = arm_decode_field (given, 16, 16);
+  unsigned long index, esize, targetBeat, idx;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  if ((op1 & 0x2) == 0x2)
+    {
+      index = op2;
+      esize = 8;
+    }
+  else if (((op1 & 0x2) == 0x0) && ((op2 & 0x1) == 0x1))
+    {
+      index = op2  >> 1;
+      esize = 16;
+    }
+  else if (((op1 & 0x2) == 0) && ((op2 & 0x3) == 0))
+    {
+      index = 0;
+      esize = 32;
+    }
+  else
+    {
+      func (stream, "<undefined index>");
+      return;
+    }
+
+  targetBeat =  (op1 & 0x1) | (h << 1);
+  idx = index + targetBeat * (32/esize);
+
+  func (stream, "%lu", idx);
+}
+
+/* Print neon and mve 8-bit immediate that can be a 8, 16, 32, or 64-bits
+   in length and integer of floating-point type.  */
+static void
+print_simd_imm8 (struct disassemble_info *info, unsigned long given,
+		 unsigned int ibit_loc, const struct mopcode32 *insn)
+{
+  int bits = 0;
+  int cmode = (given >> 8) & 0xf;
+  int op = (given >> 5) & 0x1;
+  unsigned long value = 0, hival = 0;
+  unsigned shift;
+  int size = 0;
+  int isfloat = 0;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  /* On Neon the 'i' bit is at bit 24, on mve it is
+     at bit 28.  */
+  bits |= ((given >> ibit_loc) & 1) << 7;
+  bits |= ((given >> 16) & 7) << 4;
+  bits |= ((given >> 0) & 15) << 0;
+
+  if (cmode < 8)
+    {
+      shift = (cmode >> 1) & 3;
+      value = (unsigned long) bits << (8 * shift);
+      size = 32;
+    }
+  else if (cmode < 12)
+    {
+      shift = (cmode >> 1) & 1;
+      value = (unsigned long) bits << (8 * shift);
+      size = 16;
+    }
+  else if (cmode < 14)
+    {
+      shift = (cmode & 1) + 1;
+      value = (unsigned long) bits << (8 * shift);
+      value |= (1ul << (8 * shift)) - 1;
+      size = 32;
+    }
+  else if (cmode == 14)
+    {
+      if (op)
+	{
+	  /* Bit replication into bytes.  */
+	  int ix;
+	  unsigned long mask;
+
+	  value = 0;
+	  hival = 0;
+	  for (ix = 7; ix >= 0; ix--)
+	    {
+	      mask = ((bits >> ix) & 1) ? 0xff : 0;
+	      if (ix <= 3)
+		value = (value << 8) | mask;
+	      else
+		hival = (hival << 8) | mask;
+	    }
+	  size = 64;
+	}
+      else
+	{
+	  /* Byte replication.  */
+	  value = (unsigned long) bits;
+	  size = 8;
+	}
+    }
+  else if (!op)
+    {
+      /* Floating point encoding.  */
+      int tmp;
+
+      value = (unsigned long)  (bits & 0x7f) << 19;
+      value |= (unsigned long) (bits & 0x80) << 24;
+      tmp = bits & 0x40 ? 0x3c : 0x40;
+      value |= (unsigned long) tmp << 24;
+      size = 32;
+      isfloat = 1;
+    }
+  else
+    {
+      func (stream, "<illegal constant %.8x:%x:%x>",
+	    bits, cmode, op);
+      size = 32;
+      return;
+    }
+
+  // printU determines whether the immediate value should be printed as
+  // unsigned.
+  unsigned printU = 0;
+  switch (insn->mve_op)
+    {
+    default:
+      break;
+    // We want this for instructions that don't have a 'signed' type
+    case MVE_VBIC_IMM:
+    case MVE_VORR_IMM:
+    case MVE_VMVN_IMM:
+    case MVE_VMOV_IMM_TO_VEC:
+      printU = 1;
+      break;
+    }
+  switch (size)
+    {
+    case 8:
+      func (stream, "#%ld\t; 0x%.2lx", value, value);
+      break;
+
+    case 16:
+      func (stream,
+	    printU
+	    ? "#%lu\t; 0x%.4lx"
+	    : "#%ld\t; 0x%.4lx", value, value);
+      break;
+
+    case 32:
+      if (isfloat)
+	{
+	  unsigned char valbytes[4];
+	  double fvalue;
+
+	  /* Do this a byte at a time so we don't have to
+	     worry about the host's endianness.  */
+	  valbytes[0] = value & 0xff;
+	  valbytes[1] = (value >> 8) & 0xff;
+	  valbytes[2] = (value >> 16) & 0xff;
+	  valbytes[3] = (value >> 24) & 0xff;
+
+	  floatformat_to_double
+	    (& floatformat_ieee_single_little, valbytes,
+	     & fvalue);
+
+	  func (stream, "#%.7g\t; 0x%.8lx", fvalue,
+		value);
+	}
+      else
+	func (stream,
+	      printU
+	      ? "#%lu\t; 0x%.8lx"
+	      : "#%ld\t; 0x%.8lx",
+	      (long) (((value & 0x80000000L) != 0)
+		      && !printU
+		      ? value | ~0xffffffffL : value),
+	      value);
+      break;
+
+    case 64:
+      func (stream, "#0x%.8lx%.8lx", hival, value);
+      break;
+
+    default:
+      abort ();
+    }
+
+}
+
 static void
 print_mve_undefined (struct disassemble_info *info,
 		     enum mve_undefined undefined_code)
@@ -4885,6 +5343,10 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "size equals zero");
       break;
 
+    case UNDEF_SIZE_2:
+      func (stream, "size equals two");
+      break;
+
     case UNDEF_SIZE_3:
       func (stream, "size equals three");
       break;
@@ -4921,6 +5383,18 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "fsi = 0 and invalid imm6");
       break;
 
+    case UNDEF_BAD_OP1_OP2:
+      func (stream, "bad size with op2 = 2 and op1 = 0 or 1");
+      break;
+
+    case UNDEF_BAD_U_OP1_OP2:
+      func (stream, "unsigned with op2 = 0 and op1 = 0 or 1");
+      break;
+
+    case UNDEF_OP_0_BAD_CMODE:
+      func (stream, "op field equal 0 and bad cmode");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4979,6 +5453,14 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "same arm register used for both operands");
       break;
 
+    case UNPRED_Q_REGS_EQ_AND_SIZE_1:
+      func (stream, "use of identical q registers and size = 1");
+      break;
+
+    case UNPRED_Q_REGS_EQ_AND_SIZE_2:
+      func (stream, "use of identical q registers and size = 1");
+      break;
+
     case UNPRED_NONE:
       break;
     }
@@ -5342,6 +5824,88 @@ print_mve_size (struct disassemble_info *info,
 	}
       break;
 
+    case MVE_VMOV_GP_TO_VEC_LANE:
+    case MVE_VMOV_VEC_LANE_TO_GP:
+      switch (size)
+	{
+	case 0: case 4:
+	  func (stream, "32");
+	  break;
+
+	case 1: case 3:
+	case 5: case 7:
+	  func (stream, "16");
+	  break;
+
+	case 8: case 9: case 10: case 11:
+	case 12: case 13: case 14: case 15:
+	  func (stream, "8");
+	  break;
+
+	default:
+	  break;
+	}
+      break;
+
+    case MVE_VMOV_IMM_TO_VEC:
+      switch (size)
+	{
+	case 0: case 4: case 8:
+	case 12: case 24: case 26:
+	  func (stream, "i32");
+	  break;
+	case 16: case 20:
+	  func (stream, "i16");
+	  break;
+	case 28:
+	  func (stream, "i8");
+	  break;
+	case 29:
+	  func (stream, "i64");
+	  break;
+	case 30:
+	  func (stream, "f32");
+	  break;
+	default:
+	  break;
+	}
+      break;
+
+    case MVE_VMVN_IMM:
+      switch (size)
+	{
+	case 0: case 2: case 4:
+	case 6: case 12: case 13:
+	  func (stream, "32");
+	  break;
+
+	case 8: case 10:
+	  func (stream, "16");
+	  break;
+
+	default:
+	  break;
+	}
+      break;
+
+    case MVE_VBIC_IMM:
+    case MVE_VORR_IMM:
+      switch (size)
+	{
+	case 1: case 3:
+	case 5: case 7:
+	  func (stream, "32");
+	  break;
+
+	case 9: case 11:
+	  func (stream, "16");
+	  break;
+
+	default:
+	  break;
+	}
+      break;
+
     default:
       break;
     }
@@ -5566,7 +6130,6 @@ print_insn_coprocessor (bfd_vma pc,
 	   don't let it match here.  */
 	continue;
 
-
       for (c = insn->assembler; *c; c++)
 	{
 	  if (*c == '%')
@@ -6833,10 +7396,30 @@ print_insn_mve (struct disassemble_info *info, long given)
 
 		    case 'u':
 		      {
-			if (arm_decode_field (given, 28, 28) == 0)
-			  func (stream, "s");
+			unsigned long op1 = arm_decode_field (given, 21, 22);
+
+			if ((insn->mve_op == MVE_VMOV_VEC_LANE_TO_GP))
+			  {
+			    /* Check for signed.  */
+			    if (arm_decode_field (given, 23, 23) == 0)
+			      {
+				/* We don't print 's' for S32.  */
+				if ((arm_decode_field (given, 5, 6) == 0)
+				    && ((op1 == 0) || (op1 == 1)))
+				  ;
+				else
+				  func (stream, "s");
+			      }
+			    else
+			      func (stream, "u");
+			  }
 			else
-			  func (stream, "u");
+			  {
+			    if (arm_decode_field (given, 28, 28) == 0)
+			      func (stream, "s");
+			    else
+			      func (stream, "u");
+			  }
 		      }
 		      break;
 
@@ -6853,6 +7436,16 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_mve_register_blocks (info, given, insn->mve_op);
 		      break;
 
+		    case 'E':
+		      /* SIMD encoded constant for mov, mvn, vorr, vbic.  */
+
+		      print_simd_imm8 (info, given, 28, insn);
+		      break;
+
+		    case 'N':
+		      print_mve_vmov_index (info, given);
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {
@@ -6910,12 +7503,18 @@ print_insn_mve (struct disassemble_info *info, long given)
 			    func (stream, "%ld", value);
 			    value_in_comment = value;
 			    break;
+			  case 'F':
+			    func (stream, "s%ld", value);
+			    break;
 			  case 'Q':
 			    if (value & 0x8)
 			      func (stream, "<illegal reg q%ld.5>", value);
 			    else
 			      func (stream, "q%ld", value);
 			    break;
+			  case 'x':
+			    func (stream, "0x%08lx", value);
+			    break;
 			  default:
 			    abort ();
 			  }

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull, vqmovn, vqmovun and vmovn
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (45 preceding siblings ...)
  2019-05-01 17:44 ` [PATCH 45/57][Arm][OBJDUMP] Add support for MVE instructions: vmov, vmvn, vorr, vorn, vmovx and vbic Andre Vieira (lists)
@ 2019-05-01 17:44 ` Andre Vieira (lists)
  2019-05-01 17:45 ` [PATCH 47/57][Arm][OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmladav, vmlas, vrmlsldavh, vmlsldav, vmlsdav, vrmlaldavh, vqdmlah, vqrdmlash, vqrdmlash, vqdmlsdh, vqrdmlsdh, vqdmulh and vqrdmulh Andre Vieira (lists)
                   ` (13 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:44 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 479 bytes --]

Hi,

This patch adds support for MVE instructions: VMOVL, VMULL, VQDMULL, 
VQMOVN, VQMOVUN, and VMOVN.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 46.patch --]
[-- Type: text/x-patch, Size: 6890 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index eb468afc2bc15725709bf9033e0b1288545429b4..e6383355496aa2ef8dc8dd5f5fc3bd1ffcb67905 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -144,6 +144,14 @@ enum mve_instructions
   MVE_VBIC_IMM,
   MVE_VBIC_REG,
   MVE_VMOVX,
+  MVE_VMOVL,
+  MVE_VMOVN,
+  MVE_VMULL_INT,
+  MVE_VMULL_POLY,
+  MVE_VQDMULL_T1,
+  MVE_VQDMULL_T2,
+  MVE_VQMOVN,
+  MVE_VQMOVUN,
   MVE_NONE
 };
 
@@ -1913,6 +1921,7 @@ static const struct opcode32 neon_opcodes[] =
    %B			print v{st,ld}[24] any one operands
    %E			print vmov, vmvn, vorr, vbic encoded constant
    %N			print generic index for vmov
+   %T			print bottom ('b') or top ('t') of source register
 
    %<bitfield>r		print as an ARM register
    %<bitfield>d		print the bitfield in decimal
@@ -2280,12 +2289,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xee100b10, 0xff100f1f,
    "vmov%c.%u%5-6,21-22s\t%12-15r, %17-19,7Q[%N]"},
 
+  /* Vector VMOVL long.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOVL,
+   0xeea00f40, 0xefa70fd1,
+   "vmovl%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VMOV and narrow.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMOVN,
+   0xfe310e81, 0xffb30fd1,
+   "vmovn%T%v.i%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Floating point move extract.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VMOVX,
    0xfeb00a40, 0xffbf0fd0,
    "vmovx.f16\t%22,12-15F, %5,0-3F"},
 
+  /* Vector VMULL integer.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMULL_INT,
+   0xee010e00, 0xef810f51,
+   "vmull%T%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMULL polynomial.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMULL_POLY,
+   0xee310e00, 0xefb10f51,
+   "vmull%T%v.%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VMVN immediate to vector.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VMVN_IMM,
@@ -2310,6 +2343,30 @@ static const struct mopcode32 mve_opcodes[] =
    0xef200150, 0xffb11f51,
    "vorr%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VQDMULL T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULL_T1,
+   0xee300f01, 0xefb10f51,
+   "vqdmull%T%v.s%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMULL T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULL_T2,
+   0xee300f60, 0xefb10f70,
+   "vqdmull%T%v.s%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQMOVN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQMOVN,
+   0xee330e01, 0xefb30fd1,
+   "vqmovn%T%v.%u%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VQMOVUN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQMOVUN,
+   0xee310e81, 0xffb30fd1,
+   "vqmovun%T%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
@@ -4420,6 +4477,7 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMULL_INT:
     case MVE_VHADD_T2:
     case MVE_VHSUB_T2:
     case MVE_VCMP_VEC_T1:
@@ -4505,6 +4563,23 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMOVL:
+      {
+	unsigned long size = arm_decode_field (given, 19, 20);
+	if ((size == 0) || (size == 3))
+	  return TRUE;
+	else
+	  return FALSE;
+      }
+
+    case MVE_VMOVN:
+    case MVE_VQMOVUN:
+    case MVE_VQMOVN:
+      if (arm_decode_field (given, 18, 19) == 3)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4858,6 +4933,15 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VMOVN:
+      if (arm_decode_field (given, 18, 19) == 2)
+	{
+	  *undefined_code = UNDEF_SIZE_2;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5129,6 +5213,86 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMULL_INT:
+      {
+	unsigned long Qd;
+	unsigned long Qm;
+	unsigned long Qn;
+
+	if (arm_decode_field (given, 20, 21) == 2)
+	  {
+	    Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	    Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	    Qn = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	    if ((Qd == Qn) || (Qd == Qm))
+	      {
+		*unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_2;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VQDMULL_T1:
+      {
+	unsigned long Qd;
+	unsigned long Qm;
+	unsigned long Qn;
+
+	if (arm_decode_field (given, 28, 28) == 1)
+	  {
+	    Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	    Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	    Qn = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	    if ((Qd == Qn) || (Qd == Qm))
+	      {
+		*unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VQDMULL_T2:
+      {
+	unsigned long gpr = arm_decode_field (given, 0, 3);
+	if (gpr == 0xd)
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if (gpr == 0xf)
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+
+	if (arm_decode_field (given, 28, 28) == 1)
+	  {
+	    unsigned long Qd
+	      = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	    unsigned long Qn = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	    if ((Qd == Qn))
+	      {
+		*unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+
+	return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -5807,6 +5971,24 @@ print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VMOVN:
+    case MVE_VQDMULL_T1:
+    case MVE_VQDMULL_T2:
+    case MVE_VQMOVN:
+    case MVE_VQMOVUN:
+      if (size == 0)
+	func (stream, "16");
+      else if (size == 1)
+	func (stream, "32");
+      break;
+
+    case MVE_VMOVL:
+      if (size == 1)
+	func (stream, "8");
+      else if (size == 2)
+	func (stream, "16");
+      break;
+
     case MVE_VDUP:
       switch (size)
 	{
@@ -5871,6 +6053,13 @@ print_mve_size (struct disassemble_info *info,
 	}
       break;
 
+    case MVE_VMULL_POLY:
+      if (size == 0)
+	func (stream, "p8");
+      else if (size == 1)
+	func (stream, "p16");
+      break;
+
     case MVE_VMVN_IMM:
       switch (size)
 	{
@@ -7446,6 +7635,13 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      print_mve_vmov_index (info, given);
 		      break;
 
+		    case 'T':
+		      if (arm_decode_field (given, 12, 12) == 0)
+			func (stream, "b");
+		      else
+			func (stream, "t");
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 47/57][Arm][OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmladav, vmlas, vrmlsldavh, vmlsldav, vmlsdav, vrmlaldavh, vqdmlah, vqrdmlash, vqrdmlash, vqdmlsdh, vqrdmlsdh, vqdmulh and vqrdmulh
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (46 preceding siblings ...)
  2019-05-01 17:44 ` [PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull, vqmovn, vqmovun and vmovn Andre Vieira (lists)
@ 2019-05-01 17:45 ` Andre Vieira (lists)
  2019-05-01 17:46 ` [PATCH 48/57][Arm][OBJDUMP] Add support for MVE instructions: vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
                   ` (12 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:45 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 654 bytes --]

Hello,

This patch adds support for MVE instructions: VADDV, VMLALDAV, VMLADAV, 
VMLAS, VRMLSLDAVH, VLSLDAV, VLSDAV, VRMLALDAVH, VQDLAH, VQRDMLASH, 
VQRDMLASH, VQDMLSDH, VQRDMLSDH, VQDMULH, and VQRDMULH.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_undefined): Add new reasons.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 47.patch --]
[-- Type: text/x-patch, Size: 12370 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index e6383355496aa2ef8dc8dd5f5fc3bd1ffcb67905..006475d40046fc75df94ce29b595f220fda1c3ee 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -152,6 +152,29 @@ enum mve_instructions
   MVE_VQDMULL_T2,
   MVE_VQMOVN,
   MVE_VQMOVUN,
+  MVE_VADDV,
+  MVE_VMLADAV_T1,
+  MVE_VMLADAV_T2,
+  MVE_VMLALDAV,
+  MVE_VMLAS,
+  MVE_VADDLV,
+  MVE_VMLSDAV_T1,
+  MVE_VMLSDAV_T2,
+  MVE_VMLSLDAV,
+  MVE_VRMLALDAVH,
+  MVE_VRMLSLDAVH,
+  MVE_VQDMLADH,
+  MVE_VQRDMLADH,
+  MVE_VQDMLAH,
+  MVE_VQRDMLAH,
+  MVE_VQDMLASH,
+  MVE_VQRDMLASH,
+  MVE_VQDMLSDH,
+  MVE_VQRDMLSDH,
+  MVE_VQDMULH_T1,
+  MVE_VQRDMULH_T2,
+  MVE_VQDMULH_T3,
+  MVE_VQRDMULH_T4,
   MVE_NONE
 };
 
@@ -203,6 +226,7 @@ enum mve_undefined
 				   op2 == 0 and op1 == (0 or 1).  */
   UNDEF_OP_0_BAD_CMODE,		/* undefined because op == 0 and cmode
 				   in {0xx1, x0x1}.  */
+  UNDEF_XCHG_UNS,		/* undefined because X == 1 and U == 1.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1922,9 +1946,11 @@ static const struct opcode32 neon_opcodes[] =
    %E			print vmov, vmvn, vorr, vbic encoded constant
    %N			print generic index for vmov
    %T			print bottom ('b') or top ('t') of source register
+   %X			print exchange field in vmla* instructions
 
    %<bitfield>r		print as an ARM register
    %<bitfield>d		print the bitfield in decimal
+   %<bitfield>A		print accumulate or not
    %<bitfield>Q		print as a MVE Q register
    %<bitfield>F		print as a MVE S register
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
@@ -1999,6 +2025,18 @@ static const struct mopcode32 mve_opcodes[] =
    0xef100150, 0xffb11f51,
    "vbic%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VADDLV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADDLV,
+   0xee890f00, 0xef8f1fd1,
+   "vaddlv%5A%v.%u32\t%13-15l, %20-22h, %1-3Q"},
+
+  /* Vector VADDV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADDV,
+   0xeef10f00, 0xeff31fd1,
+   "vaddv%5A%v.%u%18-19s\t%13-15l, %1-3Q"},
+
   /* Vector VCMP floating point T1.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMP_FP_T1,
@@ -2222,6 +2260,74 @@ static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VMLALDAV.  Note must appear before VMLADAV due to instruction
+     opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLALDAV,
+   0xee801e00, 0xef801f51,
+   "vmlaldav%5Ax%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLALDAV,
+   0xee800e00, 0xef801f51,
+   "vmlalv%5A%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAV T1 variant, same as VMLADAV but with X == 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T1,
+   0xeef00e00, 0xeff01f51,
+   "vmlav%5A%v.%u%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAV T2 variant, same as VMLADAV but with X == 0.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T2,
+   0xeef00f00, 0xeff11f51,
+   "vmlav%5A%v.%u8\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLADAV T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T1,
+   0xeef01e00, 0xeff01f51,
+   "vmladav%5Ax%v.%u%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLADAV T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLADAV_T2,
+   0xeef01f00, 0xeff11f51,
+   "vmladav%5Ax%v.%u8\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLAS.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLAS,
+   0xee011e40, 0xef811f70,
+   "vmlas%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VRMLSLDAVH.  Note must appear before VMLSDAV due to instruction
+     opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLSLDAVH,
+   0xfe800e01, 0xff810f51,
+   "vrmlsldavh%5A%X%v.s32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSLDAV.  Note must appear before VMLSDAV due to instruction
+     opcdoe aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSLDAV,
+   0xee800e01, 0xff800f51,
+   "vmlsldav%5A%X%v.%u%16s\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSDAV T1 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSDAV_T1,
+   0xeef00e01, 0xfff00f51,
+   "vmlsdav%5A%X%v.s%16s\t%13-15l, %17-19,7Q, %1-3Q"},
+
+  /* Vector VMLSDAV T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLSDAV_T2,
+   0xfef00e01, 0xfff10f51,
+   "vmlsdav%5A%X%v.s8\t%13-15l, %17-19,7Q, %1-3Q"},
+
   /* Vector VMOV between gpr and half precision register, op == 0.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VMOV_HFP_TO_GP,
@@ -2367,12 +2473,96 @@ static const struct mopcode32 mve_opcodes[] =
    0xee310e81, 0xffb30fd1,
    "vqmovun%T%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VQDMLADH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLADH,
+   0xee000e00, 0xff810f51,
+   "vqdmladh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMLADH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLADH,
+   0xee000e01, 0xff810f51,
+   "vqrdmladh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMLAH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLAH,
+   0xee000e60, 0xef811f70,
+   "vqdmlah%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMLAH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLAH,
+   0xee000e40, 0xef811f70,
+   "vqrdmlah%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQDMLASH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLASH,
+   0xee001e60, 0xef811f70,
+   "vqdmlash%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMLASH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLASH,
+   0xee001e40, 0xef811f70,
+   "vqrdmlash%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQDMLSDH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMLSDH,
+   0xfe000e00, 0xff810f51,
+   "vqdmlsdh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMLSDH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMLSDH,
+   0xfe000e01, 0xff810f51,
+   "vqrdmlsdh%X%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMULH T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULH_T1,
+   0xef000b40, 0xff811f51,
+   "vqdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQRDMULH T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMULH_T2,
+   0xff000b40, 0xff811f51,
+   "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQDMULH T3 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQDMULH_T3,
+   0xee010e60, 0xff811f70,
+   "vqdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VQRDMULH T4 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRDMULH_T4,
+   0xfe010e60, 0xff811f70,
+   "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
    0xffb20440, 0xffb31c51,
    "vrint%m%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VRMLALDAVH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLALDAVH,
+   0xee800f00, 0xef811f51,
+   "vrmlalvh%5A%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
+  /* Vector VRMLALDAVH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMLALDAVH,
+   0xee801f00, 0xef811f51,
+   "vrmlaldavh%5Ax%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -4477,6 +4667,17 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
+    case MVE_VQDMLADH:
+    case MVE_VMLAS:
     case MVE_VMULL_INT:
     case MVE_VHADD_T2:
     case MVE_VHSUB_T2:
@@ -4572,6 +4773,7 @@ is_mve_encoding_conflict (unsigned long given,
 	  return FALSE;
       }
 
+    case MVE_VADDV:
     case MVE_VMOVN:
     case MVE_VQMOVUN:
     case MVE_VQMOVN:
@@ -4580,6 +4782,21 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMLSLDAV:
+    case MVE_VRMLSLDAVH:
+    case MVE_VMLALDAV:
+    case MVE_VADDLV:
+      if (arm_decode_field (given, 20, 22) == 7)
+	return TRUE;
+      else
+	return FALSE;
+
+    case MVE_VRMLALDAVH:
+      if ((arm_decode_field (given, 20, 22) & 6) == 6)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -4681,6 +4898,8 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VQDMULH_T1:
+    case MVE_VQRDMULH_T2:
     case MVE_VRHADD:
     case MVE_VHADD_T1:
     case MVE_VHSUB_T1:
@@ -4942,6 +5161,19 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VRMLALDAVH:
+    case MVE_VMLADAV_T1:
+    case MVE_VMLADAV_T2:
+    case MVE_VMLALDAV:
+      if ((arm_decode_field (given, 28, 28) == 1)
+	  && (arm_decode_field (given, 12, 12) == 1))
+	{
+	  *undefined_code = UNDEF_XCHG_UNS;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5001,6 +5233,13 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
+    case MVE_VMLAS:
     case MVE_VFMA_FP_SCALAR:
     case MVE_VFMAS_FP_SCALAR:
     case MVE_VHADD_T2:
@@ -5213,6 +5452,10 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMLADH:
     case MVE_VMULL_INT:
       {
 	unsigned long Qd;
@@ -5293,6 +5536,18 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMLSLDAV:
+    case MVE_VRMLSLDAVH:
+    case MVE_VMLALDAV:
+    case MVE_VADDLV:
+      if (arm_decode_field (given, 20, 22) == 6)
+	{
+	  *unpredictable_code = UNPRED_R13;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5559,6 +5814,10 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "op field equal 0 and bad cmode");
       break;
 
+    case UNDEF_XCHG_UNS:
+      func (stream, "exchange and unsigned together");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -5918,6 +6177,7 @@ print_mve_size (struct disassemble_info *info,
 
   switch (matched_insn)
     {
+    case MVE_VADDV:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
@@ -5936,12 +6196,25 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VLDRD_GATHER_T4:
     case MVE_VLDRB_T1:
     case MVE_VLDRH_T2:
+    case MVE_VMLAS:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
     case MVE_VPT_VEC_T4:
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
+    case MVE_VQDMLADH:
+    case MVE_VQRDMLADH:
+    case MVE_VQDMLAH:
+    case MVE_VQRDMLAH:
+    case MVE_VQDMLASH:
+    case MVE_VQRDMLASH:
+    case MVE_VQDMLSDH:
+    case MVE_VQRDMLSDH:
+    case MVE_VQDMULH_T1:
+    case MVE_VQRDMULH_T2:
+    case MVE_VQDMULH_T3:
+    case MVE_VQRDMULH_T4:
     case MVE_VRHADD:
     case MVE_VRINT_FP:
     case MVE_VST2:
@@ -5971,6 +6244,10 @@ print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VMLADAV_T1:
+    case MVE_VMLALDAV:
+    case MVE_VMLSDAV_T1:
+    case MVE_VMLSLDAV:
     case MVE_VMOVN:
     case MVE_VQDMULL_T1:
     case MVE_VQDMULL_T2:
@@ -7642,6 +7919,11 @@ print_insn_mve (struct disassemble_info *info, long given)
 			func (stream, "t");
 		      break;
 
+		    case 'X':
+		      if (arm_decode_field (given, 12, 12) == 1)
+			func (stream, "x");
+		      break;
+
 		    case '0': case '1': case '2': case '3': case '4':
 		    case '5': case '6': case '7': case '8': case '9':
 		      {
@@ -7665,6 +7947,10 @@ print_insn_mve (struct disassemble_info *info, long given)
 					    value,
 					    insn->mve_op);
 			    break;
+			  case 'A':
+			    if (value == 1)
+			      func (stream, "a");
+			    break;
 			  case 'i':
 			    {
 			      unsigned long imm

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 49/57][Arm][OBJDUMP] Add support for MVE complex number instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (48 preceding siblings ...)
  2019-05-01 17:46 ` [PATCH 48/57][Arm][OBJDUMP] Add support for MVE instructions: vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
@ 2019-05-01 17:46 ` Andre Vieira (lists)
  2019-05-01 17:47 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (10 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:46 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 464 bytes --]

Hello,

This patch adds support for MVE instructions: VCADD, VHCADD, VCMLA, and 
VCMUL.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_rotate): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 49.patch --]
[-- Type: text/x-patch, Size: 6047 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 1dae51d8a0889e288e85876be280bfaea2a4c785..f2e244d104cdb1938ea2a9b8066647b485aaaa1f 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -179,6 +179,11 @@ enum mve_instructions
   MVE_VDWDUP,
   MVE_VIWDUP,
   MVE_VIDUP,
+  MVE_VCADD_FP,
+  MVE_VCADD_VEC,
+  MVE_VHCADD,
+  MVE_VCMLA_FP,
+  MVE_VCMUL_FP,
   MVE_NONE
 };
 
@@ -1964,6 +1969,7 @@ static const struct opcode32 neon_opcodes[] =
    %<bitfield>h		print high half of 64-bit destination reg
    %<bitfield>k		print immediate for vector conversion instruction
    %<bitfield>l		print low half of 64-bit destination reg
+   %<bitfield>o		print rotate value for vcmul
    %<bitfield>u		print immediate value for vddup/vdwdup
    %<bitfield>x		print the bitfield in hex.
   */
@@ -2044,6 +2050,24 @@ static const struct mopcode32 mve_opcodes[] =
    0xeef10f00, 0xeff31fd1,
    "vaddv%5A%v.%u%18-19s\t%13-15l, %1-3Q"},
 
+  /* Vector VCADD floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCADD_FP,
+   0xfc800840, 0xfea11f51,
+   "vcadd%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%24o"},
+
+  /* Vector VCADD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCADD_VEC,
+   0xfe000f00, 0xff810f51,
+   "vcadd%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%12o"},
+
+  /* Vector VCMLA.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMLA_FP,
+   0xfc200840, 0xfe211f51,
+   "vcmla%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%23-24o"},
+
   /* Vector VCMP floating point T1.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMP_FP_T1,
@@ -2147,6 +2171,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xee001f40, 0xef811f70,
    "vhsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
 
+  /* Vector VCMUL.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCMUL_FP,
+   0xee300e00, 0xefb10f50,
+   "vcmul%v.f%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%0,12o"},
+
   /* Vector VDUP.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VDUP,
@@ -2201,6 +2231,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xee011f60, 0xff811f70,
    "vdwdup%v.u%20-21s\t%13-15,22Q, %17-19l, %1-3h, #%0,7u"},
 
+  /* Vector VHCADD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VHCADD,
+   0xee000f00, 0xff810f51,
+   "vhcadd%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%12o"},
+
   /* Vector VIWDUP.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VIWDUP,
@@ -4698,6 +4734,8 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VCADD_VEC:
+    case MVE_VHCADD:
     case MVE_VDDUP:
     case MVE_VIDUP:
     case MVE_VQRDMLADH:
@@ -5521,6 +5559,7 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	  return FALSE;
       }
 
+    case MVE_VCMUL_FP:
     case MVE_VQDMULL_T1:
       {
 	unsigned long Qd;
@@ -5599,6 +5638,58 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCADD_VEC:
+    case MVE_VHCADD:
+      {
+	unsigned long Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	if ((Qd == Qm) && arm_decode_field (given, 20, 21) == 2)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_2;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VCADD_FP:
+      {
+	unsigned long Qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	if ((Qd == Qm) && arm_decode_field (given, 20, 20) == 1)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VCMLA_FP:
+      {
+	unsigned long Qda;
+	unsigned long Qm;
+	unsigned long Qn;
+
+	if (arm_decode_field (given, 20, 20) == 1)
+	  {
+	    Qda = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	    Qm = arm_decode_field_multiple (given, 1, 3, 5, 5);
+	    Qn = arm_decode_field_multiple (given, 17, 19, 7, 7);
+
+	    if ((Qda == Qn) || (Qda == Qm))
+	      {
+		*unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1;
+		return TRUE;
+	      }
+	    else
+	      return FALSE;
+	  }
+	else
+	  return FALSE;
+
+      }
+
     default:
       return FALSE;
     }
@@ -6206,6 +6297,49 @@ print_mve_vcvt_size (struct disassemble_info *info,
     }
 }
 
+static void
+print_mve_rotate (struct disassemble_info *info, unsigned long rot,
+		  unsigned long rot_width)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  if (rot_width == 1)
+    {
+      switch (rot)
+	{
+	case 0:
+	  func (stream, "90");
+	  break;
+	case 1:
+	  func (stream, "270");
+	  break;
+	default:
+	  break;
+	}
+    }
+  else if (rot_width == 2)
+    {
+      switch (rot)
+	{
+	case 0:
+	  func (stream, "0");
+	  break;
+	case 1:
+	  func (stream, "90");
+	  break;
+	case 2:
+	  func (stream, "180");
+	  break;
+	case 3:
+	  func (stream, "270");
+	  break;
+	default:
+	  break;
+	}
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -6229,6 +6363,7 @@ print_mve_size (struct disassemble_info *info,
   switch (matched_insn)
     {
     case MVE_VADDV:
+    case MVE_VCADD_VEC:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
@@ -6239,6 +6374,7 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VDWDUP:
     case MVE_VHADD_T1:
     case MVE_VHADD_T2:
+    case MVE_VHCADD:
     case MVE_VHSUB_T1:
     case MVE_VHSUB_T2:
     case MVE_VIDUP:
@@ -6299,6 +6435,9 @@ print_mve_size (struct disassemble_info *info,
 	func (stream, "16");
       break;
 
+    case MVE_VCADD_FP:
+    case MVE_VCMLA_FP:
+    case MVE_VCMUL_FP:
     case MVE_VMLADAV_T1:
     case MVE_VMLALDAV:
     case MVE_VMLSDAV_T1:
@@ -8064,6 +8203,9 @@ print_insn_mve (struct disassemble_info *info, long given)
 				break;
 			      }
 			    break;
+			  case 'o':
+			    print_mve_rotate (info, value, width);
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 48/57][Arm][OBJDUMP] Add support for MVE instructions: vddup, vdwdup, vidup and viwdup
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (47 preceding siblings ...)
  2019-05-01 17:45 ` [PATCH 47/57][Arm][OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmladav, vmlas, vrmlsldavh, vmlsldav, vmlsdav, vrmlaldavh, vqdmlah, vqrdmlash, vqrdmlash, vqdmlsdh, vqrdmlsdh, vqdmulh and vqrdmulh Andre Vieira (lists)
@ 2019-05-01 17:46 ` Andre Vieira (lists)
  2019-05-01 17:46 ` [PATCH 49/57][Arm][OBJDUMP] Add support for MVE complex number instructions Andre Vieira (lists)
                   ` (11 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:46 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 434 bytes --]

Hello,

This patch adds support for MVE instructions: VDDUP, VDWDUP, VIDUP, and 
VIWDUP.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 48.patch --]
[-- Type: text/x-patch, Size: 4183 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 006475d40046fc75df94ce29b595f220fda1c3ee..1dae51d8a0889e288e85876be280bfaea2a4c785 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -175,6 +175,10 @@ enum mve_instructions
   MVE_VQRDMULH_T2,
   MVE_VQDMULH_T3,
   MVE_VQRDMULH_T4,
+  MVE_VDDUP,
+  MVE_VDWDUP,
+  MVE_VIWDUP,
+  MVE_VIDUP,
   MVE_NONE
 };
 
@@ -1957,9 +1961,12 @@ static const struct opcode32 neon_opcodes[] =
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
    %<bitfield>i		print immediate for vstr/vldr reg +/- imm
+   %<bitfield>h		print high half of 64-bit destination reg
    %<bitfield>k		print immediate for vector conversion instruction
+   %<bitfield>l		print low half of 64-bit destination reg
+   %<bitfield>u		print immediate value for vddup/vdwdup
    %<bitfield>x		print the bitfield in hex.
- */
+  */
 
 static const struct mopcode32 mve_opcodes[] =
 {
@@ -2182,6 +2189,30 @@ static const struct mopcode32 mve_opcodes[] =
    0xffb30040, 0xffb31c51,
    "vcvt%m%v.%s\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VDDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VDDUP,
+   0xee011f6e, 0xff811f7e,
+   "vddup%v.u%20-21s\t%13-15,22Q, %17-19l, #%0,7u"},
+
+  /* Vector VDWDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VDWDUP,
+   0xee011f60, 0xff811f70,
+   "vdwdup%v.u%20-21s\t%13-15,22Q, %17-19l, %1-3h, #%0,7u"},
+
+  /* Vector VIWDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VIWDUP,
+   0xee010f60, 0xff811f70,
+   "viwdup%v.u%20-21s\t%13-15,22Q, %17-19l, %1-3h, #%0,7u"},
+
+  /* Vector VIDUP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VIDUP,
+   0xee010f6e, 0xff811f7e,
+   "vidup%v.u%20-21s\t%13-15,22Q, %17-19l, #%0,7u"},
+
   /* Vector VLD2.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VLD2,
@@ -4667,6 +4698,8 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VDDUP:
+    case MVE_VIDUP:
     case MVE_VQRDMLADH:
     case MVE_VQDMLAH:
     case MVE_VQRDMLAH:
@@ -4797,6 +4830,14 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VDWDUP:
+    case MVE_VIWDUP:
+      if ((arm_decode_field (given, 20, 21) == 3)
+	  || (arm_decode_field (given, 1, 3) == 7))
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -5548,6 +5589,16 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VDWDUP:
+    case MVE_VIWDUP:
+      if (arm_decode_field (given, 1, 3) == 6)
+	{
+	  *unpredictable_code = UNPRED_R13;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -6184,10 +6235,14 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VCMP_VEC_T4:
     case MVE_VCMP_VEC_T5:
     case MVE_VCMP_VEC_T6:
+    case MVE_VDDUP:
+    case MVE_VDWDUP:
     case MVE_VHADD_T1:
     case MVE_VHADD_T2:
     case MVE_VHSUB_T1:
     case MVE_VHSUB_T2:
+    case MVE_VIDUP:
+    case MVE_VIWDUP:
     case MVE_VLD2:
     case MVE_VLD4:
     case MVE_VLDRB_GATHER_T1:
@@ -7951,6 +8006,12 @@ print_insn_mve (struct disassemble_info *info, long given)
 			    if (value == 1)
 			      func (stream, "a");
 			    break;
+			  case 'h':
+			    {
+			      unsigned int odd_reg = (value << 1) | 1;
+			      func (stream, "%s", arm_regnames[odd_reg]);
+			    }
+			    break;
 			  case 'i':
 			    {
 			      unsigned long imm
@@ -7978,6 +8039,31 @@ print_insn_mve (struct disassemble_info *info, long given)
 			  case 'k':
 			    func (stream, "%lu", 64 - value);
 			    break;
+			  case 'l':
+			    {
+			      unsigned int even_reg = value << 1;
+			      func (stream, "%s", arm_regnames[even_reg]);
+			    }
+			    break;
+			  case 'u':
+			    switch (value)
+			      {
+			      case 0:
+				func (stream, "1");
+				break;
+			      case 1:
+				func (stream, "2");
+				break;
+			      case 2:
+				func (stream, "4");
+				break;
+			      case 3:
+				func (stream, "8");
+				break;
+			      default:
+				break;
+			      }
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (49 preceding siblings ...)
  2019-05-01 17:46 ` [PATCH 49/57][Arm][OBJDUMP] Add support for MVE complex number instructions Andre Vieira (lists)
@ 2019-05-01 17:47 ` Andre Vieira (lists)
  2019-05-01 17:48 ` [PATCH 52/57][Arm][OBJDUMP] Add support for MVE instructions: vadc, vabav, vabd, vabs, vadd, vsbc and vsub Andre Vieira (lists)
                   ` (9 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:47 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 553 bytes --]

Hello,

This patch adds support for all MVE vector shift instructions.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (enum mve_instructions): Add new instructions.
	(enum mve_undefined): Add new reasons.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_size): Likewise.
	(print_mve_shift_n): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 50.patch --]
[-- Type: text/x-patch, Size: 13532 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index f2e244d104cdb1938ea2a9b8066647b485aaaa1f..56255d5f61dd29b72e02469894186734ca1b4346 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -184,6 +184,30 @@ enum mve_instructions
   MVE_VHCADD,
   MVE_VCMLA_FP,
   MVE_VCMUL_FP,
+  MVE_VQRSHL_T1,
+  MVE_VQRSHL_T2,
+  MVE_VQRSHRN,
+  MVE_VQRSHRUN,
+  MVE_VQSHL_T1,
+  MVE_VQSHL_T2,
+  MVE_VQSHLU_T3,
+  MVE_VQSHL_T4,
+  MVE_VQSHRN,
+  MVE_VQSHRUN,
+  MVE_VRSHL_T1,
+  MVE_VRSHL_T2,
+  MVE_VRSHR,
+  MVE_VRSHRN,
+  MVE_VSHL_T1,
+  MVE_VSHL_T2,
+  MVE_VSHL_T3,
+  MVE_VSHLC,
+  MVE_VSHLL_T1,
+  MVE_VSHLL_T2,
+  MVE_VSHR,
+  MVE_VSHRN,
+  MVE_VSLI,
+  MVE_VSRI,
   MVE_NONE
 };
 
@@ -216,6 +240,7 @@ enum mve_unpredictable
 
 enum mve_undefined
 {
+  UNDEF_SIZE,			/* undefined size.  */
   UNDEF_SIZE_0,			/* undefined because size == 0.  */
   UNDEF_SIZE_2,			/* undefined because size == 2.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
@@ -2420,6 +2445,63 @@ static const struct mopcode32 mve_opcodes[] =
    0xef800050, 0xefb810f0,
    "vorr%v.i%8-11s\t%13-15,22Q, %E"},
 
+  /* Vector VQSHL T2 Variant.
+     NOTE: MVE_VQSHL_T2 must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHL_T2,
+   0xef800750, 0xef801fd1,
+   "vqshl%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VQSHLU T3 Variant
+     NOTE: MVE_VQSHL_T2 must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHLU_T3,
+   0xff800650, 0xff801fd1,
+   "vqshlu%v.s%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VRSHR
+     NOTE: MVE_VRSHR must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRSHR,
+   0xef800250, 0xef801fd1,
+   "vrshr%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VSHL.
+     NOTE: MVE_VSHL must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHL_T1,
+   0xef800550, 0xff801fd1,
+   "vshl%v.i%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VSHR
+     NOTE: MVE_VSHR must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHR,
+   0xef800050, 0xef801fd1,
+   "vshr%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VSLI
+     NOTE: MVE_VSLI must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSLI,
+   0xff800550, 0xff801fd1,
+   "vsli%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VSRI
+     NOTE: MVE_VSRI must appear in the table before
+     before MVE_VMOV_IMM_TO_VEC due to opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSRI,
+   0xff800450, 0xff801fd1,
+   "vsri%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
   /* Vector VMOV immediate to vector,
      cmode == 11x1 -> VMVN which is UNDEFINED
      for such a cmode.  */
@@ -2462,6 +2544,13 @@ static const struct mopcode32 mve_opcodes[] =
    0xee100b10, 0xff100f1f,
    "vmov%c.%u%5-6,21-22s\t%12-15r, %17-19,7Q[%N]"},
 
+  /* Vector VSHLL T1 Variant.  Note: VSHLL T1 must appear before MVE_VMOVL due
+     to instruction opcode aliasing.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHLL_T1,
+   0xeea00f40, 0xefa00fd1,
+   "vshll%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
   /* Vector VMOVL long.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VMOVL,
@@ -2612,6 +2701,54 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe010e60, 0xff811f70,
    "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
 
+  /* Vector VQRSHL T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRSHL_T1,
+   0xef000550, 0xef811f51,
+   "vqrshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"},
+
+  /* Vector VQRSHL T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRSHL_T2,
+   0xee331ee0, 0xefb31ff0,
+   "vqrshl%v.%u%18-19s\t%13-15,22Q, %0-3r"},
+
+  /* Vector VQRSHRN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRSHRN,
+   0xee800f41, 0xefa00fd1,
+   "vqrshrn%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VQRSHRUN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQRSHRUN,
+   0xfe800fc0, 0xffa00fd1,
+   "vqrshrun%T%v.s%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VQSHL T1 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHL_T1,
+   0xee311ee0, 0xefb31ff0,
+   "vqshl%v.%u%18-19s\t%13-15,22Q, %0-3r"},
+
+  /* Vector VQSHL T4 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHL_T4,
+   0xef000450, 0xef811f51,
+   "vqshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"},
+
+  /* Vector VQSHRN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHRN,
+   0xee800f40, 0xefa00fd1,
+   "vqshrn%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VQSHRUN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSHRUN,
+   0xee800fc0, 0xffa00fd1,
+   "vqshrun%T%v.s%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
@@ -2630,6 +2767,54 @@ static const struct mopcode32 mve_opcodes[] =
    0xee801f00, 0xef811f51,
    "vrmlaldavh%5Ax%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"},
 
+  /* Vector VRSHL T1 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRSHL_T1,
+   0xef000540, 0xef811f51,
+   "vrshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"},
+
+  /* Vector VRSHL T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRSHL_T2,
+   0xee331e60, 0xefb31ff0,
+   "vrshl%v.%u%18-19s\t%13-15,22Q, %0-3r"},
+
+  /* Vector VRSHRN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRSHRN,
+   0xfe800fc1, 0xffa00fd1,
+   "vrshrn%T%v.i%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
+  /* Vector VSHL T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHL_T2,
+   0xee311e60, 0xefb31ff0,
+   "vshl%v.%u%18-19s\t%13-15,22Q, %0-3r"},
+
+  /* Vector VSHL T3 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHL_T3,
+   0xef000440, 0xef811f51,
+   "vshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"},
+
+  /* Vector VSHLC.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHLC,
+   0xeea00fc0, 0xffa01ff0,
+   "vshlc%v\t%13-15,22Q, %0-3r, #%16-20d"},
+
+  /* Vector VSHLL T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHLL_T2,
+   0xee310e01, 0xefb30fd1,
+   "vshll%T%v.%u%18-19s\t%13-15,22Q, %1-3,5Q, #%18-19d"},
+
+  /* Vector VSHRN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSHRN,
+   0xee800fc1, 0xffa00fd1,
+   "vshrn%T%v.i%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -4734,6 +4919,10 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VQRSHL_T1:
+    case MVE_VQSHL_T4:
+    case MVE_VRSHL_T1:
+    case MVE_VSHL_T3:
     case MVE_VCADD_VEC:
     case MVE_VHCADD:
     case MVE_VDDUP:
@@ -4844,6 +5033,11 @@ is_mve_encoding_conflict (unsigned long given,
 	  return FALSE;
       }
 
+    case MVE_VQRSHL_T2:
+    case MVE_VQSHL_T1:
+    case MVE_VRSHL_T2:
+    case MVE_VSHL_T2:
+    case MVE_VSHLL_T2:
     case MVE_VADDV:
     case MVE_VMOVN:
     case MVE_VQMOVUN:
@@ -4876,6 +5070,32 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+
+    case MVE_VSHLL_T1:
+      if (arm_decode_field (given, 16, 18) == 0)
+	{
+	  unsigned long sz = arm_decode_field (given, 19, 20);
+
+	  if ((sz == 1) || (sz == 2))
+	    return TRUE;
+	  else
+	    return FALSE;
+	}
+      else
+	return FALSE;
+
+    case MVE_VQSHL_T2:
+    case MVE_VQSHLU_T3:
+    case MVE_VRSHR:
+    case MVE_VSHL_T1:
+    case MVE_VSHR:
+    case MVE_VSLI:
+    case MVE_VSRI:
+      if (arm_decode_field (given, 19, 21) == 0)
+	return TRUE;
+      else
+	return FALSE;
+
     default:
       return FALSE;
 
@@ -5231,6 +5451,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VSHLL_T2:
     case MVE_VMOVN:
       if (arm_decode_field (given, 18, 19) == 2)
 	{
@@ -5253,6 +5474,56 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VQSHRN:
+    case MVE_VQSHRUN:
+    case MVE_VSHLL_T1:
+    case MVE_VSHRN:
+      {
+	unsigned long sz = arm_decode_field (given, 19, 20);
+	if (sz == 1)
+	  return FALSE;
+	else if ((sz & 2) == 2)
+	  return FALSE;
+	else
+	  {
+	    *undefined_code = UNDEF_SIZE;
+	    return TRUE;
+	  }
+      }
+      break;
+
+    case MVE_VQSHL_T2:
+    case MVE_VQSHLU_T3:
+    case MVE_VRSHR:
+    case MVE_VSHL_T1:
+    case MVE_VSHR:
+    case MVE_VSLI:
+    case MVE_VSRI:
+      {
+	unsigned long sz = arm_decode_field (given, 19, 21);
+	if ((sz & 7) == 1)
+	  return FALSE;
+	else if ((sz & 6) == 2)
+	  return FALSE;
+	else if ((sz & 4) == 4)
+	  return FALSE;
+	else
+	  {
+	    *undefined_code = UNDEF_SIZE;
+	    return TRUE;
+	  }
+      }
+
+    case MVE_VQRSHRN:
+    case MVE_VQRSHRUN:
+      if (arm_decode_field (given, 19, 20) == 0)
+	{
+	  *undefined_code = UNDEF_SIZE_0;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5312,6 +5583,11 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQRSHL_T2:
+    case MVE_VQSHL_T1:
+    case MVE_VRSHL_T2:
+    case MVE_VSHL_T2:
+    case MVE_VSHLC:
     case MVE_VQDMLAH:
     case MVE_VQRDMLAH:
     case MVE_VQDMLASH:
@@ -5900,6 +6176,10 @@ print_mve_undefined (struct disassemble_info *info,
 
   switch (undefined_code)
     {
+    case UNDEF_SIZE:
+      func (stream, "illegal size");
+      break;
+
     case UNDEF_SIZE_0:
       func (stream, "size equals zero");
       break;
@@ -6406,8 +6686,17 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VQRDMULH_T2:
     case MVE_VQDMULH_T3:
     case MVE_VQRDMULH_T4:
+    case MVE_VQRSHL_T1:
+    case MVE_VQRSHL_T2:
+    case MVE_VQSHL_T1:
+    case MVE_VQSHL_T4:
     case MVE_VRHADD:
     case MVE_VRINT_FP:
+    case MVE_VRSHL_T1:
+    case MVE_VRSHL_T2:
+    case MVE_VSHL_T2:
+    case MVE_VSHL_T3:
+    case MVE_VSHLL_T2:
     case MVE_VST2:
     case MVE_VST4:
     case MVE_VSTRB_SCATTER_T1:
@@ -6566,11 +6855,95 @@ print_mve_size (struct disassemble_info *info,
 	}
       break;
 
+    case MVE_VQSHRN:
+    case MVE_VQSHRUN:
+    case MVE_VQRSHRN:
+    case MVE_VQRSHRUN:
+    case MVE_VRSHRN:
+    case MVE_VSHRN:
+      {
+	switch (size)
+	{
+	case 1:
+	  func (stream, "16");
+	  break;
+
+	case 2: case 3:
+	  func (stream, "32");
+	  break;
+
+	default:
+	  break;
+	}
+      }
+      break;
+
+    case MVE_VQSHL_T2:
+    case MVE_VQSHLU_T3:
+    case MVE_VRSHR:
+    case MVE_VSHL_T1:
+    case MVE_VSHLL_T1:
+    case MVE_VSHR:
+    case MVE_VSLI:
+    case MVE_VSRI:
+      {
+	switch (size)
+	{
+	case 1:
+	  func (stream, "8");
+	  break;
+
+	case 2: case 3:
+	  func (stream, "16");
+	  break;
+
+	case 4: case 5: case 6: case 7:
+	  func (stream, "32");
+	  break;
+
+	default:
+	  break;
+	}
+      }
+      break;
+
     default:
       break;
     }
 }
 
+static void
+print_mve_shift_n (struct disassemble_info *info, long given,
+		   enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  int startAt0
+    = matched_insn == MVE_VQSHL_T2
+      || matched_insn == MVE_VQSHLU_T3
+      || matched_insn == MVE_VSHL_T1
+      || matched_insn == MVE_VSHLL_T1
+      || matched_insn == MVE_VSLI;
+
+  unsigned imm6 = (given & 0x3f0000) >> 16;
+
+  if (matched_insn == MVE_VSHLL_T1)
+    imm6 &= 0x1f;
+
+  unsigned shiftAmount = 0;
+  if ((imm6 & 0x20) != 0)
+    shiftAmount = startAt0 ? imm6 - 32 : 64 - imm6;
+  else if ((imm6 & 0x10) != 0)
+    shiftAmount = startAt0 ? imm6 - 16 : 32 - imm6;
+  else if ((imm6 & 0x08) != 0)
+    shiftAmount = startAt0 ? imm6 - 8 : 16 - imm6;
+  else
+    print_mve_undefined (info, UNDEF_SIZE_0);
+
+  func (stream, "%u", shiftAmount);
+}
+
 static void
 print_vec_condition (struct disassemble_info *info, long given,
 		     enum mve_instructions matched_insn)
@@ -8210,8 +8583,42 @@ print_insn_mve (struct disassemble_info *info, long given)
 			    func (stream, "%s", arm_regnames[value]);
 			    break;
 			  case 'd':
-			    func (stream, "%ld", value);
-			    value_in_comment = value;
+			    if (insn->mve_op == MVE_VQSHL_T2
+				|| insn->mve_op == MVE_VQSHLU_T3
+				|| insn->mve_op == MVE_VRSHR
+				|| insn->mve_op == MVE_VRSHRN
+				|| insn->mve_op == MVE_VSHL_T1
+				|| insn->mve_op == MVE_VSHLL_T1
+				|| insn->mve_op == MVE_VSHR
+				|| insn->mve_op == MVE_VSHRN
+				|| insn->mve_op == MVE_VSLI
+				|| insn->mve_op == MVE_VSRI)
+			      print_mve_shift_n (info, given, insn->mve_op);
+			    else if (insn->mve_op == MVE_VSHLL_T2)
+			      {
+				switch (value)
+				  {
+				  case 0x00:
+				    func (stream, "8");
+				    break;
+				  case 0x01:
+				    func (stream, "16");
+				    break;
+				  case 0x10:
+				    print_mve_undefined (info, UNDEF_SIZE_0);
+				    break;
+				  default:
+				    assert (0);
+				    break;
+				  }
+			      }
+			    else
+			      {
+				if (insn->mve_op == MVE_VSHLC && value == 0)
+				  value = 32;
+				func (stream, "%ld", value);
+				value_in_comment = value;
+			      }
 			    break;
 			  case 'F':
 			    func (stream, "s%ld", value);

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 52/57][Arm][OBJDUMP] Add support for MVE instructions: vadc, vabav, vabd, vabs, vadd, vsbc and vsub
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (50 preceding siblings ...)
  2019-05-01 17:47 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
@ 2019-05-01 17:48 ` Andre Vieira (lists)
  2019-05-01 17:48 ` [PATCH 51/57][Arm][OBJDUMP] Add support for MVE instructions: lctp, letp, wlstp and dlstp Andre Vieira (lists)
                   ` (8 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:48 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 516 bytes --]

Hello,

This patch adds support for MVE instructions: VADC, VABAV, VABD, VABS, 
VADD, VSBC, and VSUB.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
         (enum mve_instructions): Likewise.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.
	(print_insn_mve): Likewise.

[-- Attachment #2: 52.patch --]
[-- Type: text/x-patch, Size: 7464 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index a2051a9b738237b80cc9044f883ed6a77b734807..4222bdda0400826de86f32167b91c6fe8dd17427 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -208,6 +208,21 @@ enum mve_instructions
   MVE_VSHRN,
   MVE_VSLI,
   MVE_VSRI,
+  MVE_VADC,
+  MVE_VABAV,
+  MVE_VABD_FP,
+  MVE_VABD_VEC,
+  MVE_VABS_FP,
+  MVE_VABS_VEC,
+  MVE_VADD_FP_T1,
+  MVE_VADD_FP_T2,
+  MVE_VADD_VEC_T1,
+  MVE_VADD_VEC_T2,
+  MVE_VSBC,
+  MVE_VSUB_FP_T1,
+  MVE_VSUB_FP_T2,
+  MVE_VSUB_VEC_T1,
+  MVE_VSUB_VEC_T2,
   MVE_NONE
 };
 
@@ -1990,6 +2005,7 @@ static const struct opcode32 neon_opcodes[] =
    %<bitfield>Z		as %<>r but r15 is ZR instead of PC and r13 is
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
+   %<bitfield>I		print carry flag or not
    %<bitfield>i		print immediate for vstr/vldr reg +/- imm
    %<bitfield>h		print high half of 64-bit destination reg
    %<bitfield>k		print immediate for vector conversion instruction
@@ -2063,6 +2079,56 @@ static const struct mopcode32 mve_opcodes[] =
    0xef100150, 0xffb11f51,
    "vbic%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VABAV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VABAV,
+   0xee800f01, 0xefc10f51,
+   "vabav%v.%u%20-21s\t%12-15r, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VABD floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VABD_FP,
+   0xff200d40, 0xffa11f51,
+   "vabd%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VABD.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VABD_VEC,
+   0xef000740, 0xef811f51,
+   "vabd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VABS floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VABS_FP,
+   0xFFB10740, 0xFFB31FD1,
+   "vabs%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
+  /* Vector VABS.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VABS_VEC,
+   0xffb10340, 0xffb31fd1,
+   "vabs%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VADD floating point T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VADD_FP_T1,
+   0xef000d40, 0xffa11f51,
+   "vadd%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+  /* Vector VADD floating point T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VADD_FP_T2,
+   0xee300f40, 0xefb11f70,
+   "vadd%v.f%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+  /* Vector VADD T1.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADD_VEC_T1,
+   0xef000840, 0xff811f51,
+   "vadd%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+  /* Vector VADD T2.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADD_VEC_T2,
+   0xee010f40, 0xff811f70,
+   "vadd%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VADDLV.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VADDLV,
@@ -2075,6 +2141,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xeef10f00, 0xeff31fd1,
    "vaddv%5A%v.%u%18-19s\t%13-15l, %1-3Q"},
 
+  /* Vector VADC.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VADC,
+   0xee300f00, 0xffb10f51,
+   "vadc%12I%v.i32\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VCADD floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCADD_FP,
@@ -2785,6 +2857,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe800fc1, 0xffa00fd1,
    "vrshrn%T%v.i%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
 
+  /* Vector VSBC.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSBC,
+   0xfe300f00, 0xffb10f51,
+   "vsbc%12I%v.i32\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VSHL T2 Variant.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VSHL_T2,
@@ -2905,6 +2983,30 @@ static const struct mopcode32 mve_opcodes[] =
    0xec001f00, 0xfe101f80,
    "vstrw%v.32\t%13-15,22Q, %d"},
 
+  /* Vector VSUB floating point T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VSUB_FP_T1,
+   0xef200d40, 0xffa11f51,
+   "vsub%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VSUB floating point T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VSUB_FP_T2,
+   0xee301f40, 0xefb11f70,
+   "vsub%v.f%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VSUB T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSUB_VEC_T1,
+   0xff000840, 0xff811f51,
+   "vsub%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VSUB T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VSUB_VEC_T2,
+   0xee011f40, 0xff811f70,
+   "vsub%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   {ARM_FEATURE_CORE_LOW (0),
    MVE_NONE,
    0x00000000, 0x00000000, 0}
@@ -4927,6 +5029,9 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VADD_VEC_T2:
+    case MVE_VSUB_VEC_T2:
+    case MVE_VABAV:
     case MVE_VQRSHL_T1:
     case MVE_VQSHL_T4:
     case MVE_VRSHL_T1:
@@ -5102,6 +5207,9 @@ is_mve_encoding_conflict (unsigned long given,
 	return FALSE;
 
     default:
+    case MVE_VADD_FP_T1:
+    case MVE_VADD_FP_T2:
+    case MVE_VADD_VEC_T1:
       return FALSE;
 
     }
@@ -5202,6 +5310,9 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VABD_VEC:
+    case MVE_VADD_VEC_T1:
+    case MVE_VSUB_VEC_T1:
     case MVE_VQDMULH_T1:
     case MVE_VQRDMULH_T2:
     case MVE_VRHADD:
@@ -5377,6 +5488,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VABS_FP:
     case MVE_VCVT_BETWEEN_FP_INT:
     case MVE_VCVT_FROM_FP_TO_INT:
       {
@@ -5529,6 +5641,15 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VABS_VEC:
+	if (arm_decode_field (given, 18, 19) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+	else
+	  return FALSE;
+
     default:
       return FALSE;
     }
@@ -5588,6 +5709,10 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VADD_FP_T2:
+    case MVE_VSUB_FP_T2:
+    case MVE_VADD_VEC_T2:
+    case MVE_VSUB_VEC_T2:
     case MVE_VQRSHL_T2:
     case MVE_VQSHL_T1:
     case MVE_VRSHL_T2:
@@ -5793,6 +5918,7 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VABAV:
     case MVE_VMOV_HFP_TO_GP:
     case MVE_VMOV_GP_TO_VEC_LANE:
     case MVE_VMOV_VEC_LANE_TO_GP:
@@ -6647,6 +6773,12 @@ print_mve_size (struct disassemble_info *info,
 
   switch (matched_insn)
     {
+    case MVE_VABAV:
+    case MVE_VABD_VEC:
+    case MVE_VABS_FP:
+    case MVE_VABS_VEC:
+    case MVE_VADD_VEC_T1:
+    case MVE_VADD_VEC_T2:
     case MVE_VADDV:
     case MVE_VCADD_VEC:
     case MVE_VCMP_VEC_T1:
@@ -6709,12 +6841,19 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VSTRW_SCATTER_T3:
     case MVE_VSTRB_T1:
     case MVE_VSTRH_T2:
+    case MVE_VSUB_VEC_T1:
+    case MVE_VSUB_VEC_T2:
       if (size <= 3)
 	func (stream, "%s", mve_vec_sizename[size]);
       else
 	func (stream, "<undef size>");
       break;
 
+    case MVE_VABD_FP:
+    case MVE_VADD_FP_T1:
+    case MVE_VADD_FP_T2:
+    case MVE_VSUB_FP_T1:
+    case MVE_VSUB_FP_T2:
     case MVE_VCMP_FP_T1:
     case MVE_VCMP_FP_T2:
     case MVE_VFMA_FP_SCALAR:
@@ -8519,6 +8658,10 @@ print_insn_mve (struct disassemble_info *info, long given)
 					    value,
 					    insn->mve_op);
 			    break;
+			  case 'I':
+			    if (value == 1)
+			      func (stream, "i");
+			    break;
 			  case 'A':
 			    if (value == 1)
 			      func (stream, "a");

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 51/57][Arm][OBJDUMP] Add support for MVE instructions: lctp, letp, wlstp and dlstp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (51 preceding siblings ...)
  2019-05-01 17:48 ` [PATCH 52/57][Arm][OBJDUMP] Add support for MVE instructions: vadc, vabav, vabd, vabs, vadd, vsbc and vsub Andre Vieira (lists)
@ 2019-05-01 17:48 ` Andre Vieira (lists)
  2019-05-01 17:49 ` [PATCH 53/57][Arm][OBJDUMP] Add support for MVE instructions: vand, vbrsr, vcls, vclz and vctp Andre Vieira (lists)
                   ` (7 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:48 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 367 bytes --]

Hello,

This patch adds support for MVE low-overhead loop tail predicated 
instructions: LCTP, LETP, WLSTP, and DLSTP.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
         (print_insn_thumb32): Handle new instructions.

[-- Attachment #2: 51.patch --]
[-- Type: text/x-patch, Size: 1769 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 6564e41f8d479f5146c040830056cf21e1b0d1db..a2051a9b738237b80cc9044f883ed6a77b734807 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -3949,13 +3949,21 @@ static const struct opcode32 thumb32_opcodes[] =
   /* Armv8.1-M Mainline and Armv8.1-M Mainline Security Extensions
      instructions.  */
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
-    0xf040c001, 0xfff0f001, "wls\tlr, %16-19S, %Q"},
-  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
-    0xf040e001, 0xfff0ffff, "dls\tlr, %16-19S"},
+    0xf00fe001, 0xffffffff, "lctp%c"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf02fc001, 0xfffff001, "le\t%P"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf00fc001, 0xfffff001, "le\tlr, %P"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf01fc001, 0xfffff001, "letp\tlr, %P"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf040c001, 0xfff0f001, "wls\tlr, %16-19S, %Q"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf000c001, 0xffc0f001, "wlstp.%20-21s\tlr, %16-19S, %Q"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf040e001, 0xfff0ffff, "dls\tlr, %16-19S"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf000e001, 0xffc0ffff, "dlstp.%20-21s\tlr, %16-19S"},
 
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf040e001, 0xf860f001, "bf%c\t%G, %W"},
@@ -10171,6 +10179,13 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 
 		  switch (*c)
 		    {
+		    case 's':
+		      if (val <= 3)
+			func (stream, "%s", mve_vec_sizename[val]);
+		      else
+			func (stream, "<undef size>");
+		      break;
+
 		    case 'd':
 		      func (stream, "%lu", val);
 		      value_in_comment = val;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 53/57][Arm][OBJDUMP] Add support for MVE instructions: vand, vbrsr, vcls, vclz and vctp
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (52 preceding siblings ...)
  2019-05-01 17:48 ` [PATCH 51/57][Arm][OBJDUMP] Add support for MVE instructions: lctp, letp, wlstp and dlstp Andre Vieira (lists)
@ 2019-05-01 17:49 ` Andre Vieira (lists)
  2019-05-01 17:50 ` [PATCH 55/57][Arm][OBJDUMP] Add support for MVE instructions: vmul, vmulh, vrmulh and vneg Andre Vieira (lists)
                   ` (6 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:49 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

Hello,

This patch adds support for MVE instructions: VAND, VBRSR, VCLS, VCLZ, 
and VCTP.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
	(enum mve_instructions): Likewise.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.

[-- Attachment #2: 53.patch --]
[-- Type: text/x-patch, Size: 3707 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 4222bdda0400826de86f32167b91c6fe8dd17427..8f2e541b1c1ad4f7d1ef1c3c8f4edddba551d00e 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -223,6 +223,11 @@ enum mve_instructions
   MVE_VSUB_FP_T2,
   MVE_VSUB_VEC_T1,
   MVE_VSUB_VEC_T2,
+  MVE_VAND,
+  MVE_VBRSR,
+  MVE_VCLS,
+  MVE_VCLZ,
+  MVE_VCTP,
   MVE_NONE
 };
 
@@ -2147,6 +2152,18 @@ static const struct mopcode32 mve_opcodes[] =
    0xee300f00, 0xffb10f51,
    "vadc%12I%v.i32\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VAND.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VAND,
+   0xef000150, 0xffb11f51,
+   "vand%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VBRSR register.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VBRSR,
+   0xfe011e60, 0xff811f70,
+   "vbrsr%v.%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VCADD floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCADD_FP,
@@ -2159,6 +2176,18 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe000f00, 0xff810f51,
    "vcadd%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%12o"},
 
+  /* Vector VCLS.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCLS,
+   0xffb00440, 0xffb31fd1,
+   "vcls%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCLZ.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCLZ,
+   0xffb004c0, 0xffb31fd1,
+   "vclz%v.i%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VCMLA.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VCMLA_FP,
@@ -2274,6 +2303,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xee300e00, 0xefb10f50,
    "vcmul%v.f%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q, #%0,12o"},
 
+   /* Vector VCTP.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VCTP,
+   0xf000e801, 0xffc0ffff,
+   "vctp%v.%20-21s\t%16-19r"},
+
   /* Vector VDUP.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VDUP,
@@ -5029,6 +5064,7 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VBRSR:
     case MVE_VADD_VEC_T2:
     case MVE_VSUB_VEC_T2:
     case MVE_VABAV:
@@ -5206,6 +5242,12 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VCTP:
+    if (arm_decode_field (given, 16, 19) == 0xf)
+      return TRUE;
+    else
+      return FALSE;
+
     default:
     case MVE_VADD_FP_T1:
     case MVE_VADD_FP_T2:
@@ -5650,6 +5692,16 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	else
 	  return FALSE;
 
+    case MVE_VCLS:
+    case MVE_VCLZ:
+      if (arm_decode_field (given, 18, 19) == 3)
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -5709,6 +5761,7 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VBRSR:
     case MVE_VADD_FP_T2:
     case MVE_VSUB_FP_T2:
     case MVE_VADD_VEC_T2:
@@ -6097,6 +6150,15 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 
       }
 
+    case MVE_VCTP:
+      if (arm_decode_field (given, 16, 19) == 0xd)
+	{
+	  *unpredictable_code = UNPRED_R13;
+	  return TRUE;
+	}
+      else
+	return FALSE;
+
     default:
       return FALSE;
     }
@@ -6780,13 +6842,17 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VADD_VEC_T1:
     case MVE_VADD_VEC_T2:
     case MVE_VADDV:
+    case MVE_VBRSR:
     case MVE_VCADD_VEC:
+    case MVE_VCLS:
+    case MVE_VCLZ:
     case MVE_VCMP_VEC_T1:
     case MVE_VCMP_VEC_T2:
     case MVE_VCMP_VEC_T3:
     case MVE_VCMP_VEC_T4:
     case MVE_VCMP_VEC_T5:
     case MVE_VCMP_VEC_T6:
+    case MVE_VCTP:
     case MVE_VDDUP:
     case MVE_VDWDUP:
     case MVE_VHADD_T1:

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 54/57][Arm][OBJDUMP] Add support for MVE instructions: vmax(a), vmax(a)v, vmaxnm(a), vmaxnm(a)v, vmin(a), vmin(a)v, vminnm(a), vminnm(a)v and vmla
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (54 preceding siblings ...)
  2019-05-01 17:50 ` [PATCH 55/57][Arm][OBJDUMP] Add support for MVE instructions: vmul, vmulh, vrmulh and vneg Andre Vieira (lists)
@ 2019-05-01 17:50 ` Andre Vieira (lists)
  2019-05-01 17:51 ` [PATCH 56/57][Arm][OBJDUMP] Add support for MVE instructions: vpnot, vpsel, vqabs, vqadd, vqsub, vqneg and vrev Andre Vieira (lists)
                   ` (4 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:50 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 488 bytes --]

Hello,

This patch adds support for MVE instructions: VMAX(A), VMAX(A)V, 
VMAXNM(A), VMAXNM(A)V, VMIN(A), VMIN(A)V, VMINNM(A), VMINNM(A)V, and VMLA.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
         (enum mve_instructions): Likewise.
	(is_mve_encoding_conflict): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.

[-- Attachment #2: 54.patch --]
[-- Type: text/x-patch, Size: 5599 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 8f2e541b1c1ad4f7d1ef1c3c8f4edddba551d00e..441dd5e1af98e0f55ae632e118cee1b28d3504bd 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -228,6 +228,23 @@ enum mve_instructions
   MVE_VCLS,
   MVE_VCLZ,
   MVE_VCTP,
+  MVE_VMAX,
+  MVE_VMAXA,
+  MVE_VMAXNM_FP,
+  MVE_VMAXNMA_FP,
+  MVE_VMAXNMV_FP,
+  MVE_VMAXNMAV_FP,
+  MVE_VMAXV,
+  MVE_VMAXAV,
+  MVE_VMIN,
+  MVE_VMINA,
+  MVE_VMINNM_FP,
+  MVE_VMINNMA_FP,
+  MVE_VMINNMV_FP,
+  MVE_VMINNMAV_FP,
+  MVE_VMINV,
+  MVE_VMINAV,
+  MVE_VMLA,
   MVE_NONE
 };
 
@@ -2459,6 +2476,108 @@ static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VMAX.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMAX,
+   0xef000640, 0xef811f51,
+   "vmax%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMAXA.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMAXA,
+   0xee330e81, 0xffb31fd1,
+   "vmaxa%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VMAXNM floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMAXNM_FP,
+   0xff000f50, 0xffa11f51,
+   "vmaxnm%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMAXNMA floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMAXNMA_FP,
+   0xee3f0e81, 0xefbf1fd1,
+   "vmaxnma%v.f%28s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VMAXNMV floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMAXNMV_FP,
+   0xeeee0f00, 0xefff0fd1,
+   "vmaxnmv%v.f%28s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMAXNMAV floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMAXNMAV_FP,
+   0xeeec0f00, 0xefff0fd1,
+   "vmaxnmav%v.f%28s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMAXV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMAXV,
+   0xeee20f00, 0xeff30fd1,
+   "vmaxv%v.%u%18-19s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMAXAV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMAXAV,
+   0xeee00f00, 0xfff30fd1,
+   "vmaxav%v.s%18-19s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMIN.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMIN,
+   0xef000650, 0xef811f51,
+   "vmin%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMINA.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMINA,
+   0xee331e81, 0xffb31fd1,
+   "vmina%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VMINNM floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMINNM_FP,
+   0xff200f50, 0xffa11f51,
+   "vminnm%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMINNMA floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMINNMA_FP,
+   0xee3f1e81, 0xefbf1fd1,
+   "vminnma%v.f%28s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VMINNMV floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMINNMV_FP,
+   0xeeee0f80, 0xefff0fd1,
+   "vminnmv%v.f%28s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMINNMAV floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMINNMAV_FP,
+   0xeeec0f80, 0xefff0fd1,
+   "vminnmav%v.f%28s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMINV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMINV,
+   0xeee20f80, 0xeff30fd1,
+   "vminv%v.%u%18-19s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMINAV.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMINAV,
+   0xeee00f80, 0xfff30fd1,
+   "vminav%v.s%18-19s\t%12-15r, %1-3,5Q"},
+
+  /* Vector VMLA.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMLA,
+   0xee010e40, 0xef811f70,
+   "vmla%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VMLALDAV.  Note must appear before VMLADAV due to instruction
      opcode aliasing.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
@@ -5064,6 +5183,9 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMLA:
+    case MVE_VMAX:
+    case MVE_VMIN:
     case MVE_VBRSR:
     case MVE_VADD_VEC_T2:
     case MVE_VSUB_VEC_T2:
@@ -5179,6 +5301,12 @@ is_mve_encoding_conflict (unsigned long given,
 	  return FALSE;
       }
 
+    case MVE_VMAXA:
+    case MVE_VMINA:
+    case MVE_VMAXV:
+    case MVE_VMAXAV:
+    case MVE_VMINV:
+    case MVE_VMINAV:
     case MVE_VQRSHL_T2:
     case MVE_VQSHL_T1:
     case MVE_VRSHL_T2:
@@ -5761,6 +5889,7 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMLA:
     case MVE_VBRSR:
     case MVE_VADD_FP_T2:
     case MVE_VSUB_FP_T2:
@@ -5971,6 +6100,14 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMAXV:
+    case MVE_VMAXAV:
+    case MVE_VMAXNMV_FP:
+    case MVE_VMAXNMAV_FP:
+    case MVE_VMINNMV_FP:
+    case MVE_VMINNMAV_FP:
+    case MVE_VMINV:
+    case MVE_VMINAV:
     case MVE_VABAV:
     case MVE_VMOV_HFP_TO_GP:
     case MVE_VMOV_GP_TO_VEC_LANE:
@@ -6870,6 +7007,15 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VLDRD_GATHER_T4:
     case MVE_VLDRB_T1:
     case MVE_VLDRH_T2:
+    case MVE_VMAX:
+    case MVE_VMAXA:
+    case MVE_VMAXV:
+    case MVE_VMAXAV:
+    case MVE_VMIN:
+    case MVE_VMINA:
+    case MVE_VMINV:
+    case MVE_VMINAV:
+    case MVE_VMLA:
     case MVE_VMLAS:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
@@ -6926,6 +7072,14 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VFMA_FP:
     case MVE_VFMS_FP:
     case MVE_VFMAS_FP_SCALAR:
+    case MVE_VMAXNM_FP:
+    case MVE_VMAXNMA_FP:
+    case MVE_VMAXNMV_FP:
+    case MVE_VMAXNMAV_FP:
+    case MVE_VMINNM_FP:
+    case MVE_VMINNMA_FP:
+    case MVE_VMINNMV_FP:
+    case MVE_VMINNMAV_FP:
     case MVE_VPT_FP_T1:
     case MVE_VPT_FP_T2:
       if (size == 0)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 55/57][Arm][OBJDUMP] Add support for MVE instructions: vmul, vmulh, vrmulh and vneg
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (53 preceding siblings ...)
  2019-05-01 17:49 ` [PATCH 53/57][Arm][OBJDUMP] Add support for MVE instructions: vand, vbrsr, vcls, vclz and vctp Andre Vieira (lists)
@ 2019-05-01 17:50 ` Andre Vieira (lists)
  2019-05-01 17:50 ` [PATCH 54/57][Arm][OBJDUMP] Add support for MVE instructions: vmax(a), vmax(a)v, vmaxnm(a), vmaxnm(a)v, vmin(a), vmin(a)v, vminnm(a), vminnm(a)v and vmla Andre Vieira (lists)
                   ` (5 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:50 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 470 bytes --]

Hello,

This patch adds support for MVE instructions: VMUL, VMULH, VRMULH, and VNEG.

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
         (enum mve_instructions): Likewise.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_size): Likewise.

[-- Attachment #2: 55.patch --]
[-- Type: text/x-patch, Size: 4095 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 441dd5e1af98e0f55ae632e118cee1b28d3504bd..38e2e1036218cadf383c016492936195fb924170 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -245,6 +245,14 @@ enum mve_instructions
   MVE_VMINV,
   MVE_VMINAV,
   MVE_VMLA,
+  MVE_VMUL_FP_T1,
+  MVE_VMUL_FP_T2,
+  MVE_VMUL_VEC_T1,
+  MVE_VMUL_VEC_T2,
+  MVE_VMULH,
+  MVE_VRMULH,
+  MVE_VNEG_FP,
+  MVE_VNEG_VEC,
   MVE_NONE
 };
 
@@ -2795,6 +2803,42 @@ static const struct mopcode32 mve_opcodes[] =
    0xfeb00a40, 0xffbf0fd0,
    "vmovx.f16\t%22,12-15F, %5,0-3F"},
 
+  /* Vector VMUL floating-point T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMUL_FP_T1,
+   0xff000d50, 0xffa11f51,
+   "vmul%v.f%20s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMUL floating-point T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VMUL_FP_T2,
+   0xee310e60, 0xefb11f70,
+   "vmul%v.f%28s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VMUL T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMUL_VEC_T1,
+   0xef000950, 0xff811f51,
+   "vmul%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VMUL T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMUL_VEC_T2,
+   0xee011e60, 0xff811f70,
+   "vmul%v.i%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VMULH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VMULH,
+   0xee010e01, 0xef811f51,
+   "vmulh%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VRMULH.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VRMULH,
+   0xee011e01, 0xef811f51,
+   "vrmulh%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
   /* Vector VMULL integer.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VMULL_INT,
@@ -2819,6 +2863,18 @@ static const struct mopcode32 mve_opcodes[] =
    0xffb005c0, 0xffbf1fd1,
    "vmvn%v\t%13-15,22Q, %1-3,5Q"},
 
+  /* Vector VNEG floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VNEG_FP,
+   0xffb107c0, 0xffb31fd1,
+   "vneg%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VNEG.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VNEG_VEC,
+   0xffb103c0, 0xffb31fd1,
+   "vneg%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VORN, vector bitwise or not.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VORN,
@@ -5183,6 +5239,9 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VMUL_VEC_T2:
+    case MVE_VMULH:
+    case MVE_VRMULH:
     case MVE_VMLA:
     case MVE_VMAX:
     case MVE_VMIN:
@@ -5480,6 +5539,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VMUL_VEC_T1:
     case MVE_VABD_VEC:
     case MVE_VADD_VEC_T1:
     case MVE_VSUB_VEC_T1:
@@ -5658,6 +5718,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VNEG_FP:
     case MVE_VABS_FP:
     case MVE_VCVT_BETWEEN_FP_INT:
     case MVE_VCVT_FROM_FP_TO_INT:
@@ -5820,6 +5881,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	else
 	  return FALSE;
 
+    case MVE_VNEG_VEC:
     case MVE_VCLS:
     case MVE_VCLZ:
       if (arm_decode_field (given, 18, 19) == 3)
@@ -5889,6 +5951,8 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VMUL_FP_T2:
+    case MVE_VMUL_VEC_T2:
     case MVE_VMLA:
     case MVE_VBRSR:
     case MVE_VADD_FP_T2:
@@ -7017,6 +7081,13 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VMINAV:
     case MVE_VMLA:
     case MVE_VMLAS:
+    case MVE_VMUL_VEC_T1:
+    case MVE_VMUL_VEC_T2:
+    case MVE_VMULH:
+    case MVE_VRMULH:
+    case MVE_VMULL_INT:
+    case MVE_VNEG_FP:
+    case MVE_VNEG_VEC:
     case MVE_VPT_VEC_T1:
     case MVE_VPT_VEC_T2:
     case MVE_VPT_VEC_T3:
@@ -7080,6 +7151,8 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VMINNMA_FP:
     case MVE_VMINNMV_FP:
     case MVE_VMINNMAV_FP:
+    case MVE_VMUL_FP_T1:
+    case MVE_VMUL_FP_T2:
     case MVE_VPT_FP_T1:
     case MVE_VPT_FP_T2:
       if (size == 0)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 56/57][Arm][OBJDUMP] Add support for MVE instructions: vpnot, vpsel, vqabs, vqadd, vqsub, vqneg and vrev
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (55 preceding siblings ...)
  2019-05-01 17:50 ` [PATCH 54/57][Arm][OBJDUMP] Add support for MVE instructions: vmax(a), vmax(a)v, vmaxnm(a), vmaxnm(a)v, vmin(a), vmin(a)v, vminnm(a), vminnm(a)v and vmla Andre Vieira (lists)
@ 2019-05-01 17:51 ` Andre Vieira (lists)
  2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
                   ` (3 subsequent siblings)
  60 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 17:51 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 565 bytes --]

Hello,

This patch adds support for MVE instructions: VPNOT, VPSEL, VQABS, 
VQADD, VQSUB, VQNEG, and VREV

opcodes/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
             Michael Collison <michael.collison@arm.com>

	* arm-dis.c (thumb32_opcodes): Add new instructions.
         (enum mve_instructions): Likewise.
	(enum mve_undefined): Add new reasons.
	(is_mve_encoding_conflict): Handle new instructions.
	(is_mve_undefined): Likewise.
	(is_mve_unpredictable): Likewise.
	(print_mve_undefined): Likewise.
	(print_mve_size): Likewise.

[-- Attachment #2: 56.patch --]
[-- Type: text/x-patch, Size: 6546 bytes --]

diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 38e2e1036218cadf383c016492936195fb924170..b94ec9b3dde291665b908212e06cae2ba1597102 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -253,6 +253,17 @@ enum mve_instructions
   MVE_VRMULH,
   MVE_VNEG_FP,
   MVE_VNEG_VEC,
+  MVE_VPNOT,
+  MVE_VPSEL,
+  MVE_VQABS,
+  MVE_VQADD_T1,
+  MVE_VQADD_T2,
+  MVE_VQSUB_T1,
+  MVE_VQSUB_T2,
+  MVE_VQNEG,
+  MVE_VREV16,
+  MVE_VREV32,
+  MVE_VREV64,
   MVE_NONE
 };
 
@@ -290,6 +301,7 @@ enum mve_undefined
   UNDEF_SIZE_2,			/* undefined because size == 2.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
+  UNDEF_SIZE_NOT_0,		/* undefined because size != 0.  */
   UNDEF_SIZE_NOT_2,		/* undefined because size != 2.  */
   UNDEF_SIZE_NOT_3,		/* undefined because size != 3.  */
   UNDEF_NOT_UNS_SIZE_0,		/* undefined because U == 0 and
@@ -2893,6 +2905,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xee300f01, 0xefb10f51,
    "vqdmull%T%v.s%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VPNOT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPNOT,
+   0xfe310f4d, 0xffffffff,
+   "vpnot%v"},
+
+  /* Vector VPSEL.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VPSEL,
+   0xfe310f01, 0xffb11f51,
+   "vpsel%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQABS.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQABS,
+   0xffb00740, 0xffb31fd1,
+   "vqabs%v.s%18-19s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQADD T1 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQADD_T1,
+   0xef000050, 0xef811f51,
+   "vqadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQADD T2 variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQADD_T2,
+   0xee000f60, 0xef811f70,
+   "vqadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
   /* Vector VQDMULL T2 variant.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VQDMULL_T2,
@@ -2983,6 +3025,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xfe010e60, 0xff811f70,
    "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
 
+  /* Vector VQNEG.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQNEG,
+   0xffb007c0, 0xffb31fd1,
+   "vqneg%v.s%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VQRSHL T1 variant.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VQRSHL_T1,
@@ -3031,6 +3079,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xee800fc0, 0xffa00fd1,
    "vqshrun%T%v.s%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"},
 
+  /* Vector VQSUB T1 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSUB_T1,
+   0xef000250, 0xef811f51,
+   "vqsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
+
+  /* Vector VQSUB T2 Variant.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VQSUB_T2,
+   0xee001f60, 0xef811f70,
+   "vqsub%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"},
+
+  /* Vector VREV16.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VREV16,
+   0xffb00140, 0xffb31fd1,
+   "vrev16%v.8\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VREV32.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VREV32,
+   0xffb000c0, 0xffb31fd1,
+   "vrev32%v.%18-19s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VREV64.  */
+  {ARM_FEATURE_COPROC (FPU_MVE),
+   MVE_VREV64,
+   0xffb00040, 0xffb31fd1,
+   "vrev64%v.%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VRINT floating point.  */
   {ARM_FEATURE_COPROC (FPU_MVE_FP),
    MVE_VRINT_FP,
@@ -5239,6 +5317,8 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VQADD_T2:
+    case MVE_VQSUB_T2:
     case MVE_VMUL_VEC_T2:
     case MVE_VMULH:
     case MVE_VRMULH:
@@ -5539,6 +5619,8 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VQADD_T1:
+    case MVE_VQSUB_T1:
     case MVE_VMUL_VEC_T1:
     case MVE_VABD_VEC:
     case MVE_VADD_VEC_T1:
@@ -5881,6 +5963,8 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
 	else
 	  return FALSE;
 
+    case MVE_VQNEG:
+    case MVE_VQABS:
     case MVE_VNEG_VEC:
     case MVE_VCLS:
     case MVE_VCLZ:
@@ -5892,6 +5976,36 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VREV16:
+      if (arm_decode_field (given, 18, 19) == 0)
+	return FALSE;
+      else
+	{
+	  *undefined_code = UNDEF_SIZE_NOT_0;
+	  return TRUE;
+	}
+
+    case MVE_VREV32:
+      {
+	unsigned long size = arm_decode_field (given, 18, 19);
+	if ((size & 2) == 2)
+	  {
+	    *undefined_code = UNDEF_SIZE_2;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
+    case MVE_VREV64:
+      if (arm_decode_field (given, 18, 19) != 3)
+	return FALSE;
+      else
+	{
+	  *undefined_code = UNDEF_SIZE_3;
+	  return TRUE;
+	}
+
     default:
       return FALSE;
     }
@@ -5951,6 +6065,8 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
 	return FALSE;
       }
 
+    case MVE_VQADD_T2:
+    case MVE_VQSUB_T2:
     case MVE_VMUL_FP_T2:
     case MVE_VMUL_VEC_T2:
     case MVE_VMLA:
@@ -6360,6 +6476,20 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VREV64:
+      {
+	unsigned long qd = arm_decode_field_multiple (given, 13, 15, 22, 22);
+	unsigned long qm = arm_decode_field_multiple (given, 1, 3, 6, 6);
+
+	if (qd == qm)
+	  {
+	    *unpredictable_code = UNPRED_Q_REGS_EQUAL;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -6590,6 +6720,10 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "size <= 1");
       break;
 
+    case UNDEF_SIZE_NOT_0:
+      func (stream, "size not equal to 0");
+      break;
+
     case UNDEF_SIZE_NOT_2:
       func (stream, "size not equal to 2");
       break;
@@ -7094,6 +7228,9 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VPT_VEC_T4:
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
+    case MVE_VQABS:
+    case MVE_VQADD_T1:
+    case MVE_VQADD_T2:
     case MVE_VQDMLADH:
     case MVE_VQRDMLADH:
     case MVE_VQDMLAH:
@@ -7106,10 +7243,15 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VQRDMULH_T2:
     case MVE_VQDMULH_T3:
     case MVE_VQRDMULH_T4:
+    case MVE_VQNEG:
     case MVE_VQRSHL_T1:
     case MVE_VQRSHL_T2:
     case MVE_VQSHL_T1:
     case MVE_VQSHL_T4:
+    case MVE_VQSUB_T1:
+    case MVE_VQSUB_T2:
+    case MVE_VREV32:
+    case MVE_VREV64:
     case MVE_VRHADD:
     case MVE_VRINT_FP:
     case MVE_VRSHL_T1:

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 57/57][Arm][GAS] MVE Tests
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (56 preceding siblings ...)
  2019-05-01 17:51 ` [PATCH 56/57][Arm][OBJDUMP] Add support for MVE instructions: vpnot, vpsel, vqabs, vqadd, vqsub, vqneg and vrev Andre Vieira (lists)
@ 2019-05-01 18:23 ` Andre Vieira (lists)
  2019-05-01 18:24   ` Andre Vieira (lists)
                     ` (2 more replies)
  2019-05-02 10:03 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton
                   ` (2 subsequent siblings)
  60 siblings, 3 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 18:23 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 8677 bytes --]

Hi,

This patch (see attachment) adds all MVE GAS positive tests.


gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * testsuite/gas/arm/mve-tailpredloop.d: New test.
         * testsuite/gas/arm/mve-tailpredloop.s: New test.
         * testsuite/gas/arm/mve-vabav.d: New test.
         * testsuite/gas/arm/mve-vabav.s: New test.
         * testsuite/gas/arm/mve-vabd.d: New test.
         * testsuite/gas/arm/mve-vabd.s: New test.
         * testsuite/gas/arm/mve-vabsneg.d: New test.
         * testsuite/gas/arm/mve-vabsneg.s: New test.
         * testsuite/gas/arm/mve-vadc.d: New test.
         * testsuite/gas/arm/mve-vadc.s: New test.
         * testsuite/gas/arm/mve-vaddlv.d: New test.
         * testsuite/gas/arm/mve-vaddlv.s: New test.
         * testsuite/gas/arm/mve-vaddsub.d: New test.
         * testsuite/gas/arm/mve-vaddsub.s: New test.
         * testsuite/gas/arm/mve-vaddv.d: New test.
         * testsuite/gas/arm/mve-vaddv.s: New test.
         * testsuite/gas/arm/mve-vand.d: New test.
         * testsuite/gas/arm/mve-vand.s: New test.
         * testsuite/gas/arm/mve-vbic.d: New test.
         * testsuite/gas/arm/mve-vbic.s: New test.
         * testsuite/gas/arm/mve-vbrsr.d: New test.
         * testsuite/gas/arm/mve-vbrsr.s: New test.
         * testsuite/gas/arm/mve-vcadd.d: New test.
         * testsuite/gas/arm/mve-vcadd.s: New test.
         * testsuite/gas/arm/mve-vcls.d: New test.
         * testsuite/gas/arm/mve-vcls.s: New test.
         * testsuite/gas/arm/mve-vclz.d: New test.
         * testsuite/gas/arm/mve-vclz.s: New test.
         * testsuite/gas/arm/mve-vcmla.d: New test.
         * testsuite/gas/arm/mve-vcmla.s: New test.
         * testsuite/gas/arm/mve-vcmp.d: New test.
         * testsuite/gas/arm/mve-vcmp.s: New test.
         * testsuite/gas/arm/mve-vcmul.d: New test.
         * testsuite/gas/arm/mve-vcmul.s: New test.
         * testsuite/gas/arm/mve-vcvt-1.d: New test.
         * testsuite/gas/arm/mve-vcvt-1.s: New test.
         * testsuite/gas/arm/mve-vcvt-2.d: New test.
         * testsuite/gas/arm/mve-vcvt-2.s: New test.
         * testsuite/gas/arm/mve-vcvt-3.d: New test.
         * testsuite/gas/arm/mve-vcvt-3.s: New test.
         * testsuite/gas/arm/mve-vcvt-4.d: New test.
         * testsuite/gas/arm/mve-vcvt-4.s: New test.
         * testsuite/gas/arm/mve-vddup.d: New test.
         * testsuite/gas/arm/mve-vddup.s: New test.
         * testsuite/gas/arm/mve-vdup.d: New test.
         * testsuite/gas/arm/mve-vdup.s: New test.
         * testsuite/gas/arm/mve-veor.d: New test.
         * testsuite/gas/arm/mve-veor.s: New test.
         * testsuite/gas/arm/mve-vfma-vfms.d: New test.
         * testsuite/gas/arm/mve-vfma-vfms.s: New test.
         * testsuite/gas/arm/mve-vfmas.d: New test.
         * testsuite/gas/arm/mve-vfmas.s: New test.
         * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.d: New test.
         * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.s: New test.
         * testsuite/gas/arm/mve-vhcadd.d: New test.
         * testsuite/gas/arm/mve-vhcadd.s: New test.
         * testsuite/gas/arm/mve-vmax-vmin.d: New test.
         * testsuite/gas/arm/mve-vmax-vmin.s: New test.
         * testsuite/gas/arm/mve-vmaxa-vmina.d: New test.
         * testsuite/gas/arm/mve-vmaxa-vmina.s: New test.
         * testsuite/gas/arm/mve-vmaxnm-vminnm.d: New test.
         * testsuite/gas/arm/mve-vmaxnm-vminnm.s: New test.
         * testsuite/gas/arm/mve-vmaxnma-vminnma.s: New test.
         * testsuite/gas/arm/mve-vmaxnmv-vminnmv.d: New test.
         * testsuite/gas/arm/mve-vmaxnmv-vminnmv.s: New test.
         * testsuite/gas/arm/mve-vmaxv-vminv.d: New test.
         * testsuite/gas/arm/mve-vmaxv-vminv.s: New test.
         * testsuite/gas/arm/mve-vmla.d: New test.
         * testsuite/gas/arm/mve-vmla.s: New test.
         * testsuite/gas/arm/mve-vmladav.d: New test.
         * testsuite/gas/arm/mve-vmladav.s: New test.
         * testsuite/gas/arm/mve-vmlaldav.d: New test.
         * testsuite/gas/arm/mve-vmlaldav.s: New test.
         * testsuite/gas/arm/mve-vmlalv.d: New test.
         * testsuite/gas/arm/mve-vmlalv.s: New test.
         * testsuite/gas/arm/mve-vmlas.d: New test.
         * testsuite/gas/arm/mve-vmlas.s: New test.
         * testsuite/gas/arm/mve-vmlav.d: New test.
         * testsuite/gas/arm/mve-vmlav.s: New test.
         * testsuite/gas/arm/mve-vmlsdav.d: New test.
         * testsuite/gas/arm/mve-vmlsdav.s: New test.
         * testsuite/gas/arm/mve-vmlsldav.d: New test.
         * testsuite/gas/arm/mve-vmlsldav.s: New test.
         * testsuite/gas/arm/mve-vmov-1.d: New test.
         * testsuite/gas/arm/mve-vmov-1.s: New test.
         * testsuite/gas/arm/mve-vmov-2.d: New test.
         * testsuite/gas/arm/mve-vmov-2.s: New test.
         * testsuite/gas/arm/mve-vmul.d: New test.
         * testsuite/gas/arm/mve-vmul.s: New test.
         * testsuite/gas/arm/mve-vmulh.d: New test.
         * testsuite/gas/arm/mve-vmulh.s: New test.
         * testsuite/gas/arm/mve-vmullbt.d: New test.
         * testsuite/gas/arm/mve-vmullbt.s: New test.
         * testsuite/gas/arm/mve-vmvn.d: New test.
         * testsuite/gas/arm/mve-vmvn.s: New test.
         * testsuite/gas/arm/mve-vorn.d: New test.
         * testsuite/gas/arm/mve-vorn.s: New test.
         * testsuite/gas/arm/mve-vorr.d: New test.
         * testsuite/gas/arm/mve-vorr.s: New test.
         * testsuite/gas/arm/mve-vpnot.d: New test.
         * testsuite/gas/arm/mve-vpnot.s: New test.
         * testsuite/gas/arm/mve-vpsel.d: New test.
         * testsuite/gas/arm/mve-vpsel.s: New test.
         * testsuite/gas/arm/mve-vpt.d: New test.
         * testsuite/gas/arm/mve-vpt.s: New test.
         * testsuite/gas/arm/mve-vqabsneg.s: New test.
         * testsuite/gas/arm/mve-vqaddsub.d: New test.
         * testsuite/gas/arm/mve-vqaddsub.s: New test.
         * testsuite/gas/arm/mve-vqdmladh.d: New test.
         * testsuite/gas/arm/mve-vqdmladh.s: New test.
         * testsuite/gas/arm/mve-vqdmlah.d: New test.
         * testsuite/gas/arm/mve-vqdmlah.s: New test.
         * testsuite/gas/arm/mve-vqdmlash.d: New test.
         * testsuite/gas/arm/mve-vqdmlash.s: New test.
         * testsuite/gas/arm/mve-vqdmlsdh.d: New test.
         * testsuite/gas/arm/mve-vqdmlsdh.s: New test.
         * testsuite/gas/arm/mve-vqdmulh.d: New test.
         * testsuite/gas/arm/mve-vqdmulh.s: New test.
         * testsuite/gas/arm/mve-vqdmull.d: New test.
         * testsuite/gas/arm/mve-vqdmull.s: New test.
         * testsuite/gas/arm/mve-vqmovn.d: New test.
         * testsuite/gas/arm/mve-vqmovn.s: New test.
         * testsuite/gas/arm/mve-vqrshl.d: New test.
         * testsuite/gas/arm/mve-vqrshl.s: New test.
         * testsuite/gas/arm/mve-vqrshrn.d: New test.
         * testsuite/gas/arm/mve-vqrshrn.s: New test.
         * testsuite/gas/arm/mve-vqshl.d: New test.
         * testsuite/gas/arm/mve-vqshl.s: New test.
         * testsuite/gas/arm/mve-vrev.d: New test.
         * testsuite/gas/arm/mve-vrev.s: New test.
         * testsuite/gas/arm/mve-vrint.d: New test.
         * testsuite/gas/arm/mve-vrint.s: New test.
         * testsuite/gas/arm/mve-vrmlaldavh.d: New test.
         * testsuite/gas/arm/mve-vrmlaldavh.s: New test.
         * testsuite/gas/arm/mve-vrshl.d: New test.
         * testsuite/gas/arm/mve-vrshl.s: New test.
         * testsuite/gas/arm/mve-vsbc.d: New test.
         * testsuite/gas/arm/mve-vsbc.s: New test.
         * testsuite/gas/arm/mve-vshl.d: New test.
         * testsuite/gas/arm/mve-vshl.s: New test.
         * testsuite/gas/arm/mve-vshlc.d: New test.
         * testsuite/gas/arm/mve-vshlc.s: New test.
         * testsuite/gas/arm/mve-vshll.d: New test.
         * testsuite/gas/arm/mve-vshll.s: New test.
         * testsuite/gas/arm/mve-vshr.d: New test.
         * testsuite/gas/arm/mve-vshr.s: New test.
         * testsuite/gas/arm/mve-vshrn.d: New test.
         * testsuite/gas/arm/mve-vshrn.s: New test.
         * testsuite/gas/arm/mve-vsli.d: New test.
         * testsuite/gas/arm/mve-vsli.s: New test.
         * testsuite/gas/arm/mve-vsri.d: New test.
         * testsuite/gas/arm/mve-vsri.s: New test.
         * testsuite/gas/arm/mve-vstld.d: New test.
         * testsuite/gas/arm/mve-vstld.s: New test.
         * testsuite/gas/arm/mve-vstrldr-1.d: New test.
         * testsuite/gas/arm/mve-vstrldr-1.s: New test.
         * testsuite/gas/arm/mve-vstrldr-2.d: New test.
         * testsuite/gas/arm/mve-vstrldr-2.s: New test.
         * testsuite/gas/arm/mve-vstrldr-3.d: New test.
         * testsuite/gas/arm/mve-vstrldr-3.s: New test.

[-- Attachment #2: mve_tests.tar.bz2.part00 --]
[-- Type: application/octet-stream, Size: 200000 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 57/57][Arm][GAS] MVE Tests
  2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
@ 2019-05-01 18:24   ` Andre Vieira (lists)
  2019-05-01 18:25   ` Andre Vieira (lists)
  2019-05-01 18:25   ` Andre Vieira (lists)
  2 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 18:24 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 12435 bytes --]

1/4

On 01/05/2019 19:23, Andre Vieira (lists) wrote:
> Hi,
> 
> This patch (see attachment) adds all MVE GAS positive tests.
> 
> 
> gas/ChangeLog:
> 
> 2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
> 
>          * testsuite/gas/arm/mve-tailpredloop.d: New test.
>          * testsuite/gas/arm/mve-tailpredloop.s: New test.
>          * testsuite/gas/arm/mve-vabav.d: New test.
>          * testsuite/gas/arm/mve-vabav.s: New test.
>          * testsuite/gas/arm/mve-vabd.d: New test.
>          * testsuite/gas/arm/mve-vabd.s: New test.
>          * testsuite/gas/arm/mve-vabsneg.d: New test.
>          * testsuite/gas/arm/mve-vabsneg.s: New test.
>          * testsuite/gas/arm/mve-vadc.d: New test.
>          * testsuite/gas/arm/mve-vadc.s: New test.
>          * testsuite/gas/arm/mve-vaddlv.d: New test.
>          * testsuite/gas/arm/mve-vaddlv.s: New test.
>          * testsuite/gas/arm/mve-vaddsub.d: New test.
>          * testsuite/gas/arm/mve-vaddsub.s: New test.
>          * testsuite/gas/arm/mve-vaddv.d: New test.
>          * testsuite/gas/arm/mve-vaddv.s: New test.
>          * testsuite/gas/arm/mve-vand.d: New test.
>          * testsuite/gas/arm/mve-vand.s: New test.
>          * testsuite/gas/arm/mve-vbic.d: New test.
>          * testsuite/gas/arm/mve-vbic.s: New test.
>          * testsuite/gas/arm/mve-vbrsr.d: New test.
>          * testsuite/gas/arm/mve-vbrsr.s: New test.
>          * testsuite/gas/arm/mve-vcadd.d: New test.
>          * testsuite/gas/arm/mve-vcadd.s: New test.
>          * testsuite/gas/arm/mve-vcls.d: New test.
>          * testsuite/gas/arm/mve-vcls.s: New test.
>          * testsuite/gas/arm/mve-vclz.d: New test.
>          * testsuite/gas/arm/mve-vclz.s: New test.
>          * testsuite/gas/arm/mve-vcmla.d: New test.
>          * testsuite/gas/arm/mve-vcmla.s: New test.
>          * testsuite/gas/arm/mve-vcmp.d: New test.
>          * testsuite/gas/arm/mve-vcmp.s: New test.
>          * testsuite/gas/arm/mve-vcmul.d: New test.
>          * testsuite/gas/arm/mve-vcmul.s: New test.
>          * testsuite/gas/arm/mve-vcvt-1.d: New test.
>          * testsuite/gas/arm/mve-vcvt-1.s: New test.
>          * testsuite/gas/arm/mve-vcvt-2.d: New test.
>          * testsuite/gas/arm/mve-vcvt-2.s: New test.
>          * testsuite/gas/arm/mve-vcvt-3.d: New test.
>          * testsuite/gas/arm/mve-vcvt-3.s: New test.
>          * testsuite/gas/arm/mve-vcvt-4.d: New test.
>          * testsuite/gas/arm/mve-vcvt-4.s: New test.
>          * testsuite/gas/arm/mve-vddup.d: New test.
>          * testsuite/gas/arm/mve-vddup.s: New test.
>          * testsuite/gas/arm/mve-vdup.d: New test.
>          * testsuite/gas/arm/mve-vdup.s: New test.
>          * testsuite/gas/arm/mve-veor.d: New test.
>          * testsuite/gas/arm/mve-veor.s: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.d: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.s: New test.
>          * testsuite/gas/arm/mve-vfmas.d: New test.
>          * testsuite/gas/arm/mve-vfmas.s: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.d: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.s: New test.
>          * testsuite/gas/arm/mve-vhcadd.d: New test.
>          * testsuite/gas/arm/mve-vhcadd.s: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.d: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.s: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.d: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.s: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.d: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.s: New test.
>          * testsuite/gas/arm/mve-vmaxnma-vminnma.s: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.d: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.s: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.d: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.s: New test.
>          * testsuite/gas/arm/mve-vmla.d: New test.
>          * testsuite/gas/arm/mve-vmla.s: New test.
>          * testsuite/gas/arm/mve-vmladav.d: New test.
>          * testsuite/gas/arm/mve-vmladav.s: New test.
>          * testsuite/gas/arm/mve-vmlaldav.d: New test.
>          * testsuite/gas/arm/mve-vmlaldav.s: New test.
>          * testsuite/gas/arm/mve-vmlalv.d: New test.
>          * testsuite/gas/arm/mve-vmlalv.s: New test.
>          * testsuite/gas/arm/mve-vmlas.d: New test.
>          * testsuite/gas/arm/mve-vmlas.s: New test.
>          * testsuite/gas/arm/mve-vmlav.d: New test.
>          * testsuite/gas/arm/mve-vmlav.s: New test.
>          * testsuite/gas/arm/mve-vmlsdav.d: New test.
>          * testsuite/gas/arm/mve-vmlsdav.s: New test.
>          * testsuite/gas/arm/mve-vmlsldav.d: New test.
>          * testsuite/gas/arm/mve-vmlsldav.s: New test.
>          * testsuite/gas/arm/mve-vmov-1.d: New test.
>          * testsuite/gas/arm/mve-vmov-1.s: New test.
>          * testsuite/gas/arm/mve-vmov-2.d: New test.
>          * testsuite/gas/arm/mve-vmov-2.s: New test.
>          * testsuite/gas/arm/mve-vmul.d: New test.
>          * testsuite/gas/arm/mve-vmul.s: New test.
>          * testsuite/gas/arm/mve-vmulh.d: New test.
>          * testsuite/gas/arm/mve-vmulh.s: New test.
>          * testsuite/gas/arm/mve-vmullbt.d: New test.
>          * testsuite/gas/arm/mve-vmullbt.s: New test.
>          * testsuite/gas/arm/mve-vmvn.d: New test.
>          * testsuite/gas/arm/mve-vmvn.s: New test.
>          * testsuite/gas/arm/mve-vorn.d: New test.
>          * testsuite/gas/arm/mve-vorn.s: New test.
>          * testsuite/gas/arm/mve-vorr.d: New test.
>          * testsuite/gas/arm/mve-vorr.s: New test.
>          * testsuite/gas/arm/mve-vpnot.d: New test.
>          * testsuite/gas/arm/mve-vpnot.s: New test.
>          * testsuite/gas/arm/mve-vpsel.d: New test.
>          * testsuite/gas/arm/mve-vpsel.s: New test.
>          * testsuite/gas/arm/mve-vpt.d: New test.
>          * testsuite/gas/arm/mve-vpt.s: New test.
>          * testsuite/gas/arm/mve-vqabsneg.s: New test.
>          * testsuite/gas/arm/mve-vqaddsub.d: New test.
>          * testsuite/gas/arm/mve-vqaddsub.s: New test.
>          * testsuite/gas/arm/mve-vqdmladh.d: New test.
>          * testsuite/gas/arm/mve-vqdmladh.s: New test.
>          * testsuite/gas/arm/mve-vqdmlah.d: New test.
>          * testsuite/gas/arm/mve-vqdmlah.s: New test.
>          * testsuite/gas/arm/mve-vqdmlash.d: New test.
>          * testsuite/gas/arm/mve-vqdmlash.s: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.d: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.s: New test.
>          * testsuite/gas/arm/mve-vqdmulh.d: New test.
>          * testsuite/gas/arm/mve-vqdmulh.s: New test.
>          * testsuite/gas/arm/mve-vqdmull.d: New test.
>          * testsuite/gas/arm/mve-vqdmull.s: New test.
>          * testsuite/gas/arm/mve-vqmovn.d: New test.
>          * testsuite/gas/arm/mve-vqmovn.s: New test.
>          * testsuite/gas/arm/mve-vqrshl.d: New test.
>          * testsuite/gas/arm/mve-vqrshl.s: New test.
>          * testsuite/gas/arm/mve-vqrshrn.d: New test.
>          * testsuite/gas/arm/mve-vqrshrn.s: New test.
>          * testsuite/gas/arm/mve-vqshl.d: New test.
>          * testsuite/gas/arm/mve-vqshl.s: New test.
>          * testsuite/gas/arm/mve-vrev.d: New test.
>          * testsuite/gas/arm/mve-vrev.s: New test.
>          * testsuite/gas/arm/mve-vrint.d: New test.
>          * testsuite/gas/arm/mve-vrint.s: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.d: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.s: New test.
>          * testsuite/gas/arm/mve-vrshl.d: New test.
>          * testsuite/gas/arm/mve-vrshl.s: New test.
>          * testsuite/gas/arm/mve-vsbc.d: New test.
>          * testsuite/gas/arm/mve-vsbc.s: New test.
>          * testsuite/gas/arm/mve-vshl.d: New test.
>          * testsuite/gas/arm/mve-vshl.s: New test.
>          * testsuite/gas/arm/mve-vshlc.d: New test.
>          * testsuite/gas/arm/mve-vshlc.s: New test.
>          * testsuite/gas/arm/mve-vshll.d: New test.
>          * testsuite/gas/arm/mve-vshll.s: New test.
>          * testsuite/gas/arm/mve-vshr.d: New test.
>          * testsuite/gas/arm/mve-vshr.s: New test.
>          * testsuite/gas/arm/mve-vshrn.d: New test.
>          * testsuite/gas/arm/mve-vshrn.s: New test.
>          * testsuite/gas/arm/mve-vsli.d: New test.
>          * testsuite/gas/arm/mve-vsli.s: New test.
>          * testsuite/gas/arm/mve-vsri.d: New test.
>          * testsuite/gas/arm/mve-vsri.s: New test.
>          * testsuite/gas/arm/mve-vstld.d: New test.
>          * testsuite/gas/arm/mve-vstld.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.s: New test.

[-- Attachment #2: mve_tests.tar.bz2.part01 --]
[-- Type: application/octet-stream, Size: 200000 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 57/57][Arm][GAS] MVE Tests
  2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
  2019-05-01 18:24   ` Andre Vieira (lists)
  2019-05-01 18:25   ` Andre Vieira (lists)
@ 2019-05-01 18:25   ` Andre Vieira (lists)
  2 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 18:25 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 12442 bytes --]

4/4 EOF :)

On 01/05/2019 19:23, Andre Vieira (lists) wrote:
> Hi,
> 
> This patch (see attachment) adds all MVE GAS positive tests.
> 
> 
> gas/ChangeLog:
> 
> 2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
> 
>          * testsuite/gas/arm/mve-tailpredloop.d: New test.
>          * testsuite/gas/arm/mve-tailpredloop.s: New test.
>          * testsuite/gas/arm/mve-vabav.d: New test.
>          * testsuite/gas/arm/mve-vabav.s: New test.
>          * testsuite/gas/arm/mve-vabd.d: New test.
>          * testsuite/gas/arm/mve-vabd.s: New test.
>          * testsuite/gas/arm/mve-vabsneg.d: New test.
>          * testsuite/gas/arm/mve-vabsneg.s: New test.
>          * testsuite/gas/arm/mve-vadc.d: New test.
>          * testsuite/gas/arm/mve-vadc.s: New test.
>          * testsuite/gas/arm/mve-vaddlv.d: New test.
>          * testsuite/gas/arm/mve-vaddlv.s: New test.
>          * testsuite/gas/arm/mve-vaddsub.d: New test.
>          * testsuite/gas/arm/mve-vaddsub.s: New test.
>          * testsuite/gas/arm/mve-vaddv.d: New test.
>          * testsuite/gas/arm/mve-vaddv.s: New test.
>          * testsuite/gas/arm/mve-vand.d: New test.
>          * testsuite/gas/arm/mve-vand.s: New test.
>          * testsuite/gas/arm/mve-vbic.d: New test.
>          * testsuite/gas/arm/mve-vbic.s: New test.
>          * testsuite/gas/arm/mve-vbrsr.d: New test.
>          * testsuite/gas/arm/mve-vbrsr.s: New test.
>          * testsuite/gas/arm/mve-vcadd.d: New test.
>          * testsuite/gas/arm/mve-vcadd.s: New test.
>          * testsuite/gas/arm/mve-vcls.d: New test.
>          * testsuite/gas/arm/mve-vcls.s: New test.
>          * testsuite/gas/arm/mve-vclz.d: New test.
>          * testsuite/gas/arm/mve-vclz.s: New test.
>          * testsuite/gas/arm/mve-vcmla.d: New test.
>          * testsuite/gas/arm/mve-vcmla.s: New test.
>          * testsuite/gas/arm/mve-vcmp.d: New test.
>          * testsuite/gas/arm/mve-vcmp.s: New test.
>          * testsuite/gas/arm/mve-vcmul.d: New test.
>          * testsuite/gas/arm/mve-vcmul.s: New test.
>          * testsuite/gas/arm/mve-vcvt-1.d: New test.
>          * testsuite/gas/arm/mve-vcvt-1.s: New test.
>          * testsuite/gas/arm/mve-vcvt-2.d: New test.
>          * testsuite/gas/arm/mve-vcvt-2.s: New test.
>          * testsuite/gas/arm/mve-vcvt-3.d: New test.
>          * testsuite/gas/arm/mve-vcvt-3.s: New test.
>          * testsuite/gas/arm/mve-vcvt-4.d: New test.
>          * testsuite/gas/arm/mve-vcvt-4.s: New test.
>          * testsuite/gas/arm/mve-vddup.d: New test.
>          * testsuite/gas/arm/mve-vddup.s: New test.
>          * testsuite/gas/arm/mve-vdup.d: New test.
>          * testsuite/gas/arm/mve-vdup.s: New test.
>          * testsuite/gas/arm/mve-veor.d: New test.
>          * testsuite/gas/arm/mve-veor.s: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.d: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.s: New test.
>          * testsuite/gas/arm/mve-vfmas.d: New test.
>          * testsuite/gas/arm/mve-vfmas.s: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.d: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.s: New test.
>          * testsuite/gas/arm/mve-vhcadd.d: New test.
>          * testsuite/gas/arm/mve-vhcadd.s: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.d: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.s: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.d: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.s: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.d: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.s: New test.
>          * testsuite/gas/arm/mve-vmaxnma-vminnma.s: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.d: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.s: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.d: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.s: New test.
>          * testsuite/gas/arm/mve-vmla.d: New test.
>          * testsuite/gas/arm/mve-vmla.s: New test.
>          * testsuite/gas/arm/mve-vmladav.d: New test.
>          * testsuite/gas/arm/mve-vmladav.s: New test.
>          * testsuite/gas/arm/mve-vmlaldav.d: New test.
>          * testsuite/gas/arm/mve-vmlaldav.s: New test.
>          * testsuite/gas/arm/mve-vmlalv.d: New test.
>          * testsuite/gas/arm/mve-vmlalv.s: New test.
>          * testsuite/gas/arm/mve-vmlas.d: New test.
>          * testsuite/gas/arm/mve-vmlas.s: New test.
>          * testsuite/gas/arm/mve-vmlav.d: New test.
>          * testsuite/gas/arm/mve-vmlav.s: New test.
>          * testsuite/gas/arm/mve-vmlsdav.d: New test.
>          * testsuite/gas/arm/mve-vmlsdav.s: New test.
>          * testsuite/gas/arm/mve-vmlsldav.d: New test.
>          * testsuite/gas/arm/mve-vmlsldav.s: New test.
>          * testsuite/gas/arm/mve-vmov-1.d: New test.
>          * testsuite/gas/arm/mve-vmov-1.s: New test.
>          * testsuite/gas/arm/mve-vmov-2.d: New test.
>          * testsuite/gas/arm/mve-vmov-2.s: New test.
>          * testsuite/gas/arm/mve-vmul.d: New test.
>          * testsuite/gas/arm/mve-vmul.s: New test.
>          * testsuite/gas/arm/mve-vmulh.d: New test.
>          * testsuite/gas/arm/mve-vmulh.s: New test.
>          * testsuite/gas/arm/mve-vmullbt.d: New test.
>          * testsuite/gas/arm/mve-vmullbt.s: New test.
>          * testsuite/gas/arm/mve-vmvn.d: New test.
>          * testsuite/gas/arm/mve-vmvn.s: New test.
>          * testsuite/gas/arm/mve-vorn.d: New test.
>          * testsuite/gas/arm/mve-vorn.s: New test.
>          * testsuite/gas/arm/mve-vorr.d: New test.
>          * testsuite/gas/arm/mve-vorr.s: New test.
>          * testsuite/gas/arm/mve-vpnot.d: New test.
>          * testsuite/gas/arm/mve-vpnot.s: New test.
>          * testsuite/gas/arm/mve-vpsel.d: New test.
>          * testsuite/gas/arm/mve-vpsel.s: New test.
>          * testsuite/gas/arm/mve-vpt.d: New test.
>          * testsuite/gas/arm/mve-vpt.s: New test.
>          * testsuite/gas/arm/mve-vqabsneg.s: New test.
>          * testsuite/gas/arm/mve-vqaddsub.d: New test.
>          * testsuite/gas/arm/mve-vqaddsub.s: New test.
>          * testsuite/gas/arm/mve-vqdmladh.d: New test.
>          * testsuite/gas/arm/mve-vqdmladh.s: New test.
>          * testsuite/gas/arm/mve-vqdmlah.d: New test.
>          * testsuite/gas/arm/mve-vqdmlah.s: New test.
>          * testsuite/gas/arm/mve-vqdmlash.d: New test.
>          * testsuite/gas/arm/mve-vqdmlash.s: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.d: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.s: New test.
>          * testsuite/gas/arm/mve-vqdmulh.d: New test.
>          * testsuite/gas/arm/mve-vqdmulh.s: New test.
>          * testsuite/gas/arm/mve-vqdmull.d: New test.
>          * testsuite/gas/arm/mve-vqdmull.s: New test.
>          * testsuite/gas/arm/mve-vqmovn.d: New test.
>          * testsuite/gas/arm/mve-vqmovn.s: New test.
>          * testsuite/gas/arm/mve-vqrshl.d: New test.
>          * testsuite/gas/arm/mve-vqrshl.s: New test.
>          * testsuite/gas/arm/mve-vqrshrn.d: New test.
>          * testsuite/gas/arm/mve-vqrshrn.s: New test.
>          * testsuite/gas/arm/mve-vqshl.d: New test.
>          * testsuite/gas/arm/mve-vqshl.s: New test.
>          * testsuite/gas/arm/mve-vrev.d: New test.
>          * testsuite/gas/arm/mve-vrev.s: New test.
>          * testsuite/gas/arm/mve-vrint.d: New test.
>          * testsuite/gas/arm/mve-vrint.s: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.d: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.s: New test.
>          * testsuite/gas/arm/mve-vrshl.d: New test.
>          * testsuite/gas/arm/mve-vrshl.s: New test.
>          * testsuite/gas/arm/mve-vsbc.d: New test.
>          * testsuite/gas/arm/mve-vsbc.s: New test.
>          * testsuite/gas/arm/mve-vshl.d: New test.
>          * testsuite/gas/arm/mve-vshl.s: New test.
>          * testsuite/gas/arm/mve-vshlc.d: New test.
>          * testsuite/gas/arm/mve-vshlc.s: New test.
>          * testsuite/gas/arm/mve-vshll.d: New test.
>          * testsuite/gas/arm/mve-vshll.s: New test.
>          * testsuite/gas/arm/mve-vshr.d: New test.
>          * testsuite/gas/arm/mve-vshr.s: New test.
>          * testsuite/gas/arm/mve-vshrn.d: New test.
>          * testsuite/gas/arm/mve-vshrn.s: New test.
>          * testsuite/gas/arm/mve-vsli.d: New test.
>          * testsuite/gas/arm/mve-vsli.s: New test.
>          * testsuite/gas/arm/mve-vsri.d: New test.
>          * testsuite/gas/arm/mve-vsri.s: New test.
>          * testsuite/gas/arm/mve-vstld.d: New test.
>          * testsuite/gas/arm/mve-vstld.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.s: New test.

[-- Attachment #2: mve_tests.tar.bz2.part03 --]
[-- Type: application/octet-stream, Size: 45914 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 57/57][Arm][GAS] MVE Tests
  2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
  2019-05-01 18:24   ` Andre Vieira (lists)
@ 2019-05-01 18:25   ` Andre Vieira (lists)
  2019-05-01 18:25   ` Andre Vieira (lists)
  2 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-01 18:25 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 12435 bytes --]

2/4

On 01/05/2019 19:23, Andre Vieira (lists) wrote:
> Hi,
> 
> This patch (see attachment) adds all MVE GAS positive tests.
> 
> 
> gas/ChangeLog:
> 
> 2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>
> 
>          * testsuite/gas/arm/mve-tailpredloop.d: New test.
>          * testsuite/gas/arm/mve-tailpredloop.s: New test.
>          * testsuite/gas/arm/mve-vabav.d: New test.
>          * testsuite/gas/arm/mve-vabav.s: New test.
>          * testsuite/gas/arm/mve-vabd.d: New test.
>          * testsuite/gas/arm/mve-vabd.s: New test.
>          * testsuite/gas/arm/mve-vabsneg.d: New test.
>          * testsuite/gas/arm/mve-vabsneg.s: New test.
>          * testsuite/gas/arm/mve-vadc.d: New test.
>          * testsuite/gas/arm/mve-vadc.s: New test.
>          * testsuite/gas/arm/mve-vaddlv.d: New test.
>          * testsuite/gas/arm/mve-vaddlv.s: New test.
>          * testsuite/gas/arm/mve-vaddsub.d: New test.
>          * testsuite/gas/arm/mve-vaddsub.s: New test.
>          * testsuite/gas/arm/mve-vaddv.d: New test.
>          * testsuite/gas/arm/mve-vaddv.s: New test.
>          * testsuite/gas/arm/mve-vand.d: New test.
>          * testsuite/gas/arm/mve-vand.s: New test.
>          * testsuite/gas/arm/mve-vbic.d: New test.
>          * testsuite/gas/arm/mve-vbic.s: New test.
>          * testsuite/gas/arm/mve-vbrsr.d: New test.
>          * testsuite/gas/arm/mve-vbrsr.s: New test.
>          * testsuite/gas/arm/mve-vcadd.d: New test.
>          * testsuite/gas/arm/mve-vcadd.s: New test.
>          * testsuite/gas/arm/mve-vcls.d: New test.
>          * testsuite/gas/arm/mve-vcls.s: New test.
>          * testsuite/gas/arm/mve-vclz.d: New test.
>          * testsuite/gas/arm/mve-vclz.s: New test.
>          * testsuite/gas/arm/mve-vcmla.d: New test.
>          * testsuite/gas/arm/mve-vcmla.s: New test.
>          * testsuite/gas/arm/mve-vcmp.d: New test.
>          * testsuite/gas/arm/mve-vcmp.s: New test.
>          * testsuite/gas/arm/mve-vcmul.d: New test.
>          * testsuite/gas/arm/mve-vcmul.s: New test.
>          * testsuite/gas/arm/mve-vcvt-1.d: New test.
>          * testsuite/gas/arm/mve-vcvt-1.s: New test.
>          * testsuite/gas/arm/mve-vcvt-2.d: New test.
>          * testsuite/gas/arm/mve-vcvt-2.s: New test.
>          * testsuite/gas/arm/mve-vcvt-3.d: New test.
>          * testsuite/gas/arm/mve-vcvt-3.s: New test.
>          * testsuite/gas/arm/mve-vcvt-4.d: New test.
>          * testsuite/gas/arm/mve-vcvt-4.s: New test.
>          * testsuite/gas/arm/mve-vddup.d: New test.
>          * testsuite/gas/arm/mve-vddup.s: New test.
>          * testsuite/gas/arm/mve-vdup.d: New test.
>          * testsuite/gas/arm/mve-vdup.s: New test.
>          * testsuite/gas/arm/mve-veor.d: New test.
>          * testsuite/gas/arm/mve-veor.s: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.d: New test.
>          * testsuite/gas/arm/mve-vfma-vfms.s: New test.
>          * testsuite/gas/arm/mve-vfmas.d: New test.
>          * testsuite/gas/arm/mve-vfmas.s: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.d: New test.
>          * testsuite/gas/arm/mve-vhadd-vhsub-vrhadd.s: New test.
>          * testsuite/gas/arm/mve-vhcadd.d: New test.
>          * testsuite/gas/arm/mve-vhcadd.s: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.d: New test.
>          * testsuite/gas/arm/mve-vmax-vmin.s: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.d: New test.
>          * testsuite/gas/arm/mve-vmaxa-vmina.s: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.d: New test.
>          * testsuite/gas/arm/mve-vmaxnm-vminnm.s: New test.
>          * testsuite/gas/arm/mve-vmaxnma-vminnma.s: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.d: New test.
>          * testsuite/gas/arm/mve-vmaxnmv-vminnmv.s: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.d: New test.
>          * testsuite/gas/arm/mve-vmaxv-vminv.s: New test.
>          * testsuite/gas/arm/mve-vmla.d: New test.
>          * testsuite/gas/arm/mve-vmla.s: New test.
>          * testsuite/gas/arm/mve-vmladav.d: New test.
>          * testsuite/gas/arm/mve-vmladav.s: New test.
>          * testsuite/gas/arm/mve-vmlaldav.d: New test.
>          * testsuite/gas/arm/mve-vmlaldav.s: New test.
>          * testsuite/gas/arm/mve-vmlalv.d: New test.
>          * testsuite/gas/arm/mve-vmlalv.s: New test.
>          * testsuite/gas/arm/mve-vmlas.d: New test.
>          * testsuite/gas/arm/mve-vmlas.s: New test.
>          * testsuite/gas/arm/mve-vmlav.d: New test.
>          * testsuite/gas/arm/mve-vmlav.s: New test.
>          * testsuite/gas/arm/mve-vmlsdav.d: New test.
>          * testsuite/gas/arm/mve-vmlsdav.s: New test.
>          * testsuite/gas/arm/mve-vmlsldav.d: New test.
>          * testsuite/gas/arm/mve-vmlsldav.s: New test.
>          * testsuite/gas/arm/mve-vmov-1.d: New test.
>          * testsuite/gas/arm/mve-vmov-1.s: New test.
>          * testsuite/gas/arm/mve-vmov-2.d: New test.
>          * testsuite/gas/arm/mve-vmov-2.s: New test.
>          * testsuite/gas/arm/mve-vmul.d: New test.
>          * testsuite/gas/arm/mve-vmul.s: New test.
>          * testsuite/gas/arm/mve-vmulh.d: New test.
>          * testsuite/gas/arm/mve-vmulh.s: New test.
>          * testsuite/gas/arm/mve-vmullbt.d: New test.
>          * testsuite/gas/arm/mve-vmullbt.s: New test.
>          * testsuite/gas/arm/mve-vmvn.d: New test.
>          * testsuite/gas/arm/mve-vmvn.s: New test.
>          * testsuite/gas/arm/mve-vorn.d: New test.
>          * testsuite/gas/arm/mve-vorn.s: New test.
>          * testsuite/gas/arm/mve-vorr.d: New test.
>          * testsuite/gas/arm/mve-vorr.s: New test.
>          * testsuite/gas/arm/mve-vpnot.d: New test.
>          * testsuite/gas/arm/mve-vpnot.s: New test.
>          * testsuite/gas/arm/mve-vpsel.d: New test.
>          * testsuite/gas/arm/mve-vpsel.s: New test.
>          * testsuite/gas/arm/mve-vpt.d: New test.
>          * testsuite/gas/arm/mve-vpt.s: New test.
>          * testsuite/gas/arm/mve-vqabsneg.s: New test.
>          * testsuite/gas/arm/mve-vqaddsub.d: New test.
>          * testsuite/gas/arm/mve-vqaddsub.s: New test.
>          * testsuite/gas/arm/mve-vqdmladh.d: New test.
>          * testsuite/gas/arm/mve-vqdmladh.s: New test.
>          * testsuite/gas/arm/mve-vqdmlah.d: New test.
>          * testsuite/gas/arm/mve-vqdmlah.s: New test.
>          * testsuite/gas/arm/mve-vqdmlash.d: New test.
>          * testsuite/gas/arm/mve-vqdmlash.s: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.d: New test.
>          * testsuite/gas/arm/mve-vqdmlsdh.s: New test.
>          * testsuite/gas/arm/mve-vqdmulh.d: New test.
>          * testsuite/gas/arm/mve-vqdmulh.s: New test.
>          * testsuite/gas/arm/mve-vqdmull.d: New test.
>          * testsuite/gas/arm/mve-vqdmull.s: New test.
>          * testsuite/gas/arm/mve-vqmovn.d: New test.
>          * testsuite/gas/arm/mve-vqmovn.s: New test.
>          * testsuite/gas/arm/mve-vqrshl.d: New test.
>          * testsuite/gas/arm/mve-vqrshl.s: New test.
>          * testsuite/gas/arm/mve-vqrshrn.d: New test.
>          * testsuite/gas/arm/mve-vqrshrn.s: New test.
>          * testsuite/gas/arm/mve-vqshl.d: New test.
>          * testsuite/gas/arm/mve-vqshl.s: New test.
>          * testsuite/gas/arm/mve-vrev.d: New test.
>          * testsuite/gas/arm/mve-vrev.s: New test.
>          * testsuite/gas/arm/mve-vrint.d: New test.
>          * testsuite/gas/arm/mve-vrint.s: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.d: New test.
>          * testsuite/gas/arm/mve-vrmlaldavh.s: New test.
>          * testsuite/gas/arm/mve-vrshl.d: New test.
>          * testsuite/gas/arm/mve-vrshl.s: New test.
>          * testsuite/gas/arm/mve-vsbc.d: New test.
>          * testsuite/gas/arm/mve-vsbc.s: New test.
>          * testsuite/gas/arm/mve-vshl.d: New test.
>          * testsuite/gas/arm/mve-vshl.s: New test.
>          * testsuite/gas/arm/mve-vshlc.d: New test.
>          * testsuite/gas/arm/mve-vshlc.s: New test.
>          * testsuite/gas/arm/mve-vshll.d: New test.
>          * testsuite/gas/arm/mve-vshll.s: New test.
>          * testsuite/gas/arm/mve-vshr.d: New test.
>          * testsuite/gas/arm/mve-vshr.s: New test.
>          * testsuite/gas/arm/mve-vshrn.d: New test.
>          * testsuite/gas/arm/mve-vshrn.s: New test.
>          * testsuite/gas/arm/mve-vsli.d: New test.
>          * testsuite/gas/arm/mve-vsli.s: New test.
>          * testsuite/gas/arm/mve-vsri.d: New test.
>          * testsuite/gas/arm/mve-vsri.s: New test.
>          * testsuite/gas/arm/mve-vstld.d: New test.
>          * testsuite/gas/arm/mve-vstld.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-1.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-2.s: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.d: New test.
>          * testsuite/gas/arm/mve-vstrldr-3.s: New test.

[-- Attachment #2: mve_tests.tar.bz2.part02 --]
[-- Type: application/octet-stream, Size: 200000 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint
  2019-05-01 17:43 ` [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint Andre Vieira (lists)
@ 2019-05-02  9:54   ` Nick Clifton
  2019-05-13 13:38     ` Andre Vieira (lists)
  0 siblings, 1 reply; 72+ messages in thread
From: Nick Clifton @ 2019-05-02  9:54 UTC (permalink / raw)
  To: Andre Vieira (lists), binutils

Hi Andre,

> This patch adds support for MVE instructions VCVT and VRINT.

Whilst compiling the code from this patch I received the following error message:

  opcodes/arm-dis.c: In function 'is_mve_undefined':
  opcodes/arm-dis.c:5794:24: error: bitwise comparison always evaluates to false 
      && ((imm6 & 0x30) == 2))
                        ^~

My guess is that you meant to compare against 0x20, but it would be best
if you fixed this yourself...

Cheers
  Nick

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (57 preceding siblings ...)
  2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
@ 2019-05-02 10:03 ` Nick Clifton
  2019-05-02 10:18 ` Nick Clifton
  2019-05-02 13:39 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton
  60 siblings, 0 replies; 72+ messages in thread
From: Nick Clifton @ 2019-05-02 10:03 UTC (permalink / raw)
  To: Andre Vieira (lists), binutils; +Cc: Richard Earnshaw

Hi Andre,

> The reason to split the testing is because we use assembly macros to generate extensive testing, which leads to massive 'expected result' files. Which would require zipping most of the patches to be able to send them over email. So instead we decided to collate all positive testing into one patch and only zip that one. The negative tests are smaller and have been included per relevant patch.

With the whole patch series applied to today's binutils mainline sources,
I am seeing three new assembler testsuite failures for an arm-eabi toolchain.
(I have not checked other arm toolchains yet).  The failures are:

  Running gas/testsuite/gas/arm/arm.exp ...
  FAIL: Valid Armv8.1-M Mainline Low Overhead loop instructions
  FAIL: bad MVE WLSTP, DLSTP and LETP instructions
  FAIL: MVE tail predicated low-overhead loop instructions

And looking in the log I see:

  gas/testsuite/gas/arm/armv8_1-m-loloop.s: Assembler messages:
  gas/testsuite/gas/arm/armv8_1-m-loloop.s:10: Error: branch out of range or not a multiple of 2
  FAIL: Valid Armv8.1-M Mainline Low Overhead loop instructions

and:

  extra lines in tmpdir/ld.messages starting with "^gas/testsuite/gas/arm/mve-tailpredloop-bad.s:27:   
  Error: branch out of range or not a multiple of 2$"
  EOF from gas/testsuite/gas/arm/mve-tailpredloop-bad.l
  FAIL: bad MVE WLSTP, DLSTP and LETP instructions

and:

  gas/arm/mve-tailpredloop.s:16: Error: branch out of range or not a multiple of 2
  gas/testsuite/gas/arm/mve-tailpredloop.s:17: Error: branch out of range or not a multiple of 2>, no expected output
  FAIL: MVE tail predicated low-overhead loop instructions

Possibly these are the result of my "fixing" the compilation problem in arm-dis.c
mentioned in a previous email, but I would appreciate it if you could investigate.

Cheers
  Nick

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (58 preceding siblings ...)
  2019-05-02 10:03 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton
@ 2019-05-02 10:18 ` Nick Clifton
  2019-05-13 13:39   ` [PATCH, binutils, Arm] Add Armv8.1-M Mainline and MVE enablement to NEWS Andre Vieira (lists)
  2019-05-02 13:39 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton
  60 siblings, 1 reply; 72+ messages in thread
From: Nick Clifton @ 2019-05-02 10:18 UTC (permalink / raw)
  To: Andre Vieira (lists), binutils; +Cc: Richard Earnshaw

Hi Andre,

> This patch series adds support for all M-profile Vector Extension(MVE) instructions to GAS and Objdump. 

I just noticed that the patch series does not include additions to the 
gas/NEWS and binutils/NEWS files, mentioning support for this architecture
extension.  Please could you add that ?

Cheers
  Nick



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd
  2019-05-01 16:55 ` [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd Andre Vieira (lists)
@ 2019-05-02 10:56   ` Nick Clifton
  2019-05-13 13:42     ` Andre Vieira (lists)
  0 siblings, 1 reply; 72+ messages in thread
From: Nick Clifton @ 2019-05-02 10:56 UTC (permalink / raw)
  To: Andre Vieira (lists), binutils; +Cc: Richard Earnshaw

Hi Andre,

> This patch adds most of the framework used by the rest of the GAS patches for MVE.

I noticed that this function:

> +static int
> +check_simd_pred_availability (int fp, unsigned check)

returns an integer value, but it is only ever used in boolean
tests.  IMHO it should either have a bfd_boolean return type,
or else an enum with the return values having textual names to
indicate their meaning.

I also saw that in do_neon_logic() there is a test against 
the function returning FAIL:

      if (rs == NS_QQQ
	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
	  == FAIL)

But FAIL is not one of the values explicitly returned by 
check_simd_pred_availability()....

Cheers
  Nick


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions
  2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
                   ` (59 preceding siblings ...)
  2019-05-02 10:18 ` Nick Clifton
@ 2019-05-02 13:39 ` Nick Clifton
  60 siblings, 0 replies; 72+ messages in thread
From: Nick Clifton @ 2019-05-02 13:39 UTC (permalink / raw)
  To: Andre Vieira (lists), binutils; +Cc: Richard Earnshaw

Hi Andre,

  This is just a quick note to say that I have found no other
  issues with the rest of your patch series, so once the items
  I have already mentioned are resolved I will be happy to approve
  the series.

Cheers
  Nick

 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint
  2019-05-02  9:54   ` Nick Clifton
@ 2019-05-13 13:38     ` Andre Vieira (lists)
  0 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-13 13:38 UTC (permalink / raw)
  To: Nick Clifton, binutils

[-- Attachment #1: Type: text/plain, Size: 620 bytes --]

Hi Nick,

Good catch thanks! Here is a reworked patch.

Cheers,
Andre

On 02/05/2019 10:54, Nick Clifton wrote:
> Hi Andre,
> 
>> This patch adds support for MVE instructions VCVT and VRINT.
> 
> Whilst compiling the code from this patch I received the following error message:
> 
>    opcodes/arm-dis.c: In function 'is_mve_undefined':
>    opcodes/arm-dis.c:5794:24: error: bitwise comparison always evaluates to false
>        && ((imm6 & 0x30) == 2))
>                          ^~
> 
> My guess is that you meant to compare against 0x20, but it would be best
> if you fixed this yourself...
> 
> Cheers
>    Nick
> 

[-- Attachment #2: 44.patch --]
[-- Type: text/x-patch, Size: 11839 bytes --]

diff --git a/gas/testsuite/gas/arm/mve-vrint-bad.l b/gas/testsuite/gas/arm/mve-vrint-bad.l
index 1d68a82badabae2a56559f476b356fdec9713c48..39fca355f6be2f7b8650867d20d590a4a992a18c 100644
--- a/gas/testsuite/gas/arm/mve-vrint-bad.l
+++ b/gas/testsuite/gas/arm/mve-vrint-bad.l
@@ -11,7 +11,7 @@
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintm.f64 q0,q1'
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintp.i16 q0,q1'
 [^:]*:13: Error: bad type in SIMD instruction -- `vrintp.f64 q0,q1'
-[^:]*:14: Error: invalid rounding mode -- `vrintr.f16 q0,q1'
+[^:]*:14: Error: VFP single, double or Neon quad precision register expected -- `vrintr.f16 q0,q1'
 [^:]*: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
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 2a89937b38eba5ceb70cc1a0c3a2ca8045431aae..66346ca921173a074f6d76219d0ce2c5f8d71a16 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -124,6 +124,11 @@ enum mve_instructions
   MVE_VSTRD_SCATTER_T4,
   MVE_VSTRW_SCATTER_T5,
   MVE_VSTRD_SCATTER_T6,
+  MVE_VCVT_FP_FIX_VEC,
+  MVE_VCVT_BETWEEN_FP_INT,
+  MVE_VCVT_FP_HALF_FP,
+  MVE_VCVT_FROM_FP_TO_INT,
+  MVE_VRINT_FP,
   MVE_NONE
 };
 
@@ -145,12 +150,14 @@ enum mve_unpredictable
   UNPRED_Q_REGS_EQUAL,		/* Unpredictable because vector registers are
 				   equal.  */
   UNPRED_OS,			/* Unpredictable because offset scaled == 1.  */
+  UNPRED_GP_REGS_EQUAL,		/* Unpredictable because gp registers are the
+				   same.  */
   UNPRED_NONE			/* No unpredictable behavior.  */
 };
 
 enum mve_undefined
 {
-  UNDEF_SIZE_3,			/* undefined because size == 3.  */
+  UNDEF_SIZE_0,			/* undefined because size == 0.  */
   UNDEF_SIZE_3,			/* undefined because size == 3.  */
   UNDEF_SIZE_LE_1,		/* undefined because size <= 1.  */
   UNDEF_SIZE_NOT_2,		/* undefined because size != 2.  */
@@ -160,6 +167,8 @@ enum mve_undefined
   UNDEF_NOT_UNS_SIZE_1,		/* undefined because U == 0 and
 				   size == 1.  */
   UNDEF_NOT_UNSIGNED,		/* undefined because U == 0.  */
+  UNDEF_VCVT_IMM6,		/* imm6 < 32.  */
+  UNDEF_VCVT_FSI_IMM6,		/* fsi = 0 and 32 >= imm6 <= 47.  */
   UNDEF_NONE			/* no undefined behavior.  */
 };
 
@@ -1868,7 +1877,9 @@ static const struct opcode32 neon_opcodes[] =
    %d			print addr mode of MVE vldr[bhw] and vstr[bhw]
    %u			print 'U' (unsigned) or 'S' for various mve instructions
    %i			print MVE predicate(s) for vpt and vpst
+   %m			print rounding mode for vcvt and vrint
    %n			print vector comparison code for predicated instruction
+   %s			print size for various vcvt instructions
    %v			print vector predicate for instruction in predicated
 			block
    %o			print offset scaled for vldr[hwd] and vstr[hwd]
@@ -1882,7 +1893,8 @@ static const struct opcode32 neon_opcodes[] =
 			UNPREDICTABLE
    %<bitfield>s		print size for vector predicate & non VMOV instructions
    %<bitfield>i		print immediate for vstr/vldr reg +/- imm
-   */
+   %<bitfield>k		print immediate for vector conversion instruction
+ */
 
 static const struct mopcode32 mve_opcodes[] =
 {
@@ -2051,6 +2063,36 @@ static const struct mopcode32 mve_opcodes[] =
    0xef000140, 0xef811f51,
    "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"},
 
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_FIX_VEC,
+   0xef800c50, 0xef801cd1,
+   "vcvt%v.%s\t%13-15,22Q, %1-3,5Q, #%16-21k"},
+
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_BETWEEN_FP_INT,
+   0xffb30640, 0xffb31e51,
+   "vcvt%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT between single and half-precision float, bottom half.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_HALF_FP,
+   0xee3f0e01, 0xefbf1fd1,
+   "vcvtb%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT between single and half-precision float, top half.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FP_HALF_FP,
+   0xee3f1e01, 0xefbf1fd1,
+   "vcvtt%v.%s\t%13-15,22Q, %1-3,5Q"},
+
+  /* Vector VCVT.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VCVT_FROM_FP_TO_INT,
+   0xffb30040, 0xffb31c51,
+   "vcvt%m%v.%s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VLD2.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VLD2,
@@ -2129,6 +2171,12 @@ static const struct mopcode32 mve_opcodes[] =
    0xec101f00, 0xfe101f80,
    "vldrw%v.u32\t%13-15,22Q, %d"},
 
+  /* Vector VRINT floating point.  */
+  {ARM_FEATURE_COPROC (FPU_MVE_FP),
+   MVE_VRINT_FP,
+   0xffb20440, 0xffb31c51,
+   "vrint%m%v.f%18-19s\t%13-15,22Q, %1-3,5Q"},
+
   /* Vector VST2 no writeback.  */
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_VST2,
@@ -4269,6 +4317,9 @@ is_mve_encoding_conflict (unsigned long given,
       else
 	return FALSE;
 
+    case MVE_VCVT_FP_FIX_VEC:
+      return (arm_decode_field (given, 16, 21) & 0x38) == 0;
+
     default:
       return FALSE;
 
@@ -4524,6 +4575,43 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCVT_FP_FIX_VEC:
+      {
+	unsigned long imm6 = arm_decode_field (given, 16, 21);
+	if ((imm6 & 0x20) == 0)
+	  {
+	    *undefined_code = UNDEF_VCVT_IMM6;
+	    return TRUE;
+	  }
+
+	if ((arm_decode_field (given, 9, 9) == 0)
+	    && ((imm6 & 0x30) == 0x20))
+	  {
+	    *undefined_code = UNDEF_VCVT_FSI_IMM6;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
+    case MVE_VCVT_BETWEEN_FP_INT:
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long size = arm_decode_field (given, 18, 19);
+	if (size == 0)
+	  {
+	    *undefined_code = UNDEF_SIZE_0;
+	    return TRUE;
+	  }
+	else if (size == 3)
+	  {
+	    *undefined_code = UNDEF_SIZE_3;
+	    return TRUE;
+	  }
+	else
+	  return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4749,6 +4837,31 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
       else
 	return FALSE;
 
+    case MVE_VCVT_BETWEEN_FP_INT:
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long rt = arm_decode_field (given, 0, 3);
+	unsigned long rt2 = arm_decode_field (given, 16, 19);
+
+	if ((rt == 0xd) || (rt2 == 0xd))
+	  {
+	    *unpredictable_code = UNPRED_R13;
+	    return TRUE;
+	  }
+	else if ((rt == 0xf) || (rt2 == 0xf))
+	  {
+	    *unpredictable_code = UNPRED_R15;
+	    return TRUE;
+	  }
+	else if (rt == rt2)
+	  {
+	    *unpredictable_code = UNPRED_GP_REGS_EQUAL;
+	    return TRUE;
+	  }
+
+	return FALSE;
+      }
+
     default:
       return FALSE;
     }
@@ -4797,6 +4910,14 @@ print_mve_undefined (struct disassemble_info *info,
       func (stream, "not unsigned");
       break;
 
+    case UNDEF_VCVT_IMM6:
+      func (stream, "invalid imm6");
+      break;
+
+    case UNDEF_VCVT_FSI_IMM6:
+      func (stream, "fsi = 0 and invalid imm6");
+      break;
+
     case UNDEF_NONE:
       break;
     }
@@ -4851,6 +4972,10 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "use of offset scaled");
       break;
 
+    case UNPRED_GP_REGS_EQUAL:
+      func (stream, "same general-purpose register used for both operands");
+      break;
+
     case UNPRED_NONE:
       break;
     }
@@ -4894,6 +5019,234 @@ print_mve_register_blocks (struct disassemble_info *info,
     }
 }
 
+static void
+print_mve_rounding_mode (struct disassemble_info *info,
+			 unsigned long given,
+			 enum mve_instructions matched_insn)
+{
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (matched_insn)
+    {
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	switch (arm_decode_field (given, 8, 9))
+	  {
+	  case 0:
+	    func (stream, "a");
+	    break;
+
+	  case 1:
+	    func (stream, "n");
+	    break;
+
+	  case 2:
+	    func (stream, "p");
+	    break;
+
+	  case 3:
+	    func (stream, "m");
+	    break;
+
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    case MVE_VRINT_FP:
+      {
+	switch (arm_decode_field (given, 7, 9))
+	  {
+	  case 0:
+	    func (stream, "n");
+	    break;
+
+	  case 1:
+	    func (stream, "x");
+	    break;
+
+	  case 2:
+	    func (stream, "a");
+	    break;
+
+	  case 3:
+	    func (stream, "z");
+	    break;
+
+	  case 5:
+	    func (stream, "m");
+	    break;
+
+	  case 7:
+	    func (stream, "p");
+
+	  case 4:
+	  case 6:
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+print_mve_vcvt_size (struct disassemble_info *info,
+		     unsigned long given,
+		     enum mve_instructions matched_insn)
+{
+  unsigned long mode = 0;
+  void *stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (matched_insn)
+    {
+    case MVE_VCVT_FP_FIX_VEC:
+      {
+	mode = (((given & 0x200) >> 7)
+		| ((given & 0x10000000) >> 27)
+		| ((given & 0x100) >> 8));
+
+	switch (mode)
+	  {
+	  case 0:
+	    func (stream, "f16.s16");
+	    break;
+
+	  case 1:
+	    func (stream, "s16.f16");
+	    break;
+
+	  case 2:
+	    func (stream, "f16.u16");
+	    break;
+
+	  case 3:
+	    func (stream, "u16.f16");
+	    break;
+
+	  case 4:
+	    func (stream, "f32.s32");
+	    break;
+
+	  case 5:
+	    func (stream, "s32.f32");
+	    break;
+
+	  case 6:
+	    func (stream, "f32.u32");
+	    break;
+
+	  case 7:
+	    func (stream, "u32.f32");
+	    break;
+
+	  default:
+	    break;
+	  }
+	break;
+      }
+    case MVE_VCVT_BETWEEN_FP_INT:
+      {
+	unsigned long size = arm_decode_field (given, 18, 19);
+	unsigned long op = arm_decode_field (given, 7, 8);
+
+	if (size == 1)
+	  {
+	    switch (op)
+	      {
+	      case 0:
+		func (stream, "f16.s16");
+		break;
+
+	      case 1:
+		func (stream, "f16.u16");
+		break;
+
+	      case 2:
+		func (stream, "s16.f16");
+		break;
+
+	      case 3:
+		func (stream, "u16.f16");
+		break;
+
+	      default:
+		break;
+	      }
+	  }
+	else if (size == 2)
+	  {
+	    switch (op)
+	      {
+	      case 0:
+		func (stream, "f32.s32");
+		break;
+
+	      case 1:
+		func (stream, "f32.u32");
+		break;
+
+	      case 2:
+		func (stream, "s32.f32");
+		break;
+
+	      case 3:
+		func (stream, "u32.f32");
+		break;
+	      }
+	  }
+      }
+      break;
+
+    case MVE_VCVT_FP_HALF_FP:
+      {
+	unsigned long op = arm_decode_field (given, 28, 28);
+	if (op == 0)
+	  func (stream, "f16.f32");
+	else if (op == 1)
+	  func (stream, "f32.f16");
+      }
+      break;
+
+    case MVE_VCVT_FROM_FP_TO_INT:
+      {
+	unsigned long size = arm_decode_field_multiple (given, 7, 7, 18, 19);
+
+	switch (size)
+	  {
+	  case 2:
+	    func (stream, "s16.f16");
+	    break;
+
+	  case 3:
+	    func (stream, "u16.f16");
+	    break;
+
+	  case 4:
+	    func (stream, "s32.f32");
+	    break;
+
+	  case 5:
+	    func (stream, "u32.f32");
+	    break;
+
+	  default:
+	    break;
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
 static void
 print_instruction_predicate (struct disassemble_info *info)
 {
@@ -4941,6 +5294,7 @@ print_mve_size (struct disassemble_info *info,
     case MVE_VPT_VEC_T5:
     case MVE_VPT_VEC_T6:
     case MVE_VRHADD:
+    case MVE_VRINT_FP:
     case MVE_VST2:
     case MVE_VST4:
     case MVE_VSTRB_SCATTER_T1:
@@ -6466,6 +6820,14 @@ print_insn_mve (struct disassemble_info *info, long given)
 			}
 		      break;
 
+		    case 'm':
+		      print_mve_rounding_mode (info, given, insn->mve_op);
+		      break;
+
+		    case 's':
+		      print_mve_vcvt_size (info, given, insn->mve_op);
+		      break;
+
 		    case 'u':
 		      {
 			if (arm_decode_field (given, 28, 28) == 0)
@@ -6535,6 +6897,9 @@ print_insn_mve (struct disassemble_info *info, long given)
 			      func (stream, "%lu", mod_imm);
 			    }
 			    break;
+			  case 'k':
+			    func (stream, "%lu", 64 - value);
+			    break;
 			  case 'r':
 			    func (stream, "%s", arm_regnames[value]);
 			    break;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH, binutils, Arm] Add Armv8.1-M Mainline and MVE enablement to NEWS
  2019-05-02 10:18 ` Nick Clifton
@ 2019-05-13 13:39   ` Andre Vieira (lists)
  0 siblings, 0 replies; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-13 13:39 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

Hi,

This patch announces the support for Armv8.1-M Mainline and M-profile 
Vector Extension for GAS and binutils. To be applied on top of MVE series.

Is this OK?

Cheers,
Andre

gas/ChangeLog
2019-05-13  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * NEWS: Mention Armv8.1-M Mainline and MVE.

binutils/ChangeLog
2019-05-13  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * NEWS: Mention Armv8.1-M Mainline and MVE.

On 02/05/2019 11:18, Nick Clifton wrote:
> Hi Andre,
> 
>> This patch series adds support for all M-profile Vector Extension(MVE) instructions to GAS and Objdump.
> 
> I just noticed that the patch series does not include additions to the
> gas/NEWS and binutils/NEWS files, mentioning support for this architecture
> extension.  Please could you add that ?
> 
> Cheers
>    Nick
> 
> 
> 

[-- Attachment #2: NEWS.patch --]
[-- Type: text/x-patch, Size: 1049 bytes --]

diff --git a/binutils/NEWS b/binutils/NEWS
index 7c9d7bef30b024bdb03bc0d86b1ffbc1506ffe66..5cae569e1d9435d0bf84dccbd4823170472cd5e7 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for the Armv8.1-M Mainline and M-profile Vector Extension (MVE)
+  instructions.
+
 * The separate debug info file options of readelf (--debug-dump=links
   and --debug-dump=follow) and objdump (--dwarf=links and
   --dwarf=follow-links) will now display and/or follow multiple links if
diff --git a/gas/NEWS b/gas/NEWS
index 3903c383c191428f0e39cf4a036d8d6243e2552f..ff88fe900146b57e38fde5bbbc389cd803cc7147 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for the Armv8.1-M Mainline and M-profile Vector Extension (MVE)
+  instructions.
+
 * For MIPS, Add -m[no-]fix-loongson3-llsc option to fix (or not) Loongson3 LLSC
   Errata.  Add a --enable-mips-fix-loongson3-llsc=[yes|no] configure time option
   to set the default behavior. Set the default if the configure option is not used

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd
  2019-05-02 10:56   ` Nick Clifton
@ 2019-05-13 13:42     ` Andre Vieira (lists)
       [not found]       ` <98e50dc4-7b0e-d727-0c20-34711be86533@redhat.com>
  0 siblings, 1 reply; 72+ messages in thread
From: Andre Vieira (lists) @ 2019-05-13 13:42 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 2418 bytes --]

Hi,

After Nick's comments I decided to clean up the definition and uses of 
check_simd_pred_availability.  I hope it makes the function clearer now. 
  This is to be applied on top of the MVE series (was easier and cleaner 
than rebasing everything).

Is this OK?

Cheers,
Andre

gas/ChangeLog
2019-05-13  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * config/tc-arm.c (check_simd_pred_availability): Refactor.
         (do_neon_dyadic_i_su): Refactor use of 
check_simd_pred_availability.
         (do_neon_dyadic_i64_su): Likewise.
         (do_neon_shl): Likewise.
         (do_neon_qshl): Likewise.
         (do_neon_rshl): Likewise.
         (do_neon_logic): Likewise.
         (do_neon_dyadic_if_su): Likewise.
         (do_neon_addsub_if_i): Likewise.
         (do_neon_mac_maybe_scalar): Likewise.
         (do_neon_fmac): Likewise.
         (do_neon_mul): Likewise.
         (do_neon_qdmulh): Likewise.
         (do_neon_qrdmlah): Likewise.
         (do_neon_abs_neg): Likewise.
         (do_neon_sli): Likewise.
         (do_neon_sri): Likewise.
         (do_neon_qshlu_imm): Likewise.
         (do_neon_cvt_1): Likewise.
         (do_neon_cvttb_1): Likewise.
         (do_neon_mvn): Likewise.
         (do_neon_rev): Likewise.
         (do_neon_dup): Likewise.
         (do_neon_mov): Likewise.
         (do_neon_rshift_round_imm): Likewise.
         (do_neon_sat_abs_neg): Likewise.
         (do_neon_cls): Likewise.
         (do_neon_clz): Likewise.
         (do_vmaxnm): Likewise.
         (do_vrint_1): Likewise.
         (do_vcmla): Likewise.
         (do_vcadd): Likewise.

On 02/05/2019 11:56, Nick Clifton wrote:
> Hi Andre,
> 
>> This patch adds most of the framework used by the rest of the GAS patches for MVE.
> 
> I noticed that this function:
> 
>> +static int
>> +check_simd_pred_availability (int fp, unsigned check)
> 
> returns an integer value, but it is only ever used in boolean
> tests.  IMHO it should either have a bfd_boolean return type,
> or else an enum with the return values having textual names to
> indicate their meaning.
> 
> I also saw that in do_neon_logic() there is a test against
> the function returning FAIL:
> 
>        if (rs == NS_QQQ
> 	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
> 	  == FAIL)
> 
> But FAIL is not one of the values explicitly returned by
> check_simd_pred_availability()....
> 
> Cheers
>    Nick
> 
> 

[-- Attachment #2: refactor.patch --]
[-- Type: text/x-patch, Size: 13398 bytes --]

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 20db5d9b278ccda70ac266f7df9f18e87cc430ea..6ba5e735cb78ec0e6f9d8ea1d93dc4a993a1a9a3 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -16562,7 +16562,13 @@ if (!thumb_mode && (check & NEON_CHECK_CC))
 return SUCCESS;
 }
 
-static int
+
+/* Return TRUE if the SIMD instruction is available for the current
+   cpu_variant.  FP is set to TRUE if this is a SIMD floating-point
+   instruction.  CHECK contains th.  CHECK contains the set of bits to pass to
+   vfp_or_neon_is_neon for the NEON specific checks.  */
+
+static bfd_boolean
 check_simd_pred_availability (int fp, unsigned check)
 {
 if (inst.cond > COND_ALWAYS)
@@ -16570,7 +16576,7 @@ if (inst.cond > COND_ALWAYS)
     if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
       {
 	inst.error = BAD_FPU;
-	return 1;
+	return FALSE;
       }
     inst.pred_insn_type = INSIDE_VPT_INSN;
   }
@@ -16579,18 +16585,18 @@ 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;
+      return FALSE;
   }
 else
   {
     if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
 	&& vfp_or_neon_is_neon (check) == FAIL)
-      return 3;
+      return FALSE;
 
     if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
       inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
   }
-return 0;
+return TRUE;
 }
 
 /* Neon instruction encoders, in approximate order of appearance.  */
@@ -16598,7 +16604,7 @@ return 0;
 static void
 do_neon_dyadic_i_su (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   enum neon_shape rs;
@@ -16620,7 +16626,7 @@ do_neon_dyadic_i_su (void)
 static void
 do_neon_dyadic_i64_su (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
   enum neon_shape rs;
   struct neon_type_el et;
@@ -16662,7 +16668,7 @@ neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
 static void
 do_neon_shl (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   if (!inst.operands[2].isreg)
@@ -16742,7 +16748,7 @@ do_neon_shl (void)
 static void
 do_neon_qshl (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   if (!inst.operands[2].isreg)
@@ -16816,7 +16822,7 @@ do_neon_qshl (void)
 static void
 do_neon_rshl (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   enum neon_shape rs;
@@ -16930,8 +16936,8 @@ do_neon_logic (void)
     {
       enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
       if (rs == NS_QQQ
-	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
-	  == FAIL)
+	  && !check_simd_pred_availability (FALSE,
+					    NEON_CHECK_ARCH | NEON_CHECK_CC))
 	return;
       else if (rs != NS_QQQ
 	       && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
@@ -16953,8 +16959,8 @@ do_neon_logic (void)
       /* Because neon_select_shape makes the second operand a copy of the first
 	 if the second operand is not present.  */
       if (rs == NS_QQI
-	  && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
-	  == FAIL)
+	  && !check_simd_pred_availability (FALSE,
+					    NEON_CHECK_ARCH | NEON_CHECK_CC))
 	return;
       else if (rs != NS_QQI
 	       && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
@@ -17397,8 +17403,8 @@ do_neon_dyadic_if_su (void)
 	      && et.type == NT_float
 	      && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
 
-  if (check_simd_pred_availability (et.type == NT_float,
-				    NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (et.type == NT_float,
+				     NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
@@ -17422,8 +17428,8 @@ do_neon_addsub_if_i (void)
      they are predicated or not.  */
   if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
     {
-      if (check_simd_pred_availability (et.type == NT_float,
-					NEON_CHECK_ARCH | NEON_CHECK_CC))
+      if (!check_simd_pred_availability (et.type == NT_float,
+					 NEON_CHECK_ARCH | NEON_CHECK_CC))
 	return;
     }
   else
@@ -17584,7 +17590,7 @@ do_neon_mac_maybe_scalar (void)
   if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
     return;
 
-  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (inst.operands[2].isscalar)
@@ -17621,7 +17627,7 @@ do_neon_fmac (void)
       && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
     return;
 
-  if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
@@ -17675,7 +17681,7 @@ do_neon_mul (void)
   if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
     return;
 
-  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (inst.operands[2].isscalar)
@@ -17708,7 +17714,7 @@ do_neon_mul (void)
 static void
 do_neon_qdmulh (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   if (inst.operands[2].isscalar)
@@ -18145,7 +18151,7 @@ do_mve_vmaxv (void)
 static void
 do_neon_qrdmlah (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
   if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
     {
@@ -18225,8 +18231,8 @@ do_neon_abs_neg (void)
   rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
   et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
 
-  if (check_simd_pred_availability (et.type == NT_float,
-				    NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (et.type == NT_float,
+				     NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
@@ -18243,7 +18249,7 @@ do_neon_abs_neg (void)
 static void
 do_neon_sli (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   enum neon_shape rs;
@@ -18269,7 +18275,7 @@ do_neon_sli (void)
 static void
 do_neon_sri (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   enum neon_shape rs;
@@ -18294,7 +18300,7 @@ do_neon_sri (void)
 static void
 do_neon_qshlu_imm (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   enum neon_shape rs;
@@ -18767,7 +18773,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 	      || flavour == neon_cvt_flavour_s32_f32
 	      || flavour == neon_cvt_flavour_u32_f32))
 	{
-	  if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
+	  if (!check_simd_pred_availability (TRUE,
+					     NEON_CHECK_CC | NEON_CHECK_ARCH))
 	    return;
 	}
       else if (mode == neon_cvt_mode_n)
@@ -18854,8 +18861,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 	      || flavour == neon_cvt_flavour_s32_f32
 	      || flavour == neon_cvt_flavour_u32_f32))
 	{
-	  if (check_simd_pred_availability (1,
-					    NEON_CHECK_CC | NEON_CHECK_ARCH8))
+	  if (!check_simd_pred_availability (TRUE,
+					     NEON_CHECK_CC | NEON_CHECK_ARCH8))
 	    return;
 	}
       else if (mode == neon_cvt_mode_z
@@ -18868,8 +18875,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 		   || flavour == neon_cvt_flavour_s32_f32
 		   || flavour == neon_cvt_flavour_u32_f32))
 	{
-	  if (check_simd_pred_availability (1,
-					    NEON_CHECK_CC | NEON_CHECK_ARCH))
+	  if (!check_simd_pred_availability (TRUE,
+					     NEON_CHECK_CC | NEON_CHECK_ARCH))
 	    return;
 	}
       /* fall through.  */
@@ -18878,8 +18885,8 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
 	{
 
 	  NEON_ENCODE (FLOAT, inst);
-	  if (check_simd_pred_availability (1,
-					    NEON_CHECK_CC | NEON_CHECK_ARCH8))
+	  if (!check_simd_pred_availability (TRUE,
+					     NEON_CHECK_CC | NEON_CHECK_ARCH8))
 	    return;
 
 	  inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
@@ -19039,7 +19046,7 @@ do_neon_cvttb_1 (bfd_boolean t)
   else if (rs == NS_QQ || rs == NS_QQI)
     {
       int single_to_half = 0;
-      if (check_simd_pred_availability (1, NEON_CHECK_ARCH))
+      if (!check_simd_pred_availability (TRUE, NEON_CHECK_ARCH))
 	return;
 
       enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
@@ -19179,7 +19186,7 @@ neon_move_immediate (void)
 static void
 do_neon_mvn (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   if (inst.operands[1].isreg)
@@ -19523,7 +19530,7 @@ do_neon_ext (void)
 static void
 do_neon_rev (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   enum neon_shape rs;
@@ -19588,7 +19595,7 @@ do_neon_dup (void)
 	N_8 | N_16 | N_32 | N_KEY, N_EQK);
       if (rs == NS_QR)
 	{
-	  if (check_simd_pred_availability (0, NEON_CHECK_ARCH))
+	  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH))
 	    return;
 	}
       else
@@ -19754,7 +19761,8 @@ do_neon_mov (void)
 
     case NS_QQ:  /* case 0/1.  */
       {
-	if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+	if (!check_simd_pred_availability (FALSE,
+					   NEON_CHECK_CC | NEON_CHECK_ARCH))
 	  return;
 	/* The architecture manual I have doesn't explicitly state which
 	   value the U bit should have for register->register moves, but
@@ -19784,7 +19792,8 @@ do_neon_mov (void)
       /* fall through.  */
 
     case NS_QI:  /* case 2/3.  */
-      if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+      if (!check_simd_pred_availability (FALSE,
+					 NEON_CHECK_CC | NEON_CHECK_ARCH))
 	return;
       inst.instruction = 0x0800010;
       neon_move_immediate ();
@@ -20089,7 +20098,7 @@ do_mve_movl (void)
 static void
 do_neon_rshift_round_imm (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
    return;
 
   enum neon_shape rs;
@@ -20186,7 +20195,7 @@ do_neon_zip_uzp (void)
 static void
 do_neon_sat_abs_neg (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
     return;
 
   enum neon_shape rs;
@@ -20222,7 +20231,7 @@ do_neon_recip_est (void)
 static void
 do_neon_cls (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   enum neon_shape rs;
@@ -20239,7 +20248,7 @@ do_neon_cls (void)
 static void
 do_neon_clz (void)
 {
-  if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
     return;
 
   enum neon_shape rs;
@@ -20792,7 +20801,7 @@ do_vmaxnm (void)
   if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
     return;
 
-  if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
+  if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH8))
     return;
 
   neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
@@ -20856,7 +20865,8 @@ do_vrint_1 (enum neon_cvt_mode mode)
       if (et.type == NT_invtype)
 	return;
 
-      if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
+      if (!check_simd_pred_availability (TRUE,
+					 NEON_CHECK_CC | NEON_CHECK_ARCH8))
 	return;
 
       NEON_ENCODE (FLOAT, inst);
@@ -20959,7 +20969,8 @@ do_vcmla (void)
 	      _("immediate out of range"));
   rot /= 90;
 
-  if (check_simd_pred_availability (1, NEON_CHECK_ARCH8 | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (TRUE,
+				     NEON_CHECK_ARCH8 | NEON_CHECK_CC))
     return;
 
   if (inst.operands[2].isscalar)
@@ -21036,8 +21047,8 @@ do_vcadd (void)
   if (et.type == NT_invtype)
     return;
 
-  if (check_simd_pred_availability (et.type == NT_float, NEON_CHECK_ARCH8
-				    | NEON_CHECK_CC))
+  if (!check_simd_pred_availability (et.type == NT_float,
+				     NEON_CHECK_ARCH8 | NEON_CHECK_CC))
     return;
 
   if (et.type == NT_float)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd
       [not found]         ` <4e56a5f3-bcde-f4cd-21d4-35cc3f11b5e8@arm.com>
@ 2019-05-14 16:53           ` Nick Clifton
  2019-05-14 16:54           ` Nick Clifton
  1 sibling, 0 replies; 72+ messages in thread
From: Nick Clifton @ 2019-05-14 16:53 UTC (permalink / raw)
  To: Andre Simoes Dias Vieira; +Cc: Richard Earnshaw, binutils

Hi Andre,

> Sure no problem. Let's see if it all fits in one email.

Thanks - that was very helpful.  I have no more concerns about the patch,
so please consider it approved and apply it at your leisure.

Cheers
  Nick

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd
       [not found]         ` <4e56a5f3-bcde-f4cd-21d4-35cc3f11b5e8@arm.com>
  2019-05-14 16:53           ` Nick Clifton
@ 2019-05-14 16:54           ` Nick Clifton
  1 sibling, 0 replies; 72+ messages in thread
From: Nick Clifton @ 2019-05-14 16:54 UTC (permalink / raw)
  To: Andre Simoes Dias Vieira; +Cc: Richard Earnshaw, binutils

Hi Andre,

  Sorry, just to be clear - I meant that the entire patch series
  is approved, not just patch 2/57....

Cheers
  Nick

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2019-05-14 16:54 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-01 16:51 [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
2019-05-01 16:53 ` [PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp Andre Vieira (lists)
2019-05-01 16:55 ` [PATCH 2/57][Arm][GAS] Add support for MVE instructions: vpst, vadd, vsub and vabd Andre Vieira (lists)
2019-05-02 10:56   ` Nick Clifton
2019-05-13 13:42     ` Andre Vieira (lists)
     [not found]       ` <98e50dc4-7b0e-d727-0c20-34711be86533@redhat.com>
     [not found]         ` <4e56a5f3-bcde-f4cd-21d4-35cc3f11b5e8@arm.com>
2019-05-14 16:53           ` Nick Clifton
2019-05-14 16:54           ` Nick Clifton
2019-05-01 16:56 ` [PATCH 3/57][Arm][GAS] Add support for MVE instructions: vabs and vneg Andre Vieira (lists)
2019-05-01 16:57 ` [PATCH 4/57][Arm][GAS] Add support for MVE instructions: vabav, vmladav and vmlsdav Andre Vieira (lists)
2019-05-01 16:59 ` [PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t} Andre Vieira (lists)
2019-05-01 17:00 ` [PATCH 6/57][Arm][GAS] Add support for MVE instructions: vst/vld{2,4} Andre Vieira (lists)
2019-05-01 17:01 ` [PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr Andre Vieira (lists)
2019-05-01 17:02 ` [PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt Andre Vieira (lists)
2019-05-01 17:03 ` [PATCH 10/57][Arm][GAS] Add support for MVE instructions: vcmp and vpt Andre Vieira (lists)
2019-05-01 17:03 ` [PATCH 9/57][Arm][GAS] Add support for MVE instructions: vmov Andre Vieira (lists)
2019-05-01 17:05 ` [PATCH 11/57][Arm][GAS] Add support for MVE instructions: vadc, vsbc and vbrsr Andre Vieira (lists)
2019-05-01 17:06 ` [PATCH 12/57][Arm][GAS] Add support for MVE instructions: vaddlv and vaddv Andre Vieira (lists)
2019-05-01 17:07 ` [PATCH 13/57][Arm][GAS] Add support for MVE instructions: vand, vbic, vorr, vorn and veor Andre Vieira (lists)
2019-05-01 17:08 ` [PATCH 14/57][Arm][GAS] Add support for MVE instructions: vcadd, vcmla and vcmul Andre Vieira (lists)
2019-05-01 17:09 ` [PATCH 15/57][Arm][GAS] Add support for MVE instructions: vcls, vclz and vfmas Andre Vieira (lists)
2019-05-01 17:09 ` [PATCH 16/57][Arm][GAS] Add support for MVE instructions: vdup, vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
2019-05-01 17:11 ` [PATCH 17/57][Arm][GAS] Add support for MVE instructions: vfma and vfms Andre Vieira (lists)
2019-05-01 17:12 ` [PATCH 19/57][Arm][GAS] Add support for MVE instructions: vmax[nm][a] and vmin[nm][a] Andre Vieira (lists)
2019-05-01 17:12 ` [PATCH 18/57][Arm][GAS] Add support for MVE instructions: vhcadd, vhadd, vhsub and vrhadd Andre Vieira (lists)
2019-05-01 17:13 ` [PATCH 21/57][Arm][GAS] Add support for MVE instructions: vmaxv, vmaxav, vminv and vminav Andre Vieira (lists)
2019-05-01 17:13 ` [PATCH 20/57][Arm][GAS] Add support for MVE instructions: vmaxnmv, vmaxnmav, vminnmv and vminnmav Andre Vieira (lists)
2019-05-01 17:15 ` [PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav, vrmlaldavh, vrmlalvh and vrmlsldavh Andre Vieira (lists)
2019-05-01 17:15 ` [PATCH 23/57][Arm][GAS] Add support for MVE instructions: vmla, vmul, vqadd and vqsub Andre Vieira (lists)
2019-05-01 17:16 ` [PATCH 24/57][Arm][GAS] Add support for MVE instructions: vmlas, vmulh and vrmulh Andre Vieira (lists)
2019-05-01 17:17 ` [PATCH 25/57][Arm][GAS] Add support for MVE instruction: vmvn, vqabs and vqneg Andre Vieira (lists)
2019-05-01 17:17 ` [PATCH 26/57][Arm][GAS] Add support for MVE instructions: vpnot and vpsel Andre Vieira (lists)
2019-05-01 17:18 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
2019-05-01 17:19 ` [PATCH 28/57][Arm][GAS] Add support for MVE instructions: vqdmlah, vqrdmlah, vqdmlash, vqrdmlash, vqdmulh and vqrdmulh Andre Vieira (lists)
2019-05-01 17:30 ` [PATCH 27/57][Arm][GAS] Add support for MVE instructions: vqdmladh, vqrdmladh, vqdmlsdh and vqrdmlsdh Andre Vieira (lists)
2019-05-01 17:31 ` [PATCH 29/57][Arm][GAS] Add support for MVE instructions: vqdmullt and vqdmullb Andre Vieira (lists)
2019-05-01 17:32 ` [PATCH 31/57][Arm][GAS] Add support for MVE instructions: vshrn[tb], vrshrn[tb], vqshrn[tb], vqshrun[tb], vqrshrn[tb] and vqrshrun[tb] Andre Vieira (lists)
2019-05-01 17:32 ` [PATCH 30/57][Arm][GAS] Add support for MVE instructions: vqmovnt, vqmovnb, vqmovunt, vqmovunb, vqrshl and vrshl Andre Vieira (lists)
2019-05-01 17:33 ` [PATCH 32/57][Arm][GAS] Add support for MVE instructions: vrintn, vrintx, vrinta, vrintz, vrintm and vrintp Andre Vieira (lists)
2019-05-01 17:34 ` [PATCH 33/57][Arm][GAS] Add support for MVE instructions: vshr, vrshr, vsli, vsri, vrev16, vrev32 and vrev64 Andre Vieira (lists)
2019-05-01 17:34 ` [PATCH 34/57][Arm][GAS] Add support for MVE instructions: vshl and vqshl Andre Vieira (lists)
2019-05-01 17:36 ` [PATCH 36/57][Arm][GAS] Add support for MVE instructions: wlstp, dlstp, letp and lctp Andre Vieira (lists)
2019-05-01 17:36 ` [PATCH 35/57][Arm][GAS] Add support for MVE instructions: vshlc and vshll Andre Vieira (lists)
2019-05-01 17:38 ` [PATCH 38/57][Arm][OBJDUMP] Disable the use of MVE reserved coproc numbers in coprocessor instructions Andre Vieira (lists)
2019-05-01 17:38 ` [PATCH 37/57][Arm][OBJDUMP] Add framework for MVE instructions Andre Vieira (lists)
2019-05-01 17:39 ` [PATCH 39/57][Arm][OBJDUMP] Add support for MVE instructions: vpt, vpst and vcmp Andre Vieira (lists)
2019-05-01 17:40 ` [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24] Andre Vieira (lists)
2019-05-01 17:40 ` [PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms, vhadd, vhsub and vrhadd Andre Vieira (lists)
2019-05-01 17:41 ` [PATCH 42/57][Arm][OBJDUMP] Add support for MVE instructions: vldr[bhw] and vstr[bhw] Andre Vieira (lists)
2019-05-01 17:42 ` [PATCH 43/57][Arm][OBJDUMP] Add support for MVE instructions: scatter stores and gather loads Andre Vieira (lists)
2019-05-01 17:43 ` [PATCH 44/57][Arm][OBJDUMP] Add support for MVE instructions: vcvt and vrint Andre Vieira (lists)
2019-05-02  9:54   ` Nick Clifton
2019-05-13 13:38     ` Andre Vieira (lists)
2019-05-01 17:44 ` [PATCH 45/57][Arm][OBJDUMP] Add support for MVE instructions: vmov, vmvn, vorr, vorn, vmovx and vbic Andre Vieira (lists)
2019-05-01 17:44 ` [PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull, vqmovn, vqmovun and vmovn Andre Vieira (lists)
2019-05-01 17:45 ` [PATCH 47/57][Arm][OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmladav, vmlas, vrmlsldavh, vmlsldav, vmlsdav, vrmlaldavh, vqdmlah, vqrdmlash, vqrdmlash, vqdmlsdh, vqrdmlsdh, vqdmulh and vqrdmulh Andre Vieira (lists)
2019-05-01 17:46 ` [PATCH 48/57][Arm][OBJDUMP] Add support for MVE instructions: vddup, vdwdup, vidup and viwdup Andre Vieira (lists)
2019-05-01 17:46 ` [PATCH 49/57][Arm][OBJDUMP] Add support for MVE complex number instructions Andre Vieira (lists)
2019-05-01 17:47 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Andre Vieira (lists)
2019-05-01 17:48 ` [PATCH 52/57][Arm][OBJDUMP] Add support for MVE instructions: vadc, vabav, vabd, vabs, vadd, vsbc and vsub Andre Vieira (lists)
2019-05-01 17:48 ` [PATCH 51/57][Arm][OBJDUMP] Add support for MVE instructions: lctp, letp, wlstp and dlstp Andre Vieira (lists)
2019-05-01 17:49 ` [PATCH 53/57][Arm][OBJDUMP] Add support for MVE instructions: vand, vbrsr, vcls, vclz and vctp Andre Vieira (lists)
2019-05-01 17:50 ` [PATCH 55/57][Arm][OBJDUMP] Add support for MVE instructions: vmul, vmulh, vrmulh and vneg Andre Vieira (lists)
2019-05-01 17:50 ` [PATCH 54/57][Arm][OBJDUMP] Add support for MVE instructions: vmax(a), vmax(a)v, vmaxnm(a), vmaxnm(a)v, vmin(a), vmin(a)v, vminnm(a), vminnm(a)v and vmla Andre Vieira (lists)
2019-05-01 17:51 ` [PATCH 56/57][Arm][OBJDUMP] Add support for MVE instructions: vpnot, vpsel, vqabs, vqadd, vqsub, vqneg and vrev Andre Vieira (lists)
2019-05-01 18:23 ` [PATCH 57/57][Arm][GAS] MVE Tests Andre Vieira (lists)
2019-05-01 18:24   ` Andre Vieira (lists)
2019-05-01 18:25   ` Andre Vieira (lists)
2019-05-01 18:25   ` Andre Vieira (lists)
2019-05-02 10:03 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton
2019-05-02 10:18 ` Nick Clifton
2019-05-13 13:39   ` [PATCH, binutils, Arm] Add Armv8.1-M Mainline and MVE enablement to NEWS Andre Vieira (lists)
2019-05-02 13:39 ` [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).