[Patch][binutils][arm] Create a new generic coprocessor array [3/10]
authorMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 7 Nov 2019 16:53:40 +0000 (16:53 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 7 Nov 2019 16:55:29 +0000 (16:55 +0000)
Hi,

This patch is part of a series that adds support for Armv8.6-A
(Matrix Multiply and BFloat16 extensions) to binutils.

Some generic instructions match a large range of encoding space (e.g.
stc, mcr, mrc).
Currently these instructions are in the coprocessor_opcodes array, which
means they are checked before many other instructions when disassembling
arm and thumb32 codes.

This patch moves the generic instructions into a separate array to be
checked later on.
This is done in order to avoid instruction conflict between the generic
instructions and newer ones -- this has already been seen with MVE, and
is also a problem with BFloat16.

One way to avoid the conflict could be to swap the search order between
coprocessor_opcodes and neon_opcodes.
We avoid this since it's a larger change that may introduce extra bugs
(that aren't caught by the testsuite).

We have decided against searching the generic array after searching the
arm specific and thumb32 specific arrays with a similar reasoning about
keeping the change small.

Regression tested with arm-none-linux-gnueabihf.

Committed on behalf of Mihail Ionescu.

opcodes/ChangeLog:

2019-10-29  Mihail Ionescu  <mihail.ionescu@arm.com>
2019-10-29  Matthew Malcomson  <matthew.malcomson@arm.com>

* arm-dis.c (print_insn_coprocessor,
print_insn_generic_coprocessor): Create wrapper functions around
the implementation of the print_insn_coprocessor control codes.
(print_insn_coprocessor_1): Original print_insn_coprocessor
function that now takes which array to look at as an argument.
(print_insn_arm): Use both print_insn_coprocessor and
print_insn_generic_coprocessor.
(print_insn_thumb32): As above.

Is it ok for trunk?

Regards,
Mihail

opcodes/ChangeLog
opcodes/arm-dis.c

index ef6ecf5e0bb82f9c5d0492bd27d66736d8e783e9..3919c260e19e8084ef8690373a177f0df78d7b7b 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-07  Mihail Ionescu  <mihail.ionescu@arm.com>
+2019-11-07  Matthew Malcomson  <matthew.malcomson@arm.com>
+
+       * arm-dis.c (print_insn_coprocessor,
+       print_insn_generic_coprocessor): Create wrapper functions around
+       the implementation of the print_insn_coprocessor control codes.
+       (print_insn_coprocessor_1): Original print_insn_coprocessor
+       function that now takes which array to look at as an argument.
+       (print_insn_arm): Use both print_insn_coprocessor and
+       print_insn_generic_coprocessor.
+       (print_insn_thumb32): As above.
+
 2019-11-07  Mihail Ionescu  <mihail.ionescu@arm.com>
 2019-11-07  Matthew Malcomson  <matthew.malcomson@arm.com>
 
index 8ff86bf4d62ff69ed9a4a5f3f5bc5c81b3abbe85..85c573034ea1e149eecbbe73eb705945040448d9 100644 (file)
@@ -1184,38 +1184,7 @@ static const struct sopcode32 coprocessor_opcodes[] =
   {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
     0xfeb80b40, 0xffbc0fd0, "vrint%16-17?mpna%u.f64\t%z1, %z0"},
 
-  /* Generic coprocessor instructions.  */
   {ANY, ARM_FEATURE_CORE_LOW (0), SENTINEL_GENERIC_START, 0, "" },
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E),
-    0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E),
-    0x0c500000, 0x0ff00000,
-    "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0e000000, 0x0f000010,
-    "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0e10f010, 0x0f10f010,
-    "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0e100010, 0x0f100010,
-    "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0e000010, 0x0f100010,
-    "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
-    0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
-
-  /* V6 coprocessor instructions.  */
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6),
-    0xfc500000, 0xfff00000,
-    "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6),
-    0xfc400000, 0xfff00000,
-    "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
-
   /* ARMv8.3 AdvSIMD instructions in the space of coprocessor 8.  */
   {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
     0xfc800800, 0xfeb00f10, "vcadd%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"},
@@ -1262,21 +1231,6 @@ static const struct sopcode32 coprocessor_opcodes[] =
   {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
     0xfe100850, 0xffb00f50, "vfmsl.f16\t%12-15,22Q, d%16-19,7d, d%0-2d[%3,5d]"},
 
