]> Git Repo - binutils.git/blobdiff - opcodes/arm-dis.c
[binutils, ARM, 8/16] BFL infrastructure with new global reloc R_ARM_THM_BF18
[binutils.git] / opcodes / arm-dis.c
index c626bc9f319d434651e3cac4aa4f95b43964a9d2..b32ff323f89711150c453e59759b7b2b63a91598 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction printing code for the ARM
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
    Contributed by Richard Earnshaw ([email protected])
    Modification by James G. Smith ([email protected])
 
 
 #include "sysdep.h"
 
-#include "dis-asm.h"
+#include "disassemble.h"
 #include "opcode/arm.h"
 #include "opintl.h"
 #include "safe-ctype.h"
+#include "libiberty.h"
 #include "floatformat.h"
 
 /* FIXME: This shouldn't be done here.  */
 #include "coff/internal.h"
 #include "libcoff.h"
+#include "bfd.h"
 #include "elf-bfd.h"
 #include "elf/internal.h"
 #include "elf/arm.h"
+#include "mach-o.h"
 
 /* FIXME: Belongs in global header.  */
 #ifndef strneq
 #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
 #endif
 
-#ifndef NUM_ELEM
-#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
-#endif
-
 /* Cached mapping symbol state.  */
 enum map_type
 {
@@ -57,15 +56,14 @@ struct arm_private_data
   /* The features to use when disassembling optional instructions.  */
   arm_feature_set features;
 
-  /* Whether any mapping symbols are present in the provided symbol
-     table.  -1 if we do not know yet, otherwise 0 or 1.  */
-  int has_mapping_symbols;
-
   /* Track the last type (although this doesn't seem to be useful) */
   enum map_type last_type;
 
   /* Tracking symbol table information */
   int last_mapping_sym;
+
+  /* The end range of the current range being disassembled.  */
+  bfd_vma last_stop_offset;
   bfd_vma last_mapping_addr;
 };
 
@@ -115,6 +113,8 @@ struct opcode16
    %<bitfield>G         print as an iWMMXt general purpose or control register
    %<bitfield>D                print as a NEON D register
    %<bitfield>Q                print as a NEON Q register
+   %<bitfield>V                print as a NEON D or Q register
+   %<bitfield>E                print a quarter-float immediate value
 
    %y<code>            print a single precision VFP reg.
                          Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
@@ -124,7 +124,7 @@ struct opcode16
    %<bitfield>'c       print specified char iff bitfield is all ones
    %<bitfield>`c       print specified char iff bitfield is all zeroes
    %<bitfield>?ab...    select from array of values in big endian order
-   
+
    %L                  print as an iWMMXt N/M width field.
    %Z                  print the Immediate of a WSHUFH instruction.
    %l                  like 'A' except use byte offsets for 'B' & 'H'
@@ -141,6 +141,8 @@ enum opcode_sentinel_enum
 } opcode_sentinels;
 
 #define UNDEFINED_INSTRUCTION      "\t\t; <UNDEFINED> instruction: %0-31x"
+#define UNKNOWN_INSTRUCTION_32BIT  "\t\t; <UNDEFINED> instruction: %08x"
+#define UNKNOWN_INSTRUCTION_16BIT  "\t\t; <UNDEFINED> instruction: %04x"
 #define UNPREDICTABLE_INSTRUCTION  "\t; <UNPREDICTABLE>"
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
@@ -406,6 +408,12 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_FPA_EXT_V2),
     0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
 
+  /* ARMv8-M Mainline Security Extensions instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN),
+    0xec300a00, 0xfff0ffff, "vlldm\t%16-19r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN),
+    0xec200a00, 0xfff0ffff, "vlstm\t%16-19r"},
+
   /* Register load/store.  */
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1),
     0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
@@ -497,6 +505,8 @@ static const struct opcode32 coprocessor_opcodes[] =
     0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
+  {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
+    0x0ee50a10, 0x0fff0fff, "vmsr%c\tmvfr2, %12-15r"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
@@ -509,6 +519,8 @@ static const struct opcode32 coprocessor_opcodes[] =
     0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
+  {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
+    0x0ef50a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr2"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
     0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD),
@@ -578,9 +590,9 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1),
     0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V3xD),
-    0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
+    0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19E"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V3),
-    0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
+    0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19E"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V2),
     0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_V2),
@@ -818,17 +830,17 @@ static const struct opcode32 coprocessor_opcodes[] =
 
   /* FP v5.  */
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe000a00, 0xff800f00, "vsel%20-21c%u.f32\t%y1, %y2, %y0"},
+    0xfe000a00, 0xff800f50, "vsel%20-21c%u.f32\t%y1, %y2, %y0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe000b00, 0xff800f00, "vsel%20-21c%u.f64\t%z1, %z2, %z0"},
+    0xfe000b00, 0xff800f50, "vsel%20-21c%u.f64\t%z1, %z2, %z0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe800a00, 0xffb00f40, "vmaxnm%u.f32\t%y1, %y2, %y0"},
+    0xfe800a00, 0xffb00f50, "vmaxnm%u.f32\t%y1, %y2, %y0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe800b00, 0xffb00f40, "vmaxnm%u.f64\t%z1, %z2, %z0"},
+    0xfe800b00, 0xffb00f50, "vmaxnm%u.f64\t%z1, %z2, %z0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe800a40, 0xffb00f40, "vminnm%u.f32\t%y1, %y2, %y0"},
+    0xfe800a40, 0xffb00f50, "vminnm%u.f32\t%y1, %y2, %y0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfe800b40, 0xffb00f40, "vminnm%u.f64\t%z1, %z2, %z0"},
+    0xfe800b40, 0xffb00f50, "vminnm%u.f64\t%z1, %z2, %z0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
     0xfebc0a40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f32\t%y1, %y0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
@@ -838,9 +850,9 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
     0x0eb60b40, 0x0fbe0f50, "vrint%7,16??xzr%c.f64\t%z1, %z0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfeb80a40, 0xffbc0f50, "vrint%16-17?mpna%u.f32\t%y1, %y0"},
+    0xfeb80a40, 0xffbc0fd0, "vrint%16-17?mpna%u.f32\t%y1, %y0"},
   {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8),
-    0xfeb80b40, 0xffbc0f50, "vrint%16-17?mpna%u.f64\t%z1, %z0"},
+    0xfeb80b40, 0xffbc0fd0, "vrint%16-17?mpna%u.f64\t%z1, %z0"},
 
   /* Generic coprocessor instructions.  */
   {ARM_FEATURE_CORE_LOW (0), SENTINEL_GENERIC_START, 0, "" },
@@ -874,6 +886,52 @@ static const struct opcode32 coprocessor_opcodes[] =
     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.  */
+  {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"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfc900800, 0xfeb00f10, "vcadd%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfc200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfd200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfc300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfd300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfe000800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20'90"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfe200800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20?21%20?780"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfe800800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20'90"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0xfea00800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20?21%20?780"},
+
+  /* Dot Product instructions in the space of coprocessor 13.  */
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
+    0xfc200d00, 0xffb00f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3,5V"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
+    0xfe000d00, 0xff000f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3D[%5?10]"},
+
+  /* ARMv8.2 FMAC Long instructions in the space of coprocessor 8.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfc200810, 0xffb00f50, "vfmal.f16\t%12-15,22D, s%7,16-19d, s%5,0-3d"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfca00810, 0xffb00f50, "vfmsl.f16\t%12-15,22D, s%7,16-19d, s%5,0-3d"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfc200850, 0xffb00f50, "vfmal.f16\t%12-15,22Q, d%16-19,7d, d%0-3,5d"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfca00850, 0xffb00f50, "vfmsl.f16\t%12-15,22Q, d%16-19,7d, d%0-3,5d"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfe000810, 0xffb00f50, "vfmal.f16\t%12-15,22D, s%7,16-19d, s%5,0-2d[%3d]"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfe100810, 0xffb00f50, "vfmsl.f16\t%12-15,22D, s%7,16-19d, s%5,0-2d[%3d]"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A),
+    0xfe000850, 0xffb00f50, "vfmal.f16\t%12-15,22Q, d%16-19,7d, d%0-2d[%3,5d]"},
+  {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.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V5),
     0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
@@ -889,6 +947,84 @@ static const struct opcode32 coprocessor_opcodes[] =
     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.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb009c0, 0x0fbf0fd0, "vabs%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e300900, 0x0fb00f50, "vadd%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb40940, 0x0fbf0f50, "vcmp%7'e%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb50940, 0x0fbf0f70, "vcmp%7'e%c.f16\t%y1, #0.0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eba09c0, 0x0fbe0fd0, "vcvt%c.f16.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0ebe09c0, 0x0fbe0fd0, "vcvt%c.%16?us%7?31%7?26.f16\t%y1, %y1, #%5,0-3k"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0ebc0940, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb80940, 0x0fbf0f50, "vcvt%c.f16.%7?su32\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfebc0940, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e800900, 0x0fb00f50, "vdiv%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0ea00900, 0x0fb00f50, "vfma%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0ea00940, 0x0fb00f50, "vfms%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e900940, 0x0fb00f50, "vfnma%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e900900, 0x0fb00f50, "vfnms%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfeb00ac0, 0xffbf0fd0, "vins.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfeb00a40, 0xffbf0fd0, "vmovx%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0d100900, 0x0f300f00, "vldr%c.16\t%y1, %A"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0d000900, 0x0f300f00, "vstr%c.16\t%y1, %A"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfe800900, 0xffb00f50, "vmaxnm%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfe800940, 0xffb00f50, "vminnm%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e000900, 0x0fb00f50, "vmla%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e000940, 0x0fb00f50, "vmls%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e100910, 0x0ff00f7f, "vmov%c.f16\t%12-15r, %y2"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e000910, 0x0ff00f7f, "vmov%c.f16\t%y2, %12-15r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xeb00900, 0x0fb00ff0, "vmov%c.f16\t%y1, #%0-3,16-19E"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e200900, 0x0fb00f50, "vmul%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb10940, 0x0fbf0fd0, "vneg%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e100940, 0x0fb00f50, "vnmla%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e100900, 0x0fb00f50, "vnmls%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e200940, 0x0fb00f50, "vnmul%c.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb60940, 0x0fbe0f50, "vrint%7,16??xzr%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfeb80940, 0xffbc0fd0, "vrint%16-17?mpna%u.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xfe000900, 0xff800f50, "vsel%20-21c%u.f16\t%y1, %y2, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0eb109c0, 0x0fbf0fd0, "vsqrt%c.f16\t%y1, %y0"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0x0e300940, 0x0fb00f50, "vsub%c.f16\t%y1, %y2, %y0"},
+
+  /* ARMv8.3 javascript conversion instruction.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A),
+    0x0eb90bc0, 0x0fbf0fd0, "vjcvt%c.s32.f64\t%y1, %z0"},
+
   {ARM_FEATURE_CORE_LOW (0), 0, 0, 0}
 };
 
@@ -919,7 +1055,7 @@ static const struct opcode32 coprocessor_opcodes[] =
    %<bitfield>Sn       print byte scaled width limited by n
    %<bitfield>Tn       print short scaled width limited by n
    %<bitfield>Un       print long scaled width limited by n
-   
+
    %<bitfield>'c       print specified char iff bitfield is all ones
    %<bitfield>`c       print specified char iff bitfield is all zeroes
    %<bitfield>?ab...    select from array of values in big endian order.  */
