[PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull...
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 16 May 2019 13:30:38 +0000 (14:30 +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.
(is_mve_encoding_conflict): Handle new instructions.
(is_mve_undefined): Likewise.
(is_mve_unpredictable): Likewise.
(print_mve_size): Likewise.
(print_insn_mve): Likewise.

opcodes/ChangeLog
opcodes/arm-dis.c

index 571dd3de3ecf18daf26c7ccc78afb559f34dbbdc..88304d59c68e33617968888c0418e9e679fe7d79 100644 (file)
@@ -1,3 +1,13 @@
+2019-05-16  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.
+
 2019-05-16  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Michael Collison <michael.collison@arm.com>
 
index a779138db0c267ac759d711240426f9c138ffc6e..16bf0b9178dc39d8cbf5b538a8315ac0132887e0 100644 (file)
@@ -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:
@@ -4502,6 +4560,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;
 
@@ -4855,6 +4930,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;
     }
@@ -5126,6 +5210,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;
     }
@@ -5804,6 +5968,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)
        {
@@ -5868,6 +6050,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)
        {
@@ -7443,6 +7632,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':
                      {