-  /* V5 coprocessor instructions.  */
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
-    0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
-    0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
-    0xfe000000, 0xff000010,
-    "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
-    0xfe000010, 0xff100010,
-    "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
-  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
-    0xfe100010, 0xff100010,
-    "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
-
   /* ARMv8.2 half-precision Floating point coprocessor 9 (VFP) instructions.
      cp_num: bit <11:8> == 0b1001.
      cond: bit <31:28> == 0b1110, otherwise, it's UNPREDICTABLE.  */
@@ -1358,6 +1312,60 @@ static const struct sopcode32 coprocessor_opcodes[] =
   {ANY, ARM_FEATURE_CORE_LOW (0), 0, 0, 0}
 };
 
+/* Generic coprocessor instructions.  These are only matched if a more specific
+   SIMD or co-processor instruction does not match first.  */
+
+static const struct sopcode32 generic_coprocessor_opcodes[] =
+{
+  /* Generic coprocessor instructions.  */
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E),
+    0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E),
+    0x0c500000, 0x0ff00000,
+    "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0e000000, 0x0f000010,
+    "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0e10f010, 0x0f10f010,
+    "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0e100010, 0x0f100010,
+    "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0e000010, 0x0f100010,
+    "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2),
+    0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
+
+  /* V6 coprocessor instructions.  */
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6),
+    0xfc500000, 0xfff00000,
+    "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6),
+    0xfc400000, 0xfff00000,
+    "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
+
+  /* V5 coprocessor instructions.  */
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
+    0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
+    0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
+    0xfe000000, 0xff000010,
+    "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
+    0xfe000010, 0xff100010,
+    "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
+  {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
+    0xfe100010, 0xff100010,
+    "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+
+  {ANY, ARM_FEATURE_CORE_LOW (0), 0, 0, 0}
+};
+
 /* Neon opcode table:  This does not encode the top byte -- that is
    checked by the print_insn_neon routine, as it depends on whether we are
    doing thumb32 or arm32 disassembly.  */
@@ -7887,10 +7895,11 @@ print_vec_condition (struct disassemble_info *info, long given,
    recognised coprocessor instruction.  */
 
 static bfd_boolean
-print_insn_coprocessor (bfd_vma pc,
-                       struct disassemble_info *info,
-                       long given,
-                       bfd_boolean thumb)
+print_insn_coprocessor_1 (const struct sopcode32 *opcodes,
+                         bfd_vma pc,
+                         struct disassemble_info *info,
+                         long given,
+                         bfd_boolean thumb)
 {
   const struct sopcode32 *insn;
   void *stream = info->stream;
@@ -7906,7 +7915,7 @@ print_insn_coprocessor (bfd_vma pc,
 
   allowed_arches = private_data->features;
 
-  for (insn = coprocessor_opcodes; insn->assembler; insn++)
+  for (insn = opcodes; insn->assembler; insn++)
     {
       unsigned long u_reg = 16;
       bfd_boolean is_unpredictable = FALSE;
@@ -8622,6 +8631,26 @@ print_insn_coprocessor (bfd_vma pc,
   return FALSE;
 }
 
+static bfd_boolean
+print_insn_coprocessor (bfd_vma pc,
+                       struct disassemble_info *info,
+                       long given,
+                       bfd_boolean thumb)
+{
+  return print_insn_coprocessor_1 (coprocessor_opcodes,
+                                  pc, info, given, thumb);
+}
+
+static bfd_boolean
+print_insn_generic_coprocessor (bfd_vma pc,
+                               struct disassemble_info *info,
+                               long given,
+                               bfd_boolean thumb)
+{
+  return print_insn_coprocessor_1 (generic_coprocessor_opcodes,
+                                  pc, info, given, thumb);
+}
+
 /* Decodes and prints ARM addressing modes.  Returns the offset
    used in the address, if any, if it is worthwhile printing the
    offset as a hexadecimal value in a comment at the end of the
@@ -9652,6 +9681,9 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
   if (print_insn_neon (info, given, FALSE))
     return;
 
+  if (print_insn_generic_coprocessor (pc, info, given, FALSE))
+    return;
+
   for (insn = arm_opcodes; insn->assembler; insn++)
     {
       if ((given & insn->mask) != insn->value)
@@ -10489,6 +10521,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
   if (is_mve && print_insn_mve (info, given))
     return;
 
+  if (print_insn_generic_coprocessor (pc, info, given, TRUE))
+    return;
+
   for (insn = thumb32_opcodes; insn->assembler; insn++)
     if ((given & insn->mask) == insn->value)
       {