@@ -956,15 +1092,23 @@ static const struct opcode32 neon_opcodes[] =
 
   /* NEON fused multiply add instructions.  */
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA),
-    0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000c10, 0xffb00f10, "vfma%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100c10, 0xffb00f10, "vfma%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA),
-    0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2200c10, 0xffb00f10, "vfms%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2300c10, 0xffb00f10, "vfms%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
 
   /* Two registers, miscellaneous.  */
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8),
     0xf3ba0400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f32\t%12-15,22R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3b60400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f16\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8),
     0xf3bb0000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us32.f32\t%12-15,22R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3b70000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us16.f16\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8),
     0xf3b00300, 0xffbf0fd0, "aese%u.8\t%12-15,22Q, %0-3,5Q"},
   {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8),
@@ -1004,8 +1148,12 @@ static const struct opcode32 neon_opcodes[] =
     "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3b70400, 0xffbf0e90, "vrecpe%c.%8?fu16\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3b70480, 0xffbf0e90, "vrsqrte%c.%8?fu16\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1045,8 +1193,11 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3b30600, 0xffb30e10,
+    0xf3bb0600, 0xffbf0e10,
     "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3b70600, 0xffbf0e10,
+    "vcvt%c.%7-8?usff16.%7-8?ffus16\t%12-15,22R, %0-3,5R"},
 
   /* Three registers of the same length.  */
   {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8),
@@ -1064,9 +1215,13 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8),
     0xf3200c40, 0xffb00f50, "sha256su1%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8),
-    0xf3000f10, 0xffa00f10, "vmaxnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000f10, 0xffb00f10, "vmaxnm%u.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100f10, 0xffb00f10, "vmaxnm%u.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8),
-    0xf3200f10, 0xffa00f10, "vminnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3200f10, 0xffb00f10, "vminnm%u.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3300f10, 0xffb00f10, "vminnm%u.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1084,41 +1239,77 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000d00, 0xffb00f10, "vadd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100d00, 0xffb00f10, "vadd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000d10, 0xffb00f10, "vmla%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100d10, 0xffb00f10, "vmla%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000e00, 0xffb00f10, "vceq%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100e00, 0xffb00f10, "vceq%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000f00, 0xffb00f10, "vmax%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100f00, 0xffb00f10, "vmax%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2000f10, 0xffb00f10, "vrecps%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2100f10, 0xffb00f10, "vrecps%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2200d00, 0xffb00f10, "vsub%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2300d00, 0xffb00f10, "vsub%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2200d10, 0xffb00f10, "vmls%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2300d10, 0xffb00f10, "vmls%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2200f00, 0xffb00f10, "vmin%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2300f00, 0xffb00f10, "vmin%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf2200f10, 0xffb00f10, "vrsqrts%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2300f10, 0xffb00f10, "vrsqrts%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000d00, 0xffb00f10, "vpadd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100d00, 0xffb00f10, "vpadd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000d10, 0xffb00f10, "vmul%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100d10, 0xffb00f10, "vmul%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000e00, 0xffb00f10, "vcge%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100e00, 0xffb00f10, "vcge%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000e10, 0xffb00f10, "vacge%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100e10, 0xffb00f10, "vacge%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3000f00, 0xffb00f10, "vpmax%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3100f00, 0xffb00f10, "vpmax%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3200d00, 0xffb00f10, "vabd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3300d00, 0xffb00f10, "vabd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3200e00, 0xffb00f10, "vcgt%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3300e00, 0xffb00f10, "vcgt%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3200e10, 0xffb00f10, "vacgt%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3300e10, 0xffb00f10, "vacgt%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+    0xf3200f00, 0xffb00f10, "vpmin%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf3300f00, 0xffb00f10, "vpmin%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1194,6 +1385,12 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2000a10, 0xfe800f10,
     "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf3000b10, 0xff800f10,
+    "vqrdmlah%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf3000c10, 0xff800f10,
+    "vqrdmlsh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
 
   /* One register and an immediate value.  */
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1344,6 +1541,9 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2a00e10, 0xfea00e90,
     "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
+    0xf2a00c10, 0xfea00e90,
+    "vcvt%c.%24,8?usff16.%24,8?ffus16\t%12-15,22R, %0-3,5R, #%16-20e"},
 
   /* Three registers of different lengths.  */
   {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8),
@@ -1403,19 +1603,25 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
+    0xf2800140, 0xff900f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf2900140, 0xffb00f50, "vmla%c.f16\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
+    0xf2800540, 0xff900f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf2900540, 0xffb00f50, "vmls%c.f16\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
+    0xf2800940, 0xff900f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf2900940, 0xffb00f50, "vmul%c.f16\t%12-15,22D, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1425,15 +1631,21 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+    0xf3800140, 0xff900f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf3900140, 0xffb00f50, "vmla%c.f16\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+    0xf3800540, 0xff900f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf3900540, 0xffb00f50, "vmls%c.f16\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
-    0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+    0xf3800940, 0xff900f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
+  {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST),
+    0xf3900940, 0xffb00f50, "vmul%c.f16\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1447,6 +1659,19 @@ static const struct opcode32 neon_opcodes[] =
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
     0xf2800a40, 0xfe800f50,
     "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf2800e40, 0xff800f50,
+   "vqrdmlah%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf2800f40, 0xff800f50,
+   "vqrdmlsh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf3800e40, 0xff800f50,
+   "vqrdmlah%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
+  {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA),
+    0xf3800f40, 0xff800f50,
+   "vqrdmlsh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"
+  },
 
   /* Element and structure load/store.  */
   {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
@@ -1519,10 +1744,10 @@ static const struct opcode32 neon_opcodes[] =
    %<bitfield>{r|R}u    as %{r|R} but if matches the other %u field then is UNPREDICTABLE
    %<bitfield>{r|R}U    as %{r|R} but if matches the other %U field then is UNPREDICTABLE
    %<bitfield>d                print the bitfield in decimal
-   %<bitfield>W         print the bitfield plus one in decimal 
+   %<bitfield>W         print the bitfield plus one in decimal
    %<bitfield>x                print the bitfield in hex
    %<bitfield>X                print the bitfield as 1 hex digit without leading "0x"
-   
+
    %<bitfield>'c       print specified char iff bitfield is all ones
    %<bitfield>`c       print specified char iff bitfield is all zeroes
    %<bitfield>?ab...    select from array of values in big endian order
@@ -1555,39 +1780,44 @@ static const struct opcode32 arm_opcodes[] =
     0x00a00090, 0x0fa000f0,
     "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
 
+  /* V8.2 RAS extension instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
+    0xe320f010, 0xffffffff, "esb"},
+
   /* V8 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
     0x0320f005, 0x0fffffff, "sevl"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  /* Defined in V8 but is in NOP space so available to all arch.  */
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
     0xe1000070, 0xfff000f0, "hlt\t0x%16-19X%12-15X%8-11X%0-3X"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS),
     0x01800e90, 0x0ff00ff0, "stlex%c\t%12-15r, %0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01900e9f, 0x0ff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
     0x01a00e90, 0x0ff00ff0, "stlexd%c\t%12-15r, %0-3r, %0-3T, [%16-19R]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
     0x01b00e9f, 0x0ff00fff, "ldaexd%c\t%12-15r, %12-15T, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01c00e90, 0x0ff00ff0, "stlexb%c\t%12-15r, %0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01d00e9f, 0x0ff00fff, "ldaexb%c\t%12-15r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01e00e90, 0x0ff00ff0, "stlexh%c\t%12-15r, %0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01f00e9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x0180fc90, 0x0ff0fff0, "stl%c\t%0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01900c9f, 0x0ff00fff, "lda%c\t%12-15r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01c0fc90, 0x0ff0fff0, "stlb%c\t%0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01d00c9f, 0x0ff00fff, "ldab%c\t%12-15r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
     0x01e0fc90, 0x0ff0fff0, "stlh%c\t%0-3r, [%16-19R]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
-    0x01f00c9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
+  {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS),
+    0x01f00c9f, 0x0ff00fff, "ldah%c\t%12-15r, [%16-19R]"},
   /* CRC32 instructions.  */
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
     0xe1000040, 0xfff00ff0, "crc32b\t%12-15R, %16-19R, %0-3R"},
@@ -1602,6 +1832,10 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
     0xe1400240, 0xfff00ff0, "crc32cw\t%12-15R, %16-19R, %0-3R"},
 
+  /* Privileged Access Never extension instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
+    0xf1100000, 0xfffffdff, "setpan\t#%9-9d"},
+
   /* Virtualization Extension instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT), 0x0160006e, 0x0fffffff, "eret%c"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT), 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
@@ -1615,6 +1849,11 @@ static const struct opcode32 arm_opcodes[] =
   /* MP Extension instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_MP), 0xf410f000, 0xfc70f000, "pldw\t%a"},
 
+  /* Speculation Barriers.  */
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V3), 0xe320f014, 0xffffffff, "csdb"},
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V3), 0xf57ff040, 0xffffffff, "ssbb"},
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V3), 0xf57ff044, 0xffffffff, "pssbb"},
+
   /* V7 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf450f000, 0xfd70f000, "pli\t%P"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
@@ -1623,6 +1862,8 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff050, 0xfffffff0, "dmb\t%U"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff040, 0xfffffff0, "dsb\t%U"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff060, 0xfffffff0, "isb\t%U"},
+   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7),
+    0x0320f000, 0x0fffffff, "nop%c\t{%0-7d}"},
 
   /* ARM V6T2 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
@@ -1639,9 +1880,9 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
 
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
@@ -1668,6 +1909,9 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
     0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
 
+  /* ARMv8.5-A instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB), 0xf57ff070, 0xffffffff, "sb"},
+
   /* ARM V6K NOP hints.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
     0x0320f001, 0x0fffffff, "yield%c"},
@@ -2100,11 +2344,11 @@ static const struct opcode32 arm_opcodes[] =
     0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
 
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
-    0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
+    0x03300000, 0x0ff00000, "teq%p%c\t%16-19r, %o"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
-    0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
+    0x01300000, 0x0ff00010, "teq%p%c\t%16-19r, %o"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
-    0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
+    0x01300010, 0x0ff00010, "teq%p%c\t%16-19R, %o"},
 
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
     0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
@@ -2253,6 +2497,8 @@ static const struct opcode32 arm_opcodes[] =
     0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
 
   /* The rest.  */
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V7),
+    0x03200000, 0x0fff00ff, "nop%c\t{%0-7d}" UNPREDICTABLE_INSTRUCTION},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V1),
     0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
   {ARM_FEATURE_CORE_LOW (0),
@@ -2290,9 +2536,14 @@ static const struct opcode16 thumb_opcodes[] =
 {
   /* Thumb instructions.  */
 
+  /* ARMv8-M Security Extensions instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0x4784, 0xff87, "blxns\t%3-6r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0x4704, 0xff87, "bxns\t%3-6r"},
+
   /* ARM V8 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),  0xbf50, 0xffff, "sevl%c"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),  0xba80, 0xffc0, "hlt\t%0-5x"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),  0xb610, 0xfff7, "setpan\t#%3-3d"},
 
   /* ARM V6K no-argument instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6K), 0xbf00, 0xffff, "nop%c"},
@@ -2303,8 +2554,10 @@ static const struct opcode16 thumb_opcodes[] =
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6K), 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
 
   /* ARM V6T2 instructions.  */
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
+    0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
+    0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xbf00, 0xff00, "it%I%X"},
 
   /* ARM V6.  */
@@ -2460,6 +2713,9 @@ static const struct opcode16 thumb_opcodes[] =
 
        %E              print the lsb and width fields of a bfc/bfi instruction
        %F              print the lsb and width fields of a sbfx/ubfx instruction
+       %G              print a fallback offset for Branch Future instructions
+       %W              print an offset for BF instruction
+       %Y              print an offset for BFL instruction
        %b              print a conditional branch offset
        %B              print an unconditional branch offset
        %s              print the shift field of an SSAT instruction
@@ -2471,10 +2727,11 @@ static const struct opcode16 thumb_opcodes[] =
        %X              print "\t; unpredictable <IT:code>" if conditional
 
        %<bitfield>d    print bitfield in decimal
+       %<bitfield>D     print bitfield plus one in decimal
        %<bitfield>W    print bitfield*4 in decimal
        %<bitfield>r    print bitfield as an ARM register
        %<bitfield>R    as %<>r but r15 is UNPREDICTABLE
-       %<bitfield>S    as %<>R but r13 is UNPREDICTABLE
+       %<bitfield>S    as %<>r but r13 and r15 is UNPREDICTABLE
        %<bitfield>c    print bitfield as a condition code
 
        %<bitfield>'c   print specified char iff bitfield is all ones
@@ -2491,6 +2748,30 @@ static const struct opcode16 thumb_opcodes[] =
    makes heavy use of special-case bit patterns.  */
 static const struct opcode32 thumb32_opcodes[] =
 {
+  /* Armv8.1-M Mainline instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf040e001, 0xf860f001, "bf%c\t%G, %W"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf060e001, 0xf8f0f001, "bfx%c\t%G, %16-19S"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf070e001, 0xf8f0f001, "bflx%c\t%G, %16-19S"},
+
+
+  /* ARMv8-M and ARMv8-M Security Extensions instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0xe97fe97f, 0xffffffff, "sg"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M),
+    0xe840f000, 0xfff0f0ff, "tt\t%8-11r, %16-19r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M),
+    0xe840f040, 0xfff0f0ff, "ttt\t%8-11r, %16-19r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M),
+    0xe840f080, 0xfff0f0ff, "tta\t%8-11r, %16-19r"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M),
+    0xe840f0c0, 0xfff0f0ff, "ttat\t%8-11r, %16-19r"},
+
+  /* ARM V8.2 RAS extension instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
+    0xf3af8010, 0xffffffff, "esb"},
+
   /* V8 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V8),
     0xf3af8005, 0xffffffff, "sevl%c.w"},
@@ -2527,17 +2808,22 @@ static const struct opcode32 thumb32_opcodes[] =
 
   /* CRC32 instructions.  */
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11S, %16-19S, %0-3S"},
+    0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11S, %16-19S, %0-3S"},
+    0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11S, %16-19S, %0-3S"},
+    0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11S, %16-19S, %0-3S"},
+    0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11S, %16-19S, %0-3S"},
+    0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
-    0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11S, %16-19S, %0-3S"},
+    0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11R, %16-19R, %0-3R"},
+
+  /* Speculation Barriers.  */
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3af8014, 0xffffffff, "csdb"},
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3bf8f40, 0xffffffff, "ssbb"},
+  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3bf8f44, 0xffffffff, "pssbb"},
 
   /* V7 instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf910f000, 0xff70f000, "pli%c\t%a"},
@@ -2562,6 +2848,9 @@ static const struct opcode32 thumb32_opcodes[] =
   /* Security extension instructions.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),  0xf7f08000, 0xfff0f000, "smc%c\t%K"},
 
+  /* ARMv8.5-A instructions.  */
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB), 0xf3bf8f70, 0xffffffff, "sb"},
+
   /* Instructions defined in the basic V6T2 set.  */
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3af8000, 0xffffffff, "nop%c.w"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3af8001, 0xffffffff, "yield%c.w"},
@@ -2572,7 +2861,7 @@ static const struct opcode32 thumb32_opcodes[] =
     0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf7f0a000, 0xfff0f000, "udf%c.w\t%H"},
 
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xf3bf8f2f, 0xffffffff, "clrex%c"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
@@ -2600,9 +2889,9 @@ static const struct opcode32 thumb32_opcodes[] =
     0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
@@ -2620,7 +2909,7 @@ static const struct opcode32 thumb32_opcodes[] =
     0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
@@ -2728,10 +3017,10 @@ static const struct opcode32 thumb32_opcodes[] =
     0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
-    0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
+    0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4D, %16-19r"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
@@ -2796,7 +3085,7 @@ static const struct opcode32 thumb32_opcodes[] =
     0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
@@ -2839,16 +3128,16 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
-    0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
+    0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4D, %16-19r%s"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
@@ -2870,7 +3159,7 @@ static const struct opcode32 thumb32_opcodes[] =
     0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
-  {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M),
     0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
   {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2),
     0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
@@ -2963,18 +3252,20 @@ arm_regname;
 
 static const arm_regname regnames[] =
 {
-  { "raw" , "Select raw register names",
+  { "reg-names-raw", N_("Select raw register names"),
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
-  { "gcc",  "Select register names used by GCC",
+  { "reg-names-gcc", N_("Select register names used by GCC"),
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
-  { "std",  "Select register names used in ARM's ISA documentation",
+  { "reg-names-std", N_("Select register names used in ARM's ISA documentation"),
     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
-  { "apcs", "Select register names used in the APCS",
+  { "force-thumb", N_("Assume all insns are Thumb insns"), {NULL} },
+  { "no-force-thumb", N_("Examine preceding label to determine an insn's type"), {NULL} },
+  { "reg-names-apcs", N_("Select register names used in the APCS"),
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
-  { "atpcs", "Select register names used in the ATPCS",
+  { "reg-names-atpcs", N_("Select register names used in the ATPCS"),
     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
-  { "special-atpcs", "Select special register names used in the ATPCS",
-    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
+  { "reg-names-special-atpcs", N_("Select special register names used in the ATPCS"),
+    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
 };
 
 static const char *const iwmmxt_wwnames[] =
@@ -3000,7 +3291,7 @@ static const char *const iwmmxt_cregnames[] =
 /* Default to GCC register name set.  */
 static unsigned int regname_selected = 1;
 
-#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
+#define NUM_ARM_OPTIONS   ARRAY_SIZE (regnames)
 #define arm_regnames      regnames[regname_selected].reg_names
 
 static bfd_boolean force_thumb = FALSE;
@@ -3019,31 +3310,6 @@ static bfd_vma ifthen_address;
 
 \f
 /* Functions.  */
-int
-get_arm_regname_num_options (void)
-{
-  return NUM_ARM_REGNAMES;
-}
-
-int
-set_arm_regname_option (int option)
-{
-  int old = regname_selected;
-  regname_selected = option;
-  return old;
-}
-
-int
-get_arm_regnames (int option,
-                 const char **setname,
-                 const char **setdescription,
-                 const char *const **register_names)
-{
-  *setname = regnames[option].name;
-  *setdescription = regnames[option].description;
-  *register_names = regnames[option].reg_names;
-  return 16;
-}
 
 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
    Returns pointer to following character of the format string and
@@ -3058,8 +3324,8 @@ arm_decode_bitfield (const char *ptr,
 {
   unsigned long value = 0;
   int width = 0;
-  
-  do 
+
+  do
     {
       int start, end;
       int bits;
@@ -3149,10 +3415,11 @@ print_insn_coprocessor (bfd_vma pc,
   unsigned long mask;
   unsigned long value = 0;
   int cond;
+  int cp_num;
   struct arm_private_data *private_data = info->private_data;
   arm_feature_set allowed_arches = ARM_ARCH_NONE;
 
-  ARM_FEATURE_COPY (allowed_arches, private_data->features);
+  allowed_arches = private_data->features;
 
   for (insn = coprocessor_opcodes; insn->assembler; insn++)
     {
@@ -3178,7 +3445,7 @@ print_insn_coprocessor (bfd_vma pc,
            continue;
 
          case SENTINEL_GENERIC_START:
-           ARM_FEATURE_COPY (allowed_arches, private_data->features);
+           allowed_arches = private_data->features;
            continue;
 
          default:
@@ -3187,6 +3454,8 @@ print_insn_coprocessor (bfd_vma pc,
 
       mask = insn->mask;
       value = insn->value;
+      cp_num = (given >> 8) & 0xf;
+
       if (thumb)
        {
          /* The high 4 bits are 0xe for Arm conditional instructions, and
@@ -3222,6 +3491,26 @@ print_insn_coprocessor (bfd_vma pc,
       if (! ARM_CPU_HAS_FEATURE (insn->arch, allowed_arches))
        continue;
 
+      if (insn->value == 0xfe000010     /* mcr2  */
+         || insn->value == 0xfe100010  /* mrc2  */
+         || insn->value == 0xfc100000  /* ldc2  */
+         || insn->value == 0xfc000000) /* stc2  */
+       {
+         if (cp_num == 9 || cp_num == 10 || cp_num == 11)
+           is_unpredictable = TRUE;
+       }
+      else if (insn->value == 0x0e000000     /* cdp  */
+              || insn->value == 0xfe000000  /* cdp2  */
+              || insn->value == 0x0e000010  /* mcr  */
+              || insn->value == 0x0e100010  /* mrc  */
+              || insn->value == 0x0c100000  /* ldc  */
+              || insn->value == 0x0c000000) /* stc  */
+       {
+         /* Floating-point instructions.  */
+         if (cp_num == 9 || cp_num == 10 || cp_num == 11)
+           continue;
+       }
+
       for (c = insn->assembler; *c; c++)
        {
          if (*c == '%')
@@ -3235,14 +3524,20 @@ print_insn_coprocessor (bfd_vma pc,
                case 'A':
                  {
                    int rn = (given >> 16) & 0xf;
-                   bfd_vma offset = given & 0xff;
+                   bfd_vma offset = given & 0xff;
 
                    func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
                    if (PRE_BIT_SET || WRITEBACK_BIT_SET)
                      {
                        /* Not unindexed.  The offset is scaled.  */
-                       offset = offset * 4;
+                       if (cp_num == 9)
+                         /* vldr.16/vstr.16 will shift the address
+                            left by 1 bit only.  */
+                         offset = offset * 2;
+                       else
+                         offset = offset * 4;
+
                        if (NEGATIVE_BIT_SET)
                          offset = - offset;
                        if (rn != 15)
@@ -3284,10 +3579,10 @@ print_insn_coprocessor (bfd_vma pc,
                        func (stream, "\t; ");
                        /* For unaligned PCs, apply off-by-alignment
                           correction.  */
-                       info->print_address_func (offset + pc 
+                       info->print_address_func (offset + pc
                                                  + info->bytes_per_chunk * 2
                                                  - (pc & 3),
-                                                 info);
+                                                 info);
                      }
                  }
                  break;
@@ -3312,6 +3607,9 @@ print_insn_coprocessor (bfd_vma pc,
 
                  /* Fall through.  */
                case 'c':
+                 if (cond != COND_UNCOND && cp_num == 9)
+                   is_unpredictable = TRUE;
+
                  func (stream, "%s", arm_conditional[cond]);
                  break;
 
@@ -3327,7 +3625,7 @@ print_insn_coprocessor (bfd_vma pc,
 
                    /* Is ``imm'' a negative number?  */
                    if (imm & 0x40)
-                     imm |= (-1 << 7);
+                     imm -= 0x80;
 
                    func (stream, "%d", imm);
                  }
@@ -3429,10 +3727,15 @@ print_insn_coprocessor (bfd_vma pc,
                          }
                        func (stream, "%s", arm_regnames[value]);
                        break;
+                     case 'V':
+                       if (given & (1 << 6))
+                         goto Q;
+                       /* FALLTHROUGH */
                      case 'D':
                        func (stream, "d%ld", value);
                        break;
                      case 'Q':
+                     Q:
                        if (value & 1)
                          func (stream, "<illegal reg q%ld.5>", value >> 1);
                        else
@@ -3442,6 +3745,36 @@ print_insn_coprocessor (bfd_vma pc,
                        func (stream, "%ld", value);
                        value_in_comment = value;
                        break;
+                     case 'E':
+                        {
+                         /* Converts immediate 8 bit back to float value.  */
+                         unsigned floatVal = (value & 0x80) << 24
+                           | (value & 0x3F) << 19
+                           | ((value & 0x40) ? (0xF8 << 22) : (1 << 30));
+
+                         /* Quarter float have a maximum value of 31.0.
+                            Get floating point value multiplied by 1e7.
+                            The maximum value stays in limit of a 32-bit int.  */
+                         unsigned decVal =
+                           (78125 << (((floatVal >> 23) & 0xFF) - 124)) *
+                           (16 + (value & 0xF));
+
+                         if (!(decVal % 1000000))
+                           func (stream, "%ld\t; 0x%08x %c%u.%01u", value,
+                                 floatVal, value & 0x80 ? '-' : ' ',
+                                 decVal / 10000000,
+                                 decVal % 10000000 / 1000000);
+                         else if (!(decVal % 10000))
+                           func (stream, "%ld\t; 0x%08x %c%u.%03u", value,
+                                 floatVal, value & 0x80 ? '-' : ' ',
+                                 decVal / 10000000,
+                                 decVal % 10000000 / 10000);
+                         else
+                           func (stream, "%ld\t; 0x%08x %c%u.%07u", value,
+                                 floatVal, value & 0x80 ? '-' : ' ',
+                                 decVal / 10000000, decVal % 10000000);
+                         break;
+                       }
                      case 'k':
                        {
                          int from = (given & (1 << 7)) ? 32 : 16;
@@ -3516,190 +3849,190 @@ print_insn_coprocessor (bfd_vma pc,
                      default:
                        abort ();
                      }
-                   break;
-
-                 case 'y':
-                 case 'z':
-                   {
-                     int single = *c++ == 'y';
-                     int regno;
+                 }
+                 break;
 
-                     switch (*c)
-                       {
-                       case '4': /* Sm pair */
-                       case '0': /* Sm, Dm */
-                         regno = given & 0x0000000f;
-                         if (single)
-                           {
-                             regno <<= 1;
-                             regno += (given >> 5) & 1;
-                           }
-                         else
-                           regno += ((given >> 5) & 1) << 4;
-                         break;
+               case 'y':
+               case 'z':
+                 {
+                   int single = *c++ == 'y';
+                   int regno;
 
-                       case '1': /* Sd, Dd */
-                         regno = (given >> 12) & 0x0000000f;
-                         if (single)
-                           {
-                             regno <<= 1;
-                             regno += (given >> 22) & 1;
-                           }
-                         else
-                           regno += ((given >> 22) & 1) << 4;
-                         break;
+                   switch (*c)
+                     {
+                     case '4': /* Sm pair */
+                     case '0': /* Sm, Dm */
+                       regno = given & 0x0000000f;
+                       if (single)
+                         {
+                           regno <<= 1;
+                           regno += (given >> 5) & 1;
+                         }
+                       else
+                         regno += ((given >> 5) & 1) << 4;
+                       break;
 
-                       case '2': /* Sn, Dn */
-                         regno = (given >> 16) & 0x0000000f;
-                         if (single)
-                           {
-                             regno <<= 1;
-                             regno += (given >> 7) & 1;
-                           }
-                         else
-                           regno += ((given >> 7) & 1) << 4;
-                         break;
+                     case '1': /* Sd, Dd */
+                       regno = (given >> 12) & 0x0000000f;
+                       if (single)
+                         {
+                           regno <<= 1;
+                           regno += (given >> 22) & 1;
+                         }
+                       else
+                         regno += ((given >> 22) & 1) << 4;
+                       break;
 
-                       case '3': /* List */
-                         func (stream, "{");
-                         regno = (given >> 12) & 0x0000000f;
-                         if (single)
-                           {
-                             regno <<= 1;
-                             regno += (given >> 22) & 1;
-                           }
-                         else
-                           regno += ((given >> 22) & 1) << 4;
-                         break;
+                     case '2': /* Sn, Dn */
+                       regno = (given >> 16) & 0x0000000f;
+                       if (single)
+                         {
+                           regno <<= 1;
+                           regno += (given >> 7) & 1;
+                         }
+                       else
+                         regno += ((given >> 7) & 1) << 4;
+                       break;
 
-                       default:
-                         abort ();
-                       }
+                     case '3': /* List */
+                       func (stream, "{");
+                       regno = (given >> 12) & 0x0000000f;
+                       if (single)
+                         {
+                           regno <<= 1;
+                           regno += (given >> 22) & 1;
+                         }
+                       else
+                         regno += ((given >> 22) & 1) << 4;
+                       break;
 
-                     func (stream, "%c%d", single ? 's' : 'd', regno);
+                     default:
+                       abort ();
+                     }
 
-                     if (*c == '3')
-                       {
-                         int count = given & 0xff;
+                   func (stream, "%c%d", single ? 's' : 'd', regno);
 
-                         if (single == 0)
-                           count >>= 1;
+                   if (*c == '3')
+                     {
+                       int count = given & 0xff;
 
-                         if (--count)
-                           {
-                             func (stream, "-%c%d",
-                                   single ? 's' : 'd',
-                                   regno + count);
-                           }
+                       if (single == 0)
+                         count >>= 1;
 
-                         func (stream, "}");
-                       }
-                     else if (*c == '4')
-                       func (stream, ", %c%d", single ? 's' : 'd',
-                             regno + 1);
-                   }
-                   break;
+                       if (--count)
+                         {
+                           func (stream, "-%c%d",
+                                 single ? 's' : 'd',
+                                 regno + count);
+                         }
 
-                 case 'L':
-                   switch (given & 0x00400100)
-                     {
-                     case 0x00000000: func (stream, "b"); break;
-                     case 0x00400000: func (stream, "h"); break;
-                     case 0x00000100: func (stream, "w"); break;
-                     case 0x00400100: func (stream, "d"); break;
-                     default:
-                       break;
+                       func (stream, "}");
                      }
-                   break;
+                   else if (*c == '4')
+                     func (stream, ", %c%d", single ? 's' : 'd',
+                           regno + 1);
+                 }
+                 break;
 
-                 case 'Z':
+               case 'L':
+                 switch (given & 0x00400100)
                    {
-                     /* given (20, 23) | given (0, 3) */
-                     value = ((given >> 16) & 0xf0) | (given & 0xf);
-                     func (stream, "%d", (int) value);
+                   case 0x00000000: func (stream, "b"); break;
+                   case 0x00400000: func (stream, "h"); break;
+                   case 0x00000100: func (stream, "w"); break;
+                   case 0x00400100: func (stream, "d"); break;
+                   default:
+                     break;
                    }
-                   break;
+                 break;
 
-                 case 'l':
-                   /* This is like the 'A' operator, except that if
-                      the width field "M" is zero, then the offset is
-                      *not* multiplied by four.  */
-                   {
-                     int offset = given & 0xff;
-                     int multiplier = (given & 0x00000100) ? 4 : 1;
+               case 'Z':
+                 {
+                   /* given (20, 23) | given (0, 3) */
+                   value = ((given >> 16) & 0xf0) | (given & 0xf);
+                   func (stream, "%d", (int) value);
+                 }
+                 break;
 
-                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+               case 'l':
+                 /* This is like the 'A' operator, except that if
+                    the width field "M" is zero, then the offset is
+                    *not* multiplied by four.  */
+                 {
+                   int offset = given & 0xff;
+                   int multiplier = (given & 0x00000100) ? 4 : 1;
 
-                     if (multiplier > 1)
-                       {
-                         value_in_comment = offset * multiplier;
-                         if (NEGATIVE_BIT_SET)
-                           value_in_comment = - value_in_comment;
-                       }
+                   func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                     if (offset)
-                       {
-                         if (PRE_BIT_SET)
-                           func (stream, ", #%s%d]%s",
-                                 NEGATIVE_BIT_SET ? "-" : "",
-                                 offset * multiplier,
-                                 WRITEBACK_BIT_SET ? "!" : "");
-                         else
-                           func (stream, "], #%s%d",
-                                 NEGATIVE_BIT_SET ? "-" : "",
-                                 offset * multiplier);
-                       }
-                     else
-                       func (stream, "]");
-                   }
-                   break;
+                   if (multiplier > 1)
+                     {
+                       value_in_comment = offset * multiplier;
+                       if (NEGATIVE_BIT_SET)
+                         value_in_comment = - value_in_comment;
+                     }
 
-                 case 'r':
-                   {
-                     int imm4 = (given >> 4) & 0xf;
-                     int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
-                     int ubit = ! NEGATIVE_BIT_SET;
-                     const char *rm = arm_regnames [given & 0xf];
-                     const char *rn = arm_regnames [(given >> 16) & 0xf];
+                   if (offset)
+                     {
+                       if (PRE_BIT_SET)
+                         func (stream, ", #%s%d]%s",
+                               NEGATIVE_BIT_SET ? "-" : "",
+                               offset * multiplier,
+                               WRITEBACK_BIT_SET ? "!" : "");
+                       else
+                         func (stream, "], #%s%d",
+                               NEGATIVE_BIT_SET ? "-" : "",
+                               offset * multiplier);
+                     }
+                   else
+                     func (stream, "]");
+                 }
+                 break;
 
-                     switch (puw_bits)
-                       {
-                       case 1:
-                       case 3:
-                         func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
-                         if (imm4)
-                           func (stream, ", lsl #%d", imm4);
-                         break;
+               case 'r':
+                 {
+                   int imm4 = (given >> 4) & 0xf;
+                   int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
+                   int ubit = ! NEGATIVE_BIT_SET;
+                   const char *rm = arm_regnames [given & 0xf];
+                   const char *rn = arm_regnames [(given >> 16) & 0xf];
 
-                       case 4:
-                       case 5:
-                       case 6:
-                       case 7:
-                         func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
-                         if (imm4 > 0)
-                           func (stream, ", lsl #%d", imm4);
-                         func (stream, "]");
-                         if (puw_bits == 5 || puw_bits == 7)
-                           func (stream, "!");
-                         break;
+                   switch (puw_bits)
+                     {
+                     case 1:
+                     case 3:
+                       func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
+                       if (imm4)
+                         func (stream, ", lsl #%d", imm4);
+                       break;
 
-                       default:
-                         func (stream, "INVALID");
-                       }
-                   }
-                   break;
+                     case 4:
+                     case 5:
+                     case 6:
+                     case 7:
+                       func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
+                       if (imm4 > 0)
+                         func (stream, ", lsl #%d", imm4);
+                       func (stream, "]");
+                       if (puw_bits == 5 || puw_bits == 7)
+                         func (stream, "!");
+                       break;
 
-                 case 'i':
-                   {
-                     long imm5;
-                     imm5 = ((given & 0x100) >> 4) | (given & 0xf);
-                     func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
-                   }
-                   break;
+                     default:
+                       func (stream, "INVALID");
+                     }
+                 }
+                 break;
 
-                 default:
-                   abort ();
+               case 'i':
+                 {
+                   long imm5;
+                   imm5 = ((given & 0x100) >> 4) | (given & 0xf);
+                   func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
                  }
+                 break;
+
+               default:
+                 abort ();
                }
            }
          else
@@ -3841,7 +4174,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
       else
        return FALSE;
     }
-  
+
   for (insn = neon_opcodes; insn->assembler; insn++)
     {
       if ((given & insn->mask) == insn->value)
@@ -3872,7 +4205,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 
                    case 'A':
                      {
-                       static const unsigned char enc[16] = 
+                       static const unsigned char enc[16] =
                        {
                          0x4, 0x14, /* st4 0,1 */
                          0x4, /* st1 2 */
@@ -3894,7 +4227,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                        int n = enc[type] & 0xf;
                        int stride = (enc[type] >> 4) + 1;
                        int ix;
-                       
+
                        func (stream, "{");
                        if (stride > 1)
                          for (ix = 0; ix != n; ix++)
@@ -3913,7 +4246,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          func (stream, ", %s", arm_regnames[rm]);
                      }
                      break;
-                     
+
                    case 'B':
                      {
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
@@ -3929,7 +4262,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 
                         if (length > 1 && size > 0)
                           stride = (idx_align & (1 << size)) ? 2 : 1;
-                       
+
                         switch (length)
                           {
                           case 1:
@@ -3946,19 +4279,19 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                                 }
                               }
                             break;
-                          
+
                           case 2:
                             if (size == 2 && (idx_align & 2) != 0)
                               return FALSE;
                             align = (idx_align & 1) ? 16 << size : 0;
                             break;
-                          
+
                           case 3:
                             if ((size == 2 && (idx_align & 3) != 0)
                                 || (idx_align & 1) != 0)
                               return FALSE;
                             break;
-                          
+
                           case 4:
                             if (size == 2)
                               {
@@ -3969,11 +4302,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                             else
                               align = (idx_align & 1) ? 32 << size : 0;
                             break;
-                          
+
                           default:
                             abort ();
                           }
-                                
+
                        func (stream, "{");
                         for (i = 0; i < length; i++)
                           func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
@@ -3988,7 +4321,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          func (stream, ", %s", arm_regnames[rm]);
                      }
                      break;
-                     
+
                    case 'C':
                      {
                        int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
@@ -4000,12 +4333,12 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                        int n = type + 1;
                        int stride = ((given >> 5) & 0x1);
                        int ix;
-                       
+
                        if (stride && (n == 1))
                          n++;
                        else
                          stride++;
-                       
+
                        func (stream, "{");
                        if (stride > 1)
                          for (ix = 0; ix != n; ix++)
@@ -4032,18 +4365,18 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          func (stream, ", %s", arm_regnames[rm]);
                      }
                      break;
-                     
+
                    case 'D':
                      {
                        int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
                        int size = (given >> 20) & 3;
                        int reg = raw_reg & ((4 << size) - 1);
                        int ix = raw_reg >> size >> 2;
-                       
+
                        func (stream, "d%d[%d]", reg, ix);
                      }
                      break;
-                     
+
                    case 'E':
                      /* Neon encoded constant for mov, mvn, vorr, vbic.  */
                      {
@@ -4054,11 +4387,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                        unsigned shift;
                         int size = 0;
                         int isfloat = 0;
-                       
+
                        bits |= ((given >> 24) & 1) << 7;
                        bits |= ((given >> 16) & 7) << 4;
                        bits |= ((given >> 0) & 15) << 0;
-                       
+
                        if (cmode < 8)
                          {
                            shift = (cmode >> 1) & 3;
@@ -4085,7 +4418,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                                /* Bit replication into bytes.  */
                                int ix;
                                unsigned long mask;
-                               
+
                                value = 0;
                                 hival = 0;
                                for (ix = 7; ix >= 0; ix--)
@@ -4109,7 +4442,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          {
                            /* Floating point encoding.  */
                            int tmp;
-                           
+
                            value = (unsigned long)  (bits & 0x7f) << 19;
                            value |= (unsigned long) (bits & 0x80) << 24;
                            tmp = bits & 0x40 ? 0x3c : 0x40;
@@ -4129,7 +4462,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                           case 8:
                            func (stream, "#%ld\t; 0x%.2lx", value, value);
                             break;
-                          
+
                           case 16:
                             func (stream, "#%ld\t; 0x%.4lx", value, value);
                             break;
@@ -4139,24 +4472,24 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                               {
                                 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_to_double
                                   (& floatformat_ieee_single_little, valbytes,
                                   & fvalue);
-                                                                
+
                                 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
                                       value);
                               }
                             else
                               func (stream, "#%ld\t; 0x%.8lx",
-                                   (long) (((value & 0x80000000L) != 0) 
+                                   (long) (((value & 0x80000000L) != 0)
                                            ? value | ~0xffffffffL : value),
                                    value);
                             break;
@@ -4164,18 +4497,18 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                           case 64:
                             func (stream, "#0x%.8lx%.8lx", hival, value);
                             break;
-                          
+
                           default:
                             abort ();
                           }
                      }
                      break;
-                     
+
                    case 'F':
                      {
                        int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
                        int num = (given >> 8) & 0x3;
-                       
+
                        if (!num)
                          func (stream, "{d%d}", regno);
                        else if (num + regno >= 32)
@@ -4193,7 +4526,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                        unsigned long value;
 
                        c = arm_decode_bitfield (c, given, &value, &width);
-                       
+
                        switch (*c)
                          {
                          case 'r':
@@ -4206,7 +4539,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          case 'e':
                            func (stream, "%ld", (1ul << width) - value);
                            break;
-                           
+
                          case 'S':
                          case 'T':
                          case 'U':
@@ -4246,7 +4579,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                            else
                              func (stream, "q%ld", value >> 1);
                            break;
-                           
+
                          case '`':
                            c++;
                            if (value == 0)
@@ -4264,11 +4597,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          default:
                            abort ();
                          }
-                       break;
-
-                     default:
-                       abort ();
                      }
+                     break;
+
+                   default:
+                     abort ();
                    }
                }
              else
@@ -4289,20 +4622,20 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
 
 /* Return the name of a v7A special register.  */
 
-static const char * 
+static const char *
 banked_regname (unsigned reg)
 {
   switch (reg)
     {
       case 15: return "CPSR";
-      case 32: return "R8_usr"; 
+      case 32: return "R8_usr";
       case 33: return "R9_usr";
       case 34: return "R10_usr";
       case 35: return "R11_usr";
       case 36: return "R12_usr";
       case 37: return "SP_usr";
       case 38: return "LR_usr";
-      case 40: return "R8_fiq"; 
+      case 40: return "R8_fiq";
       case 41: return "R9_fiq";
       case 42: return "R10_fiq";
       case 43: return "R11_fiq";
@@ -4416,6 +4749,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 
                    case 'S':
                      allow_unpredictable = TRUE;
+                     /* Fall through.  */
                    case 's':
                       if ((given & 0x004f0000) == 0x004f0000)
                        {
@@ -4599,6 +4933,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          if (! ARM_CPU_HAS_FEATURE (private_data->features, \
                                                     arm_ext_v6))
                            func (stream, "p");
+                         else
+                           is_unpredictable = TRUE;
                        }
                      break;
 
@@ -4683,7 +5019,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        }
                      else
                        {
-                         func (stream, "%cPSR_", 
+                         func (stream, "%cPSR_",
                                (given & 0x00400000) ? 'S' : 'C');
                          if (given & 0x80000)
                            func (stream, "f");
@@ -4697,7 +5033,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'U':
-                     if ((given & 0xf0) == 0x60) 
+                     if ((given & 0xf0) == 0x60)
                        {
                          switch (given & 0xf)
                            {
@@ -4706,8 +5042,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                              func (stream, "#%d", (int) given & 0xf);
                              break;
                            }
-                       } 
-                     else 
+                       }
+                     else
                        {
                          const char * opt = data_barrier_option (given & 0xf);
                          if (opt != NULL)
@@ -4724,7 +5060,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        unsigned long value;
 
                        c = arm_decode_bitfield (c, given, &value, &width);
-                       
+
                        switch (*c)
                          {
                          case 'R':
@@ -4800,65 +5136,65 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          default:
                            abort ();
                          }
-                       break;
-
-                     case 'e':
-                       {
-                         int imm;
+                     }
+                     break;
 
-                         imm = (given & 0xf) | ((given & 0xfff00) >> 4);
-                         func (stream, "%d", imm);
-                         value_in_comment = imm;
-                       }
-                       break;
+                   case 'e':
+                     {
+                       int imm;
 
-                     case 'E':
-                       /* LSB and WIDTH fields of BFI or BFC.  The machine-
-                          language instruction encodes LSB and MSB.  */
-                       {
-                         long msb = (given & 0x001f0000) >> 16;
-                         long lsb = (given & 0x00000f80) >> 7;
-                         long w = msb - lsb + 1;
+                       imm = (given & 0xf) | ((given & 0xfff00) >> 4);
+                       func (stream, "%d", imm);
+                       value_in_comment = imm;
+                     }
+                     break;
 
-                         if (w > 0)
-                           func (stream, "#%lu, #%lu", lsb, w);
-                         else
-                           func (stream, "(invalid: %lu:%lu)", lsb, msb);
-                       }
-                       break;
+                   case 'E':
+                     /* LSB and WIDTH fields of BFI or BFC.  The machine-
+                        language instruction encodes LSB and MSB.  */
+                     {
+                       long msb = (given & 0x001f0000) >> 16;
+                       long lsb = (given & 0x00000f80) >> 7;
+                       long w = msb - lsb + 1;
 
-                     case 'R':
-                       /* Get the PSR/banked register name.  */
-                       {
-                         const char * name;
-                         unsigned sysm = (given & 0x004f0000) >> 16;
+                       if (w > 0)
+                         func (stream, "#%lu, #%lu", lsb, w);
+                       else
+                         func (stream, "(invalid: %lu:%lu)", lsb, msb);
+                     }
+                     break;
 
-                         sysm |= (given & 0x300) >> 4;
-                         name = banked_regname (sysm);
+                   case 'R':
+                     /* Get the PSR/banked register name.  */
+                     {
+                       const char * name;
+                       unsigned sysm = (given & 0x004f0000) >> 16;
 
-                         if (name != NULL)
-                           func (stream, "%s", name);
-                         else
-                           func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
-                       }
-                       break;
+                       sysm |= (given & 0x300) >> 4;
+                       name = banked_regname (sysm);
 
-                     case 'V':
-                       /* 16-bit unsigned immediate from a MOVT or MOVW
-                          instruction, encoded in bits 0:11 and 15:19.  */
-                       {
-                         long hi = (given & 0x000f0000) >> 4;
-                         long lo = (given & 0x00000fff);
-                         long imm16 = hi | lo;
+                       if (name != NULL)
+                         func (stream, "%s", name);
+                       else
+                         func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
+                     }
+                     break;
 
-                         func (stream, "#%lu", imm16);
-                         value_in_comment = imm16;
-                       }
-                       break;
+                   case 'V':
+                     /* 16-bit unsigned immediate from a MOVT or MOVW
+                        instruction, encoded in bits 0:11 and 15:19.  */
+                     {
+                       long hi = (given & 0x000f0000) >> 4;
+                       long lo = (given & 0x00000fff);
+                       long imm16 = hi | lo;
 
-                     default:
-                       abort ();
+                       func (stream, "#%lu", imm16);
+                       value_in_comment = imm16;
                      }
+                     break;
+
+                   default:
+                     abort ();
                    }
                }
              else
@@ -4874,7 +5210,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
          return;
        }
     }
-  abort ();
+  func (stream, UNKNOWN_INSTRUCTION_32BIT, (unsigned)given);
+  return;
 }
 
 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
@@ -5018,7 +5355,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
                   mask.  */
                if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
                  func (stream, "!");
-               break;
+               break;
 
              case 'b':
                /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
@@ -5145,7 +5482,8 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
       }
 
   /* No match.  */
-  abort ();
+  func (stream, UNKNOWN_INSTRUCTION_16BIT, (unsigned)given);
+  return;
 }
 
 /* Return the name of an V7M special register.  */
@@ -5155,20 +5493,31 @@ psr_name (int regno)
 {
   switch (regno)
     {
-    case 0: return "APSR";
-    case 1: return "IAPSR";
-    case 2: return "EAPSR";
-    case 3: return "PSR";
-    case 5: return "IPSR";
-    case 6: return "EPSR";
-    case 7: return "IEPSR";
-    case 8: return "MSP";
-    case 9: return "PSP";
-    case 16: return "PRIMASK";
-    case 17: return "BASEPRI";
-    case 18: return "BASEPRI_MAX";
-    case 19: return "FAULTMASK";
-    case 20: return "CONTROL";
+    case 0x0: return "APSR";
+    case 0x1: return "IAPSR";
+    case 0x2: return "EAPSR";
+    case 0x3: return "PSR";
+    case 0x5: return "IPSR";
+    case 0x6: return "EPSR";
+    case 0x7: return "IEPSR";
+    case 0x8: return "MSP";
+    case 0x9: return "PSP";
+    case 0xa: return "MSPLIM";
+    case 0xb: return "PSPLIM";
+    case 0x10: return "PRIMASK";
+    case 0x11: return "BASEPRI";
+    case 0x12: return "BASEPRI_MAX";
+    case 0x13: return "FAULTMASK";
+    case 0x14: return "CONTROL";
+    case 0x88: return "MSP_NS";
+    case 0x89: return "PSP_NS";
+    case 0x8a: return "MSPLIM_NS";
+    case 0x8b: return "PSPLIM_NS";
+    case 0x90: return "PRIMASK_NS";
+    case 0x91: return "BASEPRI_NS";
+    case 0x93: return "FAULTMASK_NS";
+    case 0x94: return "CONTROL_NS";
+    case 0x98: return "SP_NS";
     default: return "<unknown>";
     }
 }
