[PATCH 45/57][Arm][OBJDUMP] Add support for MVE instructions: vmov, vmvn, vorr, vorn...
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 16 May 2019 13:29:36 +0000 (14:29 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 16 May 2019 15:37:35 +0000 (16:37 +0100)
opcodes/ChangeLog:
2019-05-16  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.

opcodes/ChangeLog
opcodes/arm-dis.c

index bec1b1067d5b18975faa9be166332c484fbe5b29..571dd3de3ecf18daf26c7ccc78afb559f34dbbdc 100644 (file)
@@ -1,3 +1,20 @@
+2019-05-16  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.
+
 2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Michael Collison <michael.collison@arm.com>
 
index 66346ca921173a074f6d76219d0ce2c5f8d71a16..a779138db0c267ac759d711240426f9c138ffc6e 100644 (file)
@@ -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
@@ -4320,6 +4468,40 @@ is_mve_encoding_conflict (unsigned long given,
     case MVE_VCVT_FP_FIX_VEC:
       return (arm_decode_field (given, 16, 21) & 0x38) == 0;
 
+    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;
 
@@ -4612,6 +4794,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;
     }
@@ -4837,6 +5080,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:
       {
@@ -4862,11 +5107,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)
@@ -4882,6 +5340,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;
@@ -4918,6 +5380,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;
     }
@@ -4976,6 +5450,14 @@ print_mve_unpredictable (struct disassemble_info *info,
       func (stream, "same general-purpose 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;
     }
@@ -5339,6 +5821,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;
     }
@@ -5563,7 +6127,6 @@ print_insn_coprocessor (bfd_vma pc,
           don't let it match here.  */
        continue;
 
-
       for (c = insn->assembler; *c; c++)
        {
          if (*c == '%')
@@ -6830,10 +7393,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;
 
@@ -6850,6 +7433,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':
                      {
@@ -6907,12 +7500,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 ();
                          }