@@ -5261,7 +5610,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  value_in_comment = imm;
                }
                break;
-                 
+
              case 'J':
                {
                  unsigned int imm = 0;
@@ -5443,7 +5792,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      if (off || !U)
                        {
                          func (stream, ", #%c%u", U ? '+' : '-', off * 4);
-                         value_in_comment = off * 4 * U ? 1 : -1;
+                         value_in_comment = off * 4 * (U ? 1 : -1);
                        }
                      func (stream, "]");
                      if (W)
@@ -5455,7 +5804,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      if (W)
                        {
                          func (stream, "#%c%u", U ? '+' : '-', off * 4);
-                         value_in_comment = off * 4 * U ? 1 : -1;
+                         value_in_comment = off * 4 * (U ? 1 : -1);
                        }
                      else
                        {
@@ -5526,6 +5875,47 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                }
                break;
 
+             case 'G':
+               {
+                 unsigned int boff = (((given & 0x07800000) >> 23) << 1);
+                 func (stream, "%x", boff);
+               }
+               break;
+
+             case 'W':
+               {
+                 unsigned int immA = (given & 0x001f0000u) >> 16;
+                 unsigned int immB = (given & 0x000007feu) >> 1;
+                 unsigned int immC = (given & 0x00000800u) >> 11;
+                 bfd_vma offset = 0;
+
+                 offset |= immA << 12;
+                 offset |= immB << 2;
+                 offset |= immC << 1;
+                 /* Sign extend.  */
+                 offset = (offset & 0x10000) ? offset - (1 << 17) : offset;
+
+                 info->print_address_func (pc + 4 + offset, info);
+               }
+               break;
+
+             case 'Y':
+               {
+                 unsigned int immA = (given & 0x007f0000u) >> 16;
+                 unsigned int immB = (given & 0x000007feu) >> 1;
+                 unsigned int immC = (given & 0x00000800u) >> 11;
+                 bfd_vma offset = 0;
+
+                 offset |= immA << 12;
+                 offset |= immB << 2;
+                 offset |= immC << 1;
+                 /* Sign extend.  */
+                 offset = (offset & 0x40000) ? offset - (1 << 19) : offset;
+
+                 info->print_address_func (pc + 4 + offset, info);
+               }
+               break;
+
              case 'b':
                {
                  unsigned int S = (given & 0x04000000u) >> 26;
@@ -5591,7 +5981,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                break;
 
              case 'U':
-               if ((given & 0xf0) == 0x60) 
+               if ((given & 0xf0) == 0x60)
                  {
                    switch (given & 0xf)
                      {
@@ -5601,7 +5991,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                              break;
                      }
                  }
-               else 
+               else
                  {
                    const char * opt = data_barrier_option (given & 0xf);
                    if (opt != NULL)
@@ -5632,7 +6022,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                    sysm |= (given & 0x30);
                    sysm |= (given & 0x00100000) >> 14;
                    name = banked_regname (sysm);
-                   
+
                    if (name != NULL)
                      func (stream, "%s", name);
                    else
@@ -5671,7 +6061,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  unsigned long val;
 
                  c = arm_decode_bitfield (c, given, &val, &width);
-                       
+
                  switch (*c)
                    {
                    case 'd':
@@ -5679,6 +6069,11 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      value_in_comment = val;
                      break;
 
+                   case 'D':
+                     func (stream, "%lu", val + 1);
+                     value_in_comment = val + 1;
+                     break;
+
                    case 'W':
                      func (stream, "%lu", val * 4);
                      value_in_comment = val * 4;
@@ -5705,7 +6100,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      if (val == ((1ul << width) - 1))
                        func (stream, "%c", *c);
                      break;
-                     
+
                    case '`':
                      c++;
                      if (val == 0)
@@ -5716,7 +6111,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      func (stream, "%c", c[(1 << width) - (int) val]);
                      c += 1 << width;
                      break;
-                     
+
                    case 'x':
                      func (stream, "0x%lx", val & 0xffffffffUL);
                      break;
@@ -5757,7 +6152,8 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
       }
 
   /* No match.  */
-  abort ();
+  func (stream, UNKNOWN_INSTRUCTION_32BIT, (unsigned)given);
+  return;
 }
 
 /* Print data bytes on INFO->STREAM.  */
@@ -5794,7 +6190,7 @@ arm_symbol_is_valid (asymbol * sym,
                     struct disassemble_info * info ATTRIBUTE_UNUSED)
 {
   const char * name;
-  
+
   if (sym == NULL)
     return FALSE;
 
@@ -5803,63 +6199,45 @@ arm_symbol_is_valid (asymbol * sym,
   return (name && *name != '$' && strncmp (name, "__tagsym$$", 10));
 }
 
-/* Parse an individual disassembler option.  */
+/* Parse the string of disassembler options.  */
 
-void
-parse_arm_disassembler_option (char *option)
+static void
+parse_arm_disassembler_options (const char *options)
 {
-  if (option == NULL)
-    return;
+  const char *opt;
 
-  if (CONST_STRNEQ (option, "reg-names-"))
+  FOR_EACH_DISASSEMBLER_OPTION (opt, options)
     {
-      int i;
-
-      option += 10;
-
-      for (i = NUM_ARM_REGNAMES; i--;)
-       if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
-         {
-           regname_selected = i;
-           break;
-         }
+      if (CONST_STRNEQ (opt, "reg-names-"))
+       {
+         unsigned int i;
+         for (i = 0; i < NUM_ARM_OPTIONS; i++)
+           if (disassembler_options_cmp (opt, regnames[i].name) == 0)
+             {
+               regname_selected = i;
+               break;
+             }
 
-      if (i < 0)
-       /* XXX - should break 'option' at following delimiter.  */
-       fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
+         if (i >= NUM_ARM_OPTIONS)
+           /* xgettext: c-format */
+           opcodes_error_handler (_("unrecognised register name set: %s"),
+                                  opt);
+       }
+      else if (CONST_STRNEQ (opt, "force-thumb"))
+       force_thumb = 1;
+      else if (CONST_STRNEQ (opt, "no-force-thumb"))
+       force_thumb = 0;
+      else
+       /* xgettext: c-format */
+       opcodes_error_handler (_("unrecognised disassembler option: %s"), opt);
     }
-  else if (CONST_STRNEQ (option, "force-thumb"))
-    force_thumb = 1;
-  else if (CONST_STRNEQ (option, "no-force-thumb"))
-    force_thumb = 0;
-  else
-    /* XXX - should break 'option' at following delimiter.  */
-    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
 
   return;
 }
 
-/* Parse the string of disassembler options, spliting it at whitespaces
-   or commas.  (Whitespace separators supported for backwards compatibility).  */
-
-static void
-parse_disassembler_options (char *options)
-{
-  if (options == NULL)
-    return;
-
-  while (*options)
-    {
-      parse_arm_disassembler_option (options);
-
-      /* Skip forward to next seperator.  */
-      while ((*options) && (! ISSPACE (*options)) && (*options != ','))
-       ++ options;
-      /* Skip forward past seperators.  */
-      while (ISSPACE (*options) || (*options == ','))
-       ++ options;      
-    }
-}
+static bfd_boolean
+mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info,
+                        enum map_type *map_symbol);
 
 /* Search back through the insn stream to determine if this instruction is
    conditionally executed.  */
@@ -5923,9 +6301,15 @@ find_ifthen_state (bfd_vma pc,
        }
       if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
        {
-         /* This could be an IT instruction.  */
-         seen_it = insn;
-         it_count = count >> 1;
+         enum map_type type = MAP_ARM;
+         bfd_boolean found = mapping_symbol_for_insn (addr, info, &type);
+
+         if (!found || (found && type == MAP_THUMB))
+           {
+             /* This could be an IT instruction.  */
+             seen_it = insn;
+             it_count = count >> 1;
+           }
        }
       if ((insn & 0xf800) >= 0xe800)
        count++;
@@ -5999,7 +6383,8 @@ get_sym_code_type (struct disassemble_info *info,
   /* If the symbol has function type then use that.  */
   if (type == STT_FUNC || type == STT_GNU_IFUNC)
     {
-      if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
+      if (ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal)
+         == ST_BRANCH_TO_THUMB)
        *map_type = MAP_THUMB;
       else
        *map_type = MAP_ARM;
@@ -6009,9 +6394,136 @@ get_sym_code_type (struct disassemble_info *info,
   return FALSE;
 }
 
+/* Search the mapping symbol state for instruction at pc.  This is only
+   applicable for elf target.
+
+   There is an assumption Here, info->private_data contains the correct AND
+   up-to-date information about current scan process.  The information will be
+   used to speed this search process.
+
+   Return TRUE if the mapping state can be determined, and map_symbol
+   will be updated accordingly.  Otherwise, return FALSE.  */
+
+static bfd_boolean
+mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info,
+                        enum map_type *map_symbol)
+{
+  bfd_vma addr, section_vma = 0;
+  int n, last_sym = -1;
+  bfd_boolean found = FALSE;
+  bfd_boolean can_use_search_opt_p = FALSE;
+
+  /* Default to DATA.  A text section is required by the ABI to contain an
+     INSN mapping symbol at the start.  A data section has no such
+     requirement, hence if no mapping symbol is found the section must
+     contain only data.  This however isn't very useful if the user has
+     fully stripped the binaries.  If this is the case use the section
+     attributes to determine the default.  If we have no section default to
+     INSN as well, as we may be disassembling some raw bytes on a baremetal
+     HEX file or similar.  */
+  enum map_type type = MAP_DATA;
+  if ((info->section && info->section->flags & SEC_CODE) || !info->section)
+    type = MAP_ARM;
+  struct arm_private_data *private_data;
+
+  if (info->private_data == NULL
+      || bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour)
+    return FALSE;
+
+  private_data = info->private_data;
+
+  /* First, look for mapping symbols.  */
+  if (info->symtab_size != 0)
+  {
+    if (pc <= private_data->last_mapping_addr)
+      private_data->last_mapping_sym = -1;
+
+    /* Start scanning at the start of the function, or wherever
+       we finished last time.  */
+    n = info->symtab_pos + 1;
+
+    /* If the last stop offset is different from the current one it means we
+       are disassembling a different glob of bytes.  As such the optimization
+       would not be safe and we should start over.  */
+    can_use_search_opt_p
+      = private_data->last_mapping_sym >= 0
+       && info->stop_offset == private_data->last_stop_offset;
+
+    if (n >= private_data->last_mapping_sym && can_use_search_opt_p)
+      n = private_data->last_mapping_sym;
+
+    /* Look down while we haven't passed the location being disassembled.
+       The reason for this is that there's no defined order between a symbol
+       and an mapping symbol that may be at the same address.  We may have to
+       look at least one position ahead.  */
+    for (; n < info->symtab_size; n++)
+      {
+       addr = bfd_asymbol_value (info->symtab[n]);
+       if (addr > pc)
+         break;
+       if (get_map_sym_type (info, n, &type))
+         {
+           last_sym = n;
+           found = TRUE;
+         }
+      }
+
+    if (!found)
+      {
+       n = info->symtab_pos;
+       if (n >= private_data->last_mapping_sym && can_use_search_opt_p)
+         n = private_data->last_mapping_sym;
+
+       /* No mapping symbol found at this address.  Look backwards
+          for a preceeding one, but don't go pass the section start
+          otherwise a data section with no mapping symbol can pick up
+          a text mapping symbol of a preceeding section.  The documentation
+          says section can be NULL, in which case we will seek up all the
+          way to the top.  */
+       if (info->section)
+         section_vma = info->section->vma;
+
+       for (; n >= 0; n--)
+         {
+           addr = bfd_asymbol_value (info->symtab[n]);
+           if (addr < section_vma)
+             break;
+
+           if (get_map_sym_type (info, n, &type))
+             {
+               last_sym = n;
+               found = TRUE;
+               break;
+             }
+         }
+      }
+  }
+
+  /* If no mapping symbol was found, try looking up without a mapping
+     symbol.  This is done by walking up from the current PC to the nearest
+     symbol.  We don't actually have to loop here since symtab_pos will
+     contain the nearest symbol already.  */
+  if (!found)
+    {
+      n = info->symtab_pos;
+      if (n >= 0 && get_sym_code_type (info, n, &type))
+       {
+         last_sym = n;
+         found = TRUE;
+       }
+    }
+
+  private_data->last_mapping_sym = last_sym;
+  private_data->last_type = type;
+  private_data->last_stop_offset = info->stop_offset;
+
+  *map_symbol = type;
+  return found;
+}
+
 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
    of the supplied arm_feature_set structure with bitmasks indicating
-   the support base architectures and coprocessor extensions.
+   the supported base architectures and coprocessor extensions.
 
    FIXME: This could more efficiently implemented as a constant array,
    although it would also be less robust.  */
@@ -6020,43 +6532,70 @@ static void
 select_arm_features (unsigned long mach,
                     arm_feature_set * features)
 {
-#undef  ARM_FEATURE_LOW
-#define ARM_FEATURE_LOW(ARCH1,CEXT) \
-  features->core[0] = (ARCH1); \
-  features->core[1] = 0; \
-  features->coproc = (CEXT) | FPU_FPA; \
-  return
-
-#undef  ARM_FEATURE_CORE_LOW
-#define ARM_FEATURE_CORE_LOW(ARCH1) \
-  features->core[0] = (ARCH1); \
-  features->core[1] = 0; \
-  features->coproc = FPU_FPA; \
-  return
-
+  arm_feature_set arch_fset;
+  const arm_feature_set fpu_any = FPU_ANY;
+
+#undef ARM_SET_FEATURES
+#define ARM_SET_FEATURES(FSET) \
+  {                                                    \
+    const arm_feature_set fset = FSET;                 \
+    arch_fset = fset;                                  \
+  }
+
+  /* When several architecture versions share the same bfd_mach_arm_XXX value
+     the most featureful is chosen.  */
   switch (mach)
     {
-    case bfd_mach_arm_2:       ARM_ARCH_V2;
-    case bfd_mach_arm_2a:      ARM_ARCH_V2S;
-    case bfd_mach_arm_3:       ARM_ARCH_V3;
-    case bfd_mach_arm_3M:      ARM_ARCH_V3M;
-    case bfd_mach_arm_4:       ARM_ARCH_V4;
-    case bfd_mach_arm_4T:      ARM_ARCH_V4T;
-    case bfd_mach_arm_5:       ARM_ARCH_V5;
-    case bfd_mach_arm_5T:      ARM_ARCH_V5T;
-    case bfd_mach_arm_5TE:     ARM_ARCH_V5TE;
-    case bfd_mach_arm_XScale:  ARM_ARCH_XSCALE;
-    case bfd_mach_arm_ep9312:  ARM_FEATURE_LOW (ARM_AEXT_V4T, \
-                                               ARM_CEXT_MAVERICK \
-                                               | FPU_MAVERICK);
-    case bfd_mach_arm_iWMMXt:  ARM_ARCH_IWMMXT;
-    case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
-      /* If the machine type is unknown allow all
-        architecture types and all extensions.  */
-    case bfd_mach_arm_unknown: ARM_FEATURE_LOW (-1UL, -1UL);
+    case bfd_mach_arm_2:        ARM_SET_FEATURES (ARM_ARCH_V2); break;
+    case bfd_mach_arm_2a:       ARM_SET_FEATURES (ARM_ARCH_V2S); break;
+    case bfd_mach_arm_3:        ARM_SET_FEATURES (ARM_ARCH_V3); break;
+    case bfd_mach_arm_3M:       ARM_SET_FEATURES (ARM_ARCH_V3M); break;
+    case bfd_mach_arm_4:        ARM_SET_FEATURES (ARM_ARCH_V4); break;
+    case bfd_mach_arm_4T:       ARM_SET_FEATURES (ARM_ARCH_V4T); break;
+    case bfd_mach_arm_5:        ARM_SET_FEATURES (ARM_ARCH_V5); break;
+    case bfd_mach_arm_5T:       ARM_SET_FEATURES (ARM_ARCH_V5T); break;
+    case bfd_mach_arm_5TE:      ARM_SET_FEATURES (ARM_ARCH_V5TE); break;
+    case bfd_mach_arm_XScale:   ARM_SET_FEATURES (ARM_ARCH_XSCALE); break;
+    case bfd_mach_arm_ep9312:
+       ARM_SET_FEATURES (ARM_FEATURE_LOW (ARM_AEXT_V4T,
+                                          ARM_CEXT_MAVERICK | FPU_MAVERICK));
+       break;
+    case bfd_mach_arm_iWMMXt:   ARM_SET_FEATURES (ARM_ARCH_IWMMXT); break;
+    case bfd_mach_arm_iWMMXt2:  ARM_SET_FEATURES (ARM_ARCH_IWMMXT2); break;
+    case bfd_mach_arm_5TEJ:     ARM_SET_FEATURES (ARM_ARCH_V5TEJ); break;
+    case bfd_mach_arm_6:        ARM_SET_FEATURES (ARM_ARCH_V6); break;
+    case bfd_mach_arm_6KZ:      ARM_SET_FEATURES (ARM_ARCH_V6KZ); break;
+    case bfd_mach_arm_6T2:      ARM_SET_FEATURES (ARM_ARCH_V6KZT2); break;
+    case bfd_mach_arm_6K:       ARM_SET_FEATURES (ARM_ARCH_V6K); break;
+    case bfd_mach_arm_7:        ARM_SET_FEATURES (ARM_ARCH_V7VE); break;
+    case bfd_mach_arm_6M:       ARM_SET_FEATURES (ARM_ARCH_V6M); break;
+    case bfd_mach_arm_6SM:      ARM_SET_FEATURES (ARM_ARCH_V6SM); break;
+    case bfd_mach_arm_7EM:      ARM_SET_FEATURES (ARM_ARCH_V7EM); break;
+    case bfd_mach_arm_8:
+       {
+         /* Add bits for extensions that Armv8.5-A recognizes.  */
+         arm_feature_set armv8_5_ext_fset
+           = ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
+         ARM_SET_FEATURES (ARM_ARCH_V8_5A);
+         ARM_MERGE_FEATURE_SETS (arch_fset, arch_fset, armv8_5_ext_fset);
+         break;
+       }
+    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;
+      /* 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;
     default:
       abort ();
     }
+#undef ARM_SET_FEATURES
+
+  /* None of the feature bits related to -mfpu have an impact on Tag_CPU_arch
+     and thus on bfd_mach_arm_XXX value.  Therefore for a given
+     bfd_mach_arm_XXX value all coprocessor feature bits should be allowed.  */
+  ARM_MERGE_FEATURE_SETS (*features, arch_fset, fpu_any);
 }
 
 
@@ -6079,7 +6618,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
 
   if (info->disassembler_options)
     {
-      parse_disassembler_options (info->disassembler_options);
+      parse_arm_disassembler_options (info->disassembler_options);
 
       /* To avoid repeated parsing of these options, we remove them here.  */
       info->disassembler_options = NULL;
@@ -6093,7 +6632,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
        /* If the user did not use the -m command line switch then default to
           disassembling all types of ARM instruction.
-          
+
           The info->mach value has to be ignored as this will be based on
           the default archictecture for the target and/or hints in the notes
           section, but it will never be greater than the current largest arm
@@ -6116,9 +6655,9 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
         during disassembly....  */
       select_arm_features (info->mach, & private.features);
 
-      private.has_mapping_symbols = -1;
       private.last_mapping_sym = -1;
       private.last_mapping_addr = 0;
+      private.last_stop_offset = 0;
 
       info->private_data = & private;
     }
@@ -6135,121 +6674,13 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
     {
       bfd_vma addr;
-      int n, start;
+      int n;
       int last_sym = -1;
       enum map_type type = MAP_ARM;
 
-      /* Start scanning at the start of the function, or wherever
-        we finished last time.  */
-      /* PR 14006.  When the address is 0 we are either at the start of the
-        very first function, or else the first function in a new, unlinked
-        executable section (eg because uf -ffunction-sections).  Either way
-        start scanning from the beginning of the symbol table, not where we
-        left off last time.  */
-      if (pc == 0)
-       start = 0;
-      else
-       {
-         start = info->symtab_pos + 1;
-         if (start < private_data->last_mapping_sym)
-           start = private_data->last_mapping_sym;
-       }
-      found = FALSE;
-
-      /* First, look for mapping symbols.  */
-      if (private_data->has_mapping_symbols != 0)
-       {
-         /* Scan up to the location being disassembled.  */
-         for (n = start; n < info->symtab_size; n++)
-           {
-             addr = bfd_asymbol_value (info->symtab[n]);
-             if (addr > pc)
-               break;
-             if (get_map_sym_type (info, n, &type))
-               {
-                 last_sym = n;
-                 found = TRUE;
-               }
-           }
+      found = mapping_symbol_for_insn (pc, info, &type);
+      last_sym = private_data->last_mapping_sym;
 
-         if (!found)
-           {
-             /* No mapping symbol found at this address.  Look backwards
-                for a preceding one.  */
-             for (n = start - 1; n >= 0; n--)
-               {
-                 if (get_map_sym_type (info, n, &type))
-                   {
-                     last_sym = n;
-                     found = TRUE;
-                     break;
-                   }
-               }
-           }
-
-         if (found)
-           private_data->has_mapping_symbols = 1;
-
-         /* No mapping symbols were found.  A leading $d may be
-            omitted for sections which start with data; but for
-            compatibility with legacy and stripped binaries, only
-            assume the leading $d if there is at least one mapping
-            symbol in the file.  */
-         if (!found && private_data->has_mapping_symbols == -1)
-           {
-             /* Look for mapping symbols, in any section.  */
-             for (n = 0; n < info->symtab_size; n++)
-               if (is_mapping_symbol (info, n, &type))
-                 {
-                   private_data->has_mapping_symbols = 1;
-                   break;
-                 }
-             if (private_data->has_mapping_symbols == -1)
-               private_data->has_mapping_symbols = 0;
-           }
-
-         if (!found && private_data->has_mapping_symbols == 1)
-           {
-             type = MAP_DATA;
-             found = TRUE;
-           }
-       }
-
-      /* Next search for function symbols to separate ARM from Thumb
-        in binaries without mapping symbols.  */
-      if (!found)
-       {
-         /* Scan up to the location being disassembled.  */
-         for (n = start; n < info->symtab_size; n++)
-           {
-             addr = bfd_asymbol_value (info->symtab[n]);
-             if (addr > pc)
-               break;
-             if (get_sym_code_type (info, n, &type))
-               {
-                 last_sym = n;
-                 found = TRUE;
-               }
-           }
-
-         if (!found)
-           {
-             /* No mapping symbol found at this address.  Look backwards
-                for a preceding one.  */
-             for (n = start - 1; n >= 0; n--)
-               {
-                 if (get_sym_code_type (info, n, &type))
-                   {
-                     last_sym = n;
-                     found = TRUE;
-                     break;
-                   }
-               }
-           }
-       }
-
-      private_data->last_mapping_sym = last_sym;
-      private_data->last_type = type;
       is_thumb = (private_data->last_type == MAP_THUMB);
       is_data = (private_data->last_type == MAP_DATA);
 
@@ -6304,9 +6735,16 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
          es = *(elf_symbol_type **)(info->symbols);
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
-         is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
-                      == ST_BRANCH_TO_THUMB)
-                     || type == STT_ARM_16BIT);
+         is_thumb =
+           ((ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal)
+             == ST_BRANCH_TO_THUMB) || type == STT_ARM_16BIT);
+       }
+      else if (bfd_asymbol_flavour (*info->symbols)
+              == bfd_target_mach_o_flavour)
+       {
+         bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)*info->symbols;
+
+         is_thumb = (asym->n_desc & BFD_MACH_O_N_ARM_THUMB_DEF);
        }
     }
 
@@ -6441,21 +6879,57 @@ print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
   return print_insn (pc, info, TRUE);
 }
 
+const disasm_options_and_args_t *
+disassembler_options_arm (void)
+{
+  static disasm_options_and_args_t *opts_and_args;
+
+  if (opts_and_args == NULL)
+    {
+      disasm_options_t *opts;
+      unsigned int i;
+
+      opts_and_args = XNEW (disasm_options_and_args_t);
+      opts_and_args->args = NULL;
+
+      opts = &opts_and_args->options;
+      opts->name = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1);
+      opts->description = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1);
+      opts->arg = NULL;
+      for (i = 0; i < NUM_ARM_OPTIONS; i++)
+       {
+         opts->name[i] = regnames[i].name;
+         if (regnames[i].description != NULL)
+           opts->description[i] = _(regnames[i].description);
+         else
+           opts->description[i] = NULL;
+       }
+      /* The array we return must be NULL terminated.  */
+      opts->name[i] = NULL;
+      opts->description[i] = NULL;
+    }
+
+  return opts_and_args;
+}
+
 void
 print_arm_disassembler_options (FILE *stream)
 {
-  int i;
-
+  unsigned int i, max_len = 0;
   fprintf (stream, _("\n\
 The following ARM specific disassembler options are supported for use with\n\
 the -M switch:\n"));
 
-  for (i = NUM_ARM_REGNAMES; i--;)
-    fprintf (stream, "  reg-names-%s %*c%s\n",
-            regnames[i].name,
-            (int)(14 - strlen (regnames[i].name)), ' ',
-            regnames[i].description);
+  for (i = 0; i < NUM_ARM_OPTIONS; i++)
+    {
+      unsigned int len = strlen (regnames[i].name);
+      if (max_len < len)
+       max_len = len;
+    }
 
-  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
-  fprintf (stream, "  no-force-thumb           Examine preceding label to determine an insn's type\n\n");
+  for (i = 0, max_len++; i < NUM_ARM_OPTIONS; i++)
+    fprintf (stream, "  %s%*c %s\n",
+            regnames[i].name,
+            (int)(max_len - strlen (regnames[i].name)), ' ',
+            _(regnames[i].description));
 }
This page took 0.118734 seconds and 4 git commands to generate.