]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - opcodes/arm-dis.c
Imported binutils-2.20
[msp430-binutils.git] / opcodes / arm-dis.c
index 9a4eacc1de62c5da3cb6425577620e713ec1d68f..76571478600d0e7567696aaed66257214aa81bcf 100644 (file)
@@ -1,6 +1,6 @@
 /* Instruction printing code for the ARM
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   2007, Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
    Modification by James G. Smith (jsmith@cygnus.co.uk)
 
@@ -48,8 +48,9 @@
 struct opcode32
 {
   unsigned long arch;          /* Architecture defining this insn.  */
-  unsigned long value, mask;   /* Recognise insn if (op&mask)==value.  */
-  const char *assembler;       /* How to disassemble this insn.  */
+  unsigned long value;         /* If arch == 0 then value is a sentinel.  */
+  unsigned long mask;          /* Recognise insn if (op & mask) == value.  */
+  const char *  assembler;     /* How to disassemble this insn.  */
 };
 
 struct opcode16
@@ -103,8 +104,16 @@ struct opcode16
                        versions.
    %i                  print 5-bit immediate in bits 8,3..0
                        (print "32" when 0)
-   %r                  print register offset address for wldt/wstr instruction
-*/
+   %r                  print register offset address for wldt/wstr instruction.  */
+
+enum
+{
+  SENTINEL_IWMMXT_START = 1,
+  SENTINEL_IWMMXT_END,
+  SENTINEL_GENERIC_START
+} opcode_sentinels;
+
+#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
 
@@ -116,10 +125,9 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
-    
+
   /* Intel Wireless MMX technology instructions.  */
-#define FIRST_IWMMXT_INSN 0x0e130130
-#define IWMMXT_INSN_COUNT 73
+  { 0, SENTINEL_IWMMXT_START, 0, "" },
   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
@@ -134,11 +142,11 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
-  {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
   {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
@@ -195,8 +203,9 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
+  { 0, SENTINEL_IWMMXT_END, 0, "" },
 
-  /* Floating point coprocessor (FPA) instructions */
+  /* Floating point coprocessor (FPA) instructions */
   {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
   {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
   {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
@@ -238,18 +247,33 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
   {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
   {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
-  {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
-  {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
-
-  /* Register load/store */
-  {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
-  {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
-  {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
-  {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
-  {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
-  {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
-
-  /* Data transfer between ARM and NEON registers */
+  {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A\t; (stc%22'l%c %8-11d, cr%12-15d, %A)"},
+  {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A\t; (ldc%22'l%c %8-11d, cr%12-15d, %A)"},
+
+  /* Register load/store.  */
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
+  {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
+  {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
+  {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
+  {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
+  {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
+  {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
+  {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
+  {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
+
+  {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
+  {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
+  {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
+  {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
+
+  /* Data transfer between ARM and NEON registers.  */
   {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
   {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
   {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
@@ -264,91 +288,78 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
   {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
   {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
-
-  /* Floating point coprocessor (VFP) instructions */
-  {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
-  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
-  {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
-  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
-  {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
-  {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"},
-  {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"},
-  {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
-  {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
-  {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
-  {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
-  {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
-  {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
-  {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
-  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"},
-  {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
-  {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
-  {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
-  {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
-  {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
-  {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
-  {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
-  {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
-  {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
-  {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
-  {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
-  {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
-  {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
-  {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
-  {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
-  {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
-  {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
-  {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
-  {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
-  {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
-  {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
-  {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
-  {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
-  {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
-  {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
-  {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
-  {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
-  {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
-  {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
-  {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
-  {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
-  {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
-  {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
-  {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
+  /* Half-precision conversion instructions.  */
+  {FPU_NEON_FP16,   0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
+  {FPU_NEON_FP16,   0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
+
+  /* Floating point coprocessor (VFP) instructions.  */
+  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
+  {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
+  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
+  {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
+  {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
+  {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
+  {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
+  {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
+  {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
+  {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
+  {FPU_VFP_EXT_V1, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
+  {FPU_VFP_EXT_V1, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
+  {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
+  {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
+  {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
+  {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
+  {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
+  {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
+  {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
+  {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
+  {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
+  {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
+  {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
+  {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
+  {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
+  {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
+  {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
+  {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
+  {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
+  {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
+  {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
+  {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
 
   /* Cirrus coprocessor instructions.  */
   {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
@@ -436,20 +447,21 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
   {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
 
-  /* Generic coprocessor instructions */
-  {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
-  {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+  /* Generic coprocessor instructions.  */
+  { 0, SENTINEL_GENERIC_START, 0, "" },
+  {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
+  {ARM_EXT_V5E, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
   {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
   {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
   {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
   {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
   {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
 
-  /* V6 coprocessor instructions */
+  /* V6 coprocessor instructions */
   {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
   {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
 
-  /* V5 coprocessor instructions */
+  /* V5 coprocessor instructions */
   {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
   {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
   {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
@@ -487,24 +499,28 @@ static const struct opcode32 coprocessor_opcodes[] =
    
    %<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  */
+   %<bitfield>?ab...    select from array of values in big endian order.  */
 
 static const struct opcode32 neon_opcodes[] =
 {
-  /* Extract */
+  /* Extract */
   {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
   {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
 
-  /* Move data element to all lanes */
+  /* Move data element to all lanes */
   {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
   {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
   {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
 
-  /* Table lookup */
+  /* Table lookup */
   {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
   
-  /* Two registers, miscellaneous */
+  /* Half-precision conversions.  */
+  {FPU_NEON_FP16,   0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
+  {FPU_NEON_FP16,   0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
+
+  /* Two registers, miscellaneous.  */
   {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
@@ -539,7 +555,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
   {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
 
-  /* Three registers of the same length */
+  /* Three registers of the same length */
   {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
@@ -594,7 +610,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
   {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
 
-  /* One register and an immediate value */
+  /* One register and an immediate value */
   {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
   {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
   {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
@@ -609,7 +625,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
   {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
 
-  /* Two registers and a shift amount */
+  /* Two registers and a shift amount */
   {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
   {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
   {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
@@ -645,10 +661,10 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
   {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
   {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
-  {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
-  {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
-  {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
-  {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
+  {FPU_NEON_EXT_V1, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
+  {FPU_NEON_EXT_V1, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
+  {FPU_NEON_EXT_V1, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
+  {FPU_NEON_EXT_V1, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
   {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
   {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
   {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
@@ -669,7 +685,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
   {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
 
-  /* Three registers of different lengths */
+  /* Three registers of different lengths */
   {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
   {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
@@ -688,7 +704,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
 
-  /* Two registers and a scalar */
+  /* Two registers and a scalar */
   {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
   {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
   {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
@@ -712,7 +728,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
   {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
 
-  /* Element and structure load/store */
+  /* Element and structure load/store */
   {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
   {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
   {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
@@ -774,7 +790,7 @@ static const struct opcode32 neon_opcodes[] =
 static const struct opcode32 arm_opcodes[] =
 {
   /* ARM instructions.  */
-  {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
+  {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
@@ -819,7 +835,7 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
   {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
 
-  /* ARM V6 instructions. */
+  /* ARM V6 instructions.  */
   {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
   {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
   {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
@@ -866,10 +882,10 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
   {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
   {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
-  {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
-  {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
-  {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
-  {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
+  {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
+  {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
+  {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
+  {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
   {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
   {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
   {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
@@ -983,23 +999,72 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
 
   /* ARM Instructions.  */
-  {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"},
-  {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
-  {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
+  {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
+  {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
+  {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
+  {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
+  {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
+  {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
+
+  {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+
   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
-  {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
+
   {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
   {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
   {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
@@ -1007,13 +1072,16 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
   {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
   {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
-  {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
-  {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
-  {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
-  {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
-  {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
-  {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
+
+  {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
+  {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
+  {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
+
+  {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
   {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
   {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
@@ -1026,7 +1094,7 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
 
   /* The rest.  */
-  {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
+  {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
   {0, 0x00000000, 0x00000000, 0}
 };
 
@@ -1091,7 +1159,7 @@ static const struct opcode16 thumb_opcodes[] =
   /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
   {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"},     /* note: 4 bit register number.  */
   /* ARM V4T ISA (Thumb v1).  */
-  {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
+  {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
   /* Format 4.  */
   {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
@@ -1142,7 +1210,7 @@ static const struct opcode16 thumb_opcodes[] =
   {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
   {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
   /* format 6 */
-  {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
+  {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
   /* format 9 */
   {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
@@ -1155,7 +1223,7 @@ static const struct opcode16 thumb_opcodes[] =
   {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
   /* format 12 */
-  {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
+  {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
   {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
   /* format 15 */
   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
@@ -1163,7 +1231,7 @@ static const struct opcode16 thumb_opcodes[] =
   /* format 17 */
   {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
   /* format 16 */
-  {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"},
+  {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
   /* format 18 */
   {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
@@ -1172,7 +1240,7 @@ static const struct opcode16 thumb_opcodes[] =
      32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
      are processed via that table.  Thus, we can never encounter a
      bare "second half of BL/BLX(1)" instruction here.  */
-  {ARM_EXT_V1,  0x0000, 0x0000, "undefined"},
+  {ARM_EXT_V1,  0x0000, 0x0000, UNDEFINED_INSTRUCTION},
   {0, 0, 0, 0}
 };
 
@@ -1239,7 +1307,7 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
   {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
-  {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
+  {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
 
   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
@@ -1274,10 +1342,10 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
-  {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
-  {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
-  {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
-  {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
+  {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
+  {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
+  {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
+  {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
   {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
@@ -1426,7 +1494,7 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl%c\t%B%x"},
 
   /* Fallback.  */
-  {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
+  {ARM_EXT_V1,   0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
   {0, 0, 0, 0}
 };
    
@@ -1502,7 +1570,8 @@ static bfd_vma ifthen_address;
 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
 
 /* Cached mapping symbol state.  */
-enum map_type {
+enum map_type
+{
   MAP_ARM,
   MAP_THUMB,
   MAP_DATA
@@ -1529,7 +1598,9 @@ set_arm_regname_option (int option)
 }
 
 int
-get_arm_regnames (int option, const char **setname, const char **setdescription,
+get_arm_regnames (int option,
+                 const char **setname,
+                 const char **setdescription,
                  const char *const **register_names)
 {
   *setname = regnames[option].name;
@@ -1541,11 +1612,13 @@ get_arm_regnames (int option, const char **setname, const char **setdescription,
 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
    Returns pointer to following character of the format string and
    fills in *VALUEP and *WIDTHP with the extracted value and number of
-   bits extracted.  WIDTHP can be NULL. */
+   bits extracted.  WIDTHP can be NULL.  */
 
 static const char *
-arm_decode_bitfield (const char *ptr, unsigned long insn,
-                    unsigned long *valuep, int *widthp)
+arm_decode_bitfield (const char *ptr,
+                    unsigned long insn,
+                    unsigned long *valuep,
+                    int *widthp)
 {
   unsigned long value = 0;
   int width = 0;
@@ -1577,7 +1650,7 @@ arm_decode_bitfield (const char *ptr, unsigned long insn,
 
 static void
 arm_decode_shift (long given, fprintf_ftype func, void *stream,
-                 int print_shift)
+                 bfd_boolean print_shift)
 {
   func (stream, "%s", arm_regnames[given & 0xf]);
 
@@ -1604,6 +1677,8 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
          else
            func (stream, ", #%d", amount);
        }
+      else if ((given & 0x80) == 0x80)
+       func (stream, ", <illegal shifter operand>");
       else if (print_shift)
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
              arm_regnames[(given & 0xf00) >> 8]);
@@ -1617,7 +1692,9 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
    recognised coprocessor instruction.  */
 
 static bfd_boolean
-print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
+print_insn_coprocessor (bfd_vma pc,
+                       struct disassemble_info *info,
+                       long given,
                        bfd_boolean thumb)
 {
   const struct opcode32 *insn;
@@ -1625,15 +1702,36 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
   fprintf_ftype func = info->fprintf_func;
   unsigned long mask;
   unsigned long value;
+  unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
   int cond;
 
   for (insn = coprocessor_opcodes; insn->assembler; insn++)
     {
-      if (insn->value == FIRST_IWMMXT_INSN
-         && info->mach != bfd_mach_arm_XScale
-         && info->mach != bfd_mach_arm_iWMMXt
-         && info->mach != bfd_mach_arm_iWMMXt2)
-       insn = insn + IWMMXT_INSN_COUNT;
+      signed long value_in_comment = 0;
+      const char *c;
+
+      if (insn->arch == 0)
+       switch (insn->value)
+         {
+         case SENTINEL_IWMMXT_START:
+           if (info->mach != bfd_mach_arm_XScale
+               && info->mach != bfd_mach_arm_iWMMXt
+               && info->mach != bfd_mach_arm_iWMMXt2)
+             do
+               insn++;
+             while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
+           continue;
+
+         case SENTINEL_IWMMXT_END:
+           continue;
+
+         case SENTINEL_GENERIC_START:
+           allowed_arches = ((arm_feature_set *) info->private_data)->core;
+           continue;
+
+         default:
+           abort ();
+         }
 
       mask = insn->mask;
       value = insn->value;
@@ -1665,463 +1763,485 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
                cond = 16;
            }
        }
-      if ((given & mask) == value)
-       {
-         const char *c;
+      
+      if ((given & mask) != value)
+       continue;
 
-         for (c = insn->assembler; *c; c++)
+      if ((insn->arch & allowed_arches) == 0)
+       continue;
+
+      for (c = insn->assembler; *c; c++)
+       {
+         if (*c == '%')
            {
-             if (*c == '%')
+             switch (*++c)
                {
-                 switch (*++c)
-                   {
-                   case '%':
-                     func (stream, "%%");
-                     break;
-
-                   case 'A':
-                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
-
-                     if ((given & (1 << 24)) != 0)
-                       {
-                         int offset = given & 0xff;
-
-                         if (offset)
-                           func (stream, ", #%s%d]%s",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
-                                 offset * 4,
-                                 ((given & 0x00200000) != 0 ? "!" : ""));
-                         else
-                           func (stream, "]");
-                       }
-                     else
-                       {
-                         int offset = given & 0xff;
+               case '%':
+                 func (stream, "%%");
+                 break;
 
-                         func (stream, "]");
+               case 'A':
+                 {
+                   int offset = given & 0xff;
 
-                         if (given & (1 << 21))
-                           {
-                             if (offset)
-                               func (stream, ", #%s%d",
-                                     ((given & 0x00800000) == 0 ? "-" : ""),
-                                     offset * 4);
-                           }
-                         else
-                           func (stream, ", {%d}", offset);
-                       }
-                     break;
+                   func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                   case 'B':
+                   value_in_comment = offset * 4;
+                   if ((given & 0x00800000) == 0)
+                     value_in_comment = - value_in_comment;
+                   
+                   if ((given & (1 << 24)) != 0)
                      {
-                       int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
-                       int offset = (given >> 1) & 0x3f;
-                       
-                       if (offset == 1)
-                         func (stream, "{d%d}", regno);
-                       else if (regno + offset > 32)
-                         func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
+                       if (offset)
+                         func (stream, ", #%d]%s",
+                               value_in_comment,
+                               ((given & 0x00200000) != 0 ? "!" : ""));
                        else
-                         func (stream, "{d%d-d%d}", regno, regno + offset - 1);
+                         func (stream, "]");
                      }
-                     break;
-                     
-                   case 'C':
+                   else
                      {
-                       int rn = (given >> 16) & 0xf;
-                       int offset = (given & 0xff) * 4;
-                       int add = (given >> 23) & 1;
-                       
-                       func (stream, "[%s", arm_regnames[rn]);
-                       
-                       if (offset)
+                       func (stream, "]");
+
+                       if (given & (1 << 21))
                          {
-                           if (!add)
-                             offset = -offset;
-                           func (stream, ", #%d", offset);
+                           if (offset)
+                             func (stream, ", #%d", value_in_comment);
                          }
-                       func (stream, "]");
-                       if (rn == 15)
+                       else
                          {
-                           func (stream, "\t; ");
-                            /* FIXME: Unsure if info->bytes_per_chunk is the
-                               right thing to use here.  */
-                           info->print_address_func (offset + pc
-                              + info->bytes_per_chunk * 2, info);
+                           func (stream, ", {%d}", offset);
+                           value_in_comment = offset;
                          }
                      }
-                     break;
+                 }
+                 break;
 
-                   case 'c':
-                     func (stream, "%s", arm_conditional[cond]);
-                     break;
+               case 'B':
+                 {
+                   int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
+                   int offset = (given >> 1) & 0x3f;
+
+                   if (offset == 1)
+                     func (stream, "{d%d}", regno);
+                   else if (regno + offset > 32)
+                     func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
+                   else
+                     func (stream, "{d%d-d%d}", regno, regno + offset - 1);
+                 }
+                 break;
+
+               case 'C':
+                 {
+                   int rn = (given >> 16) & 0xf;
+                   int offset = (given & 0xff) * 4;
+                   int add = (given >> 23) & 1;
 
-                   case 'I':
-                     /* Print a Cirrus/DSP shift immediate.  */
-                     /* Immediates are 7bit signed ints with bits 0..3 in
-                        bits 0..3 of opcode and bits 4..6 in bits 5..7
-                        of opcode.  */
+                   func (stream, "[%s", arm_regnames[rn]);
+
+                   if (offset)
+                     {
+                       if (!add)
+                         offset = -offset;
+                       func (stream, ", #%d", offset);
+                       if (rn != 15)
+                         value_in_comment = offset;
+                     }
+                   func (stream, "]");
+                   if (rn == 15)
                      {
-                       int imm;
+                       func (stream, "\t; ");
+                       /* FIXME: Unsure if info->bytes_per_chunk is the
+                          right thing to use here.  */
+                       info->print_address_func (offset + pc
+                                                 + info->bytes_per_chunk * 2, info);
+                     }
+                 }
+                 break;
 
-                       imm = (given & 0xf) | ((given & 0xe0) >> 1);
+               case 'c':
+                 func (stream, "%s", arm_conditional[cond]);
+                 break;
+
+               case 'I':
+                 /* Print a Cirrus/DSP shift immediate.  */
+                 /* Immediates are 7bit signed ints with bits 0..3 in
+                    bits 0..3 of opcode and bits 4..6 in bits 5..7
+                    of opcode.  */
+                 {
+                   int imm;
 
-                       /* Is ``imm'' a negative number?  */
-                       if (imm & 0x40)
-                         imm |= (-1 << 7);
+                   imm = (given & 0xf) | ((given & 0xe0) >> 1);
 
-                       func (stream, "%d", imm);
-                     }
+                   /* Is ``imm'' a negative number?  */
+                   if (imm & 0x40)
+                     imm |= (-1 << 7);
+
+                   func (stream, "%d", imm);
+                 }
+
+                 break;
 
+               case 'F':
+                 switch (given & 0x00408000)
+                   {
+                   case 0:
+                     func (stream, "4");
+                     break;
+                   case 0x8000:
+                     func (stream, "1");
                      break;
+                   case 0x00400000:
+                     func (stream, "2");
+                     break;
+                   default:
+                     func (stream, "3");
+                   }
+                 break;
 
-                   case 'F':
-                     switch (given & 0x00408000)
-                       {
-                       case 0:
-                         func (stream, "4");
-                         break;
-                       case 0x8000:
-                         func (stream, "1");
-                         break;
-                       case 0x00400000:
-                         func (stream, "2");
-                         break;
-                       default:
-                         func (stream, "3");
-                       }
+               case 'P':
+                 switch (given & 0x00080080)
+                   {
+                   case 0:
+                     func (stream, "s");
+                     break;
+                   case 0x80:
+                     func (stream, "d");
+                     break;
+                   case 0x00080000:
+                     func (stream, "e");
+                     break;
+                   default:
+                     func (stream, _("<illegal precision>"));
                      break;
+                   }
+                 break;
 
-                   case 'P':
-                     switch (given & 0x00080080)
-                       {
-                       case 0:
-                         func (stream, "s");
-                         break;
-                       case 0x80:
-                         func (stream, "d");
-                         break;
-                       case 0x00080000:
-                         func (stream, "e");
-                         break;
-                       default:
-                         func (stream, _("<illegal precision>"));
-                         break;
-                       }
+               case 'Q':
+                 switch (given & 0x00408000)
+                   {
+                   case 0:
+                     func (stream, "s");
                      break;
-                   case 'Q':
-                     switch (given & 0x00408000)
-                       {
-                       case 0:
-                         func (stream, "s");
-                         break;
-                       case 0x8000:
-                         func (stream, "d");
-                         break;
-                       case 0x00400000:
-                         func (stream, "e");
-                         break;
-                       default:
-                         func (stream, "p");
-                         break;
-                       }
+                   case 0x8000:
+                     func (stream, "d");
                      break;
-                   case 'R':
-                     switch (given & 0x60)
-                       {
-                       case 0:
-                         break;
-                       case 0x20:
-                         func (stream, "p");
-                         break;
-                       case 0x40:
-                         func (stream, "m");
-                         break;
-                       default:
-                         func (stream, "z");
-                         break;
-                       }
+                   case 0x00400000:
+                     func (stream, "e");
+                     break;
+                   default:
+                     func (stream, "p");
                      break;
+                   }
+                 break;
 
-                   case '0': case '1': case '2': case '3': case '4':
-                   case '5': case '6': case '7': case '8': case '9':
-                     {
-                       int width;
-                       unsigned long value;
+               case 'R':
+                 switch (given & 0x60)
+                   {
+                   case 0:
+                     break;
+                   case 0x20:
+                     func (stream, "p");
+                     break;
+                   case 0x40:
+                     func (stream, "m");
+                     break;
+                   default:
+                     func (stream, "z");
+                     break;
+                   }
+                 break;
 
-                       c = arm_decode_bitfield (c, given, &value, &width);
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                 {
+                   int width;
+                   unsigned long value;
 
-                       switch (*c)
-                         {
-                         case 'r':
-                           func (stream, "%s", arm_regnames[value]);
-                           break;
-                         case 'D':
-                           func (stream, "d%ld", value);
-                           break;
-                         case 'Q':
-                           if (value & 1)
-                             func (stream, "<illegal reg q%ld.5>", value >> 1);
-                           else
-                             func (stream, "q%ld", value >> 1);
-                           break;
-                         case 'd':
-                           func (stream, "%ld", value);
-                           break;
-                          case 'k':
-                            {
-                              int from = (given & (1 << 7)) ? 32 : 16;
-                              func (stream, "%ld", from - value);
-                            }
-                            break;
-                            
-                         case 'f':
-                           if (value > 7)
-                             func (stream, "#%s", arm_fp_const[value & 7]);
-                           else
-                             func (stream, "f%ld", value);
-                           break;
+                   c = arm_decode_bitfield (c, given, &value, &width);
 
-                         case 'w':
-                           if (width == 2)
-                             func (stream, "%s", iwmmxt_wwnames[value]);
-                           else
-                             func (stream, "%s", iwmmxt_wwssnames[value]);
-                           break;
+                   switch (*c)
+                     {
+                     case 'r':
+                       func (stream, "%s", arm_regnames[value]);
+                       break;
+                     case 'D':
+                       func (stream, "d%ld", value);
+                       break;
+                     case 'Q':
+                       if (value & 1)
+                         func (stream, "<illegal reg q%ld.5>", value >> 1);
+                       else
+                         func (stream, "q%ld", value >> 1);
+                       break;
+                     case 'd':
+                       func (stream, "%ld", value);
+                       value_in_comment = value;
+                       break;
+                     case 'k':
+                       {
+                         int from = (given & (1 << 7)) ? 32 : 16;
+                         func (stream, "%ld", from - value);
+                       }
+                       break;
 
-                         case 'g':
-                           func (stream, "%s", iwmmxt_regnames[value]);
-                           break;
-                         case 'G':
-                           func (stream, "%s", iwmmxt_cregnames[value]);
-                           break;
+                     case 'f':
+                       if (value > 7)
+                         func (stream, "#%s", arm_fp_const[value & 7]);
+                       else
+                         func (stream, "f%ld", value);
+                       break;
 
-                         case 'x':
-                           func (stream, "0x%lx", value);
-                           break;
+                     case 'w':
+                       if (width == 2)
+                         func (stream, "%s", iwmmxt_wwnames[value]);
+                       else
+                         func (stream, "%s", iwmmxt_wwssnames[value]);
+                       break;
 
-                         case '`':
-                           c++;
-                           if (value == 0)
-                             func (stream, "%c", *c);
-                           break;
-                         case '\'':
-                           c++;
-                           if (value == ((1ul << width) - 1))
-                             func (stream, "%c", *c);
-                           break;
-                         case '?':
-                           func (stream, "%c", c[(1 << width) - (int)value]);
-                           c += 1 << width;
-                           break;
-                         default:
-                           abort ();
-                         }
+                     case 'g':
+                       func (stream, "%s", iwmmxt_regnames[value]);
+                       break;
+                     case 'G':
+                       func (stream, "%s", iwmmxt_cregnames[value]);
                        break;
 
-                     case 'y':
-                     case 'z':
+                     case 'x':
+                       func (stream, "0x%lx", (value & 0xffffffffUL));
+                       break;
+
+                     case '`':
+                       c++;
+                       if (value == 0)
+                         func (stream, "%c", *c);
+                       break;
+                     case '\'':
+                       c++;
+                       if (value == ((1ul << width) - 1))
+                         func (stream, "%c", *c);
+                       break;
+                     case '?':
+                       func (stream, "%c", c[(1 << width) - (int) value]);
+                       c += 1 << width;
+                       break;
+                     default:
+                       abort ();
+                     }
+                   break;
+
+                 case 'y':
+                 case 'z':
+                   {
+                     int single = *c++ == 'y';
+                     int regno;
+
+                     switch (*c)
                        {
-                         int single = *c++ == 'y';
-                         int regno;
-                         
-                         switch (*c)
+                       case '4': /* Sm pair */
+                       case '0': /* Sm, Dm */
+                         regno = given & 0x0000000f;
+                         if (single)
                            {
-                           case '4': /* Sm pair */
-                             func (stream, "{");
-                             /* Fall through.  */
-                           case '0': /* Sm, Dm */
-                             regno = given & 0x0000000f;
-                             if (single)
-                               {
-                                 regno <<= 1;
-                                 regno += (given >> 5) & 1;
-                               }
-                              else
-                                regno += ((given >> 5) & 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;
+                             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 '3': /* List */
-                             func (stream, "{");
-                             regno = (given >> 12) & 0x0000000f;
-                             if (single)
-                               {
-                                 regno <<= 1;
-                                 regno += (given >> 22) & 1;
-                               }
-                              else
-                                regno += ((given >> 22) & 1) << 4;
-                             break;
-                             
-                           default:
-                             abort ();
+                       case '1': /* Sd, Dd */
+                         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);
+                       case '2': /* Sn, Dn */
+                         regno = (given >> 16) & 0x0000000f;
+                         if (single)
+                           {
+                             regno <<= 1;
+                             regno += (given >> 7) & 1;
+                           }
+                         else
+                           regno += ((given >> 7) & 1) << 4;
+                         break;
 
-                         if (*c == '3')
+                       case '3': /* List */
+                         func (stream, "{");
+                         regno = (given >> 12) & 0x0000000f;
+                         if (single)
                            {
-                             int count = given & 0xff;
-                             
-                             if (single == 0)
-                               count >>= 1;
-                             
-                             if (--count)
-                               {
-                                 func (stream, "-%c%d",
-                                       single ? 's' : 'd',
-                                       regno + count);
-                               }
-                             
-                             func (stream, "}");
+                             regno <<= 1;
+                             regno += (given >> 22) & 1;
                            }
-                         else if (*c == '4')
-                           func (stream, ", %c%d}", single ? 's' : 'd',
-                                 regno + 1);
-                       }
-                       break;
-                           
-                     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;
-                         }
-                       break;
+                         else
+                           regno += ((given >> 22) & 1) << 4;
+                         break;
 
-                     case 'Z':
-                       {
-                         int value;
-                         /* given (20, 23) | given (0, 3) */
-                         value = ((given >> 16) & 0xf0) | (given & 0xf);
-                         func (stream, "%d", value);
+                       default:
+                         abort ();
                        }
-                       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.  */
+                     func (stream, "%c%d", single ? 's' : 'd', regno);
+
+                     if (*c == '3')
                        {
-                         int offset = given & 0xff;
-                         int multiplier = (given & 0x00000100) ? 4 : 1;
+                         int count = given & 0xff;
 
-                         func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+                         if (single == 0)
+                           count >>= 1;
 
-                         if (offset)
+                         if (--count)
                            {
-                             if ((given & 0x01000000) != 0)
-                               func (stream, ", #%s%d]%s",
-                                     ((given & 0x00800000) == 0 ? "-" : ""),
-                                     offset * multiplier,
-                                     ((given & 0x00200000) != 0 ? "!" : ""));
-                             else
-                               func (stream, "], #%s%d",
-                                     ((given & 0x00800000) == 0 ? "-" : ""),
-                                     offset * multiplier);
+                             func (stream, "-%c%d",
+                                   single ? 's' : 'd',
+                                   regno + count);
                            }
-                         else
-                           func (stream, "]");
+
+                         func (stream, "}");
                        }
+                     else if (*c == '4')
+                       func (stream, ", %c%d", single ? 's' : 'd',
+                             regno + 1);
+                   }
+                   break;
+
+                 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;
+                     }
+                   break;
 
-                     case 'r':
-                       {
-                         int imm4 = (given >> 4) & 0xf;
-                         int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
-                         int ubit = (given >> 23) & 1;
-                         const char *rm = arm_regnames [given & 0xf];
-                         const char *rn = arm_regnames [(given >> 16) & 0xf];
+                 case 'Z':
+                   {
+                     int value;
+                     /* given (20, 23) | given (0, 3) */
+                     value = ((given >> 16) & 0xf0) | (given & 0xf);
+                     func (stream, "%d", value);
+                   }
+                   break;
 
-                         switch (puw_bits)
-                           {
-                           case 1:
-                             /* fall through */
-                           case 3:
-                             func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
-                             if (imm4)
-                               func (stream, ", lsl #%d", imm4);
-                             break;
-
-                           case 4:
-                             /* fall through */
-                           case 5:
-                             /* fall through */
-                           case 6:
-                             /* fall through */
-                           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 '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;
 
-                           default:
-                             func (stream, "INVALID");
-                           }
+                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+
+                     if (multiplier > 1)
+                       {
+                         value_in_comment = offset * multiplier;
+                         if ((given & 0x00800000) == 0)
+                           value_in_comment = - value_in_comment;
                        }
-                       break;
 
-                     case 'i':
+                     if (offset)
                        {
-                         long imm5;
-                         imm5 = ((given & 0x100) >> 4) | (given & 0xf);
-                         func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
+                         if ((given & 0x01000000) != 0)
+                           func (stream, ", #%s%d]%s",
+                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 offset * multiplier,
+                                 ((given & 0x00200000) != 0 ? "!" : ""));
+                         else
+                           func (stream, "], #%s%d",
+                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 offset * multiplier);
                        }
-                       break;
+                     else
+                       func (stream, "]");
+                   }
+                   break;
 
-                     default:
-                       abort ();
-                     }
+                 case 'r':
+                   {
+                     int imm4 = (given >> 4) & 0xf;
+                     int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
+                     int ubit = (given >> 23) & 1;
+                     const char *rm = arm_regnames [given & 0xf];
+                     const char *rn = arm_regnames [(given >> 16) & 0xf];
+
+                     switch (puw_bits)
+                       {
+                       case 1:
+                       case 3:
+                         func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
+                         if (imm4)
+                           func (stream, ", lsl #%d", imm4);
+                         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;
+
+                       default:
+                         func (stream, "INVALID");
+                       }
+                   }
+                   break;
+
+                 case 'i':
+                   {
+                     long imm5;
+                     imm5 = ((given & 0x100) >> 4) | (given & 0xf);
+                     func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
                    }
+                   break;
+
+                 default:
+                   abort ();
+                 }
                }
-             else
-               func (stream, "%c", *c);
            }
-         return TRUE;
+         else
+           func (stream, "%c", *c);
        }
+
+      if (value_in_comment > 32 || value_in_comment < -16)
+       func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
+
+      return TRUE;
     }
   return FALSE;
 }
 
-static void
+/* Decodes and prints ARM addressing modes.  Returns the offset
+   used in the address, if any, if it is worthwhile printing the
+   offset as a hexadecimal value in a comment at the end of the
+   line of disassembly.  */
+
+static signed long
 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
 {
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
+  int offset = 0;
 
   if (((given & 0x000f0000) == 0x000f0000)
       && ((given & 0x02000000) == 0))
     {
-      int offset = given & 0xfff;
+      offset = given & 0xfff;
 
       func (stream, "[pc");
 
@@ -2153,6 +2273,7 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
 
       func (stream, "\t; ");
       info->print_address_func (offset, info);
+      offset = 0;
     }
   else
     {
@@ -2162,7 +2283,7 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
        {
          if ((given & 0x02000000) == 0)
            {
-             int offset = given & 0xfff;
+             offset = given & 0xfff;
              if (offset)
                func (stream, ", #%s%d",
                      (((given & 0x00800000) == 0)
@@ -2173,7 +2294,7 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
              func (stream, ", %s",
                    (((given & 0x00800000) == 0)
                     ? "-" : ""));
-             arm_decode_shift (given, func, stream, 1);
+             arm_decode_shift (given, func, stream, TRUE);
            }
 
          func (stream, "]%s",
@@ -2183,7 +2304,7 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
        {
          if ((given & 0x02000000) == 0)
            {
-             int offset = given & 0xfff;
+             offset = given & 0xfff;
              if (offset)
                func (stream, "], #%s%d",
                      (((given & 0x00800000) == 0)
@@ -2196,10 +2317,12 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
              func (stream, "], %s",
                    (((given & 0x00800000) == 0)
                     ? "-" : ""));
-             arm_decode_shift (given, func, stream, 1);
+             arm_decode_shift (given, func, stream, TRUE);
            }
        }
     }
+
+  return (signed long) offset;
 }
 
 /* Print one neon instruction on INFO->STREAM.
@@ -2217,7 +2340,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
     {
       if ((given & 0xef000000) == 0xef000000)
        {
-         /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
+         /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
          unsigned long bit28 = given & (1 << 28);
 
          given &= 0x00ffffff;
@@ -2236,6 +2359,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
     {
       if ((given & insn->mask) == insn->value)
        {
+         signed long value_in_comment = 0;
          const char *c;
 
          for (c = insn->assembler; *c; c++)
@@ -2428,7 +2552,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                      break;
                      
                    case 'E':
-                     /* Neon encoded constant for mov, mvn, vorr, vbic */
+                     /* Neon encoded constant for mov, mvn, vorr, vbic */
                      {
                        int bits = 0;
                        int cmode = (given >> 8) & 0xf;
@@ -2445,19 +2569,19 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                        if (cmode < 8)
                          {
                            shift = (cmode >> 1) & 3;
-                           value = (unsigned long)bits << (8 * shift);
+                           value = (unsigned long) bits << (8 * shift);
                             size = 32;
                          }
                        else if (cmode < 12)
                          {
                            shift = (cmode >> 1) & 1;
-                           value = (unsigned long)bits << (8 * shift);
+                           value = (unsigned long) bits << (8 * shift);
                             size = 16;
                          }
                        else if (cmode < 14)
                          {
                            shift = (cmode & 1) + 1;
-                           value = (unsigned long)bits << (8 * shift);
+                           value = (unsigned long) bits << (8 * shift);
                            value |= (1ul << (8 * shift)) - 1;
                             size = 32;
                          }
@@ -2465,7 +2589,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          {
                            if (op)
                              {
-                               /* bit replication into bytes */
+                               /* Bit replication into bytes.  */
                                int ix;
                                unsigned long mask;
                                
@@ -2483,20 +2607,20 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                              }
                             else
                               {
-                                /* byte replication */
-                                value = (unsigned long)bits;
+                                /* Byte replication.  */
+                                value = (unsigned long) bits;
                                 size = 8;
                               }
                          }
                        else if (!op)
                          {
-                           /* floating point encoding */
+                           /* Floating point encoding.  */
                            int tmp;
                            
-                           value = (unsigned long)(bits & 0x7f) << 19;
-                           value |= (unsigned long)(bits & 0x80) << 24;
+                           value = (unsigned long)  (bits & 0x7f) << 19;
+                           value |= (unsigned long) (bits & 0x80) << 24;
                            tmp = bits & 0x40 ? 0x3c : 0x40;
-                           value |= (unsigned long)tmp << 24;
+                           value |= (unsigned long) tmp << 24;
                             size = 32;
                             isfloat = 1;
                          }
@@ -2583,6 +2707,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                            break;
                          case 'd':
                            func (stream, "%ld", value);
+                           value_in_comment = value;
                            break;
                          case 'e':
                            func (stream, "%ld", (1ul << width) - value);
@@ -2591,7 +2716,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          case 'S':
                          case 'T':
                          case 'U':
-                           /* various width encodings */
+                           /* Various width encodings.  */
                            {
                              int base = 8 << (*c - 'S'); /* 8,16 or 32 */
                              int limit;
@@ -2639,7 +2764,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                              func (stream, "%c", *c);
                            break;
                          case '?':
-                           func (stream, "%c", c[(1 << width) - (int)value]);
+                           func (stream, "%c", c[(1 << width) - (int) value]);
                            c += 1 << width;
                            break;
                          default:
@@ -2655,6 +2780,10 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
              else
                func (stream, "%c", *c);
            }
+
+         if (value_in_comment > 32 || value_in_comment < -16)
+           func (stream, "\t; 0x%lx", value_in_comment);
+
          return TRUE;
        }
     }
@@ -2678,19 +2807,20 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 
   for (insn = arm_opcodes; insn->assembler; insn++)
     {
-      if (insn->value == FIRST_IWMMXT_INSN
-         && info->mach != bfd_mach_arm_XScale
-         && info->mach != bfd_mach_arm_iWMMXt)
-       insn = insn + IWMMXT_INSN_COUNT;
-
-      if ((given & insn->mask) == insn->value
-         /* Special case: an instruction with all bits set in the condition field
-            (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
-            or by the catchall at the end of the table.  */
-         && ((given & 0xF0000000) != 0xF0000000
-             || (insn->mask & 0xF0000000) == 0xF0000000
-             || (insn->mask == 0 && insn->value == 0)))
+      if ((given & insn->mask) != insn->value)
+       continue;
+    
+      if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
+       continue;
+
+      /* Special case: an instruction with all bits set in the condition field
+        (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
+        or by the catchall at the end of the table.  */
+      if ((given & 0xF0000000) != 0xF0000000
+         || (insn->mask & 0xF0000000) == 0xF0000000
+         || (insn->mask == 0 && insn->value == 0))
        {
+         signed long value_in_comment = 0;
          const char *c;
 
          for (c = insn->assembler; *c; c++)
@@ -2704,13 +2834,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'a':
-                     print_arm_address (pc, info, given);
+                     value_in_comment = print_arm_address (pc, info, given);
                      break;
 
                    case 'P':
                      /* Set P address bit and use normal address
                         printing routine.  */
-                     print_arm_address (pc, info, given | (1 << 24));
+                     value_in_comment = print_arm_address (pc, info, given | (1 << 24));
                      break;
 
                    case 's':
@@ -2727,26 +2857,29 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        }
                      else
                        {
+                         bfd_boolean negative = (given & 0x00800000) == 0;
+                         int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+
+                         if (negative)
+                           offset = -offset;
+
                          func (stream, "[%s",
                                arm_regnames[(given >> 16) & 0xf]);
+
                          if ((given & 0x01000000) != 0)
                            {
                               /* Pre-indexed.  */
                              if ((given & 0x00400000) == 0x00400000)
                                {
                                   /* Immediate.  */
-                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  if (offset)
-                                   func (stream, ", #%s%d",
-                                         (((given & 0x00800000) == 0)
-                                          ? "-" : ""), offset);
+                                   func (stream, ", #%d", offset);
+                                 value_in_comment = offset;
                                }
                              else
                                {
                                   /* Register.  */
-                                 func (stream, ", %s%s",
-                                       (((given & 0x00800000) == 0)
-                                        ? "-" : ""),
+                                 func (stream, ", %s%s", negative ? "-" : "",
                                         arm_regnames[given & 0xf]);
                                }
 
@@ -2759,20 +2892,17 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                              if ((given & 0x00400000) == 0x00400000)
                                {
                                   /* Immediate.  */
-                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  if (offset)
-                                   func (stream, "], #%s%d",
-                                         (((given & 0x00800000) == 0)
-                                          ? "-" : ""), offset);
+                                   func (stream, "], #%d", offset);
                                  else
                                    func (stream, "]");
+
+                                 value_in_comment = offset;
                                }
                              else
                                {
                                   /* Register.  */
-                                 func (stream, "], %s%s",
-                                       (((given & 0x00800000) == 0)
-                                        ? "-" : ""),
+                                 func (stream, "], %s%s", negative ? "-" : "",
                                         arm_regnames[given & 0xf]);
                                }
                            }
@@ -2782,7 +2912,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                    case 'b':
                      {
                        int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
-                       info->print_address_func (disp*4 + pc + 8, info);
+                       info->print_address_func (disp * 4 + pc + 8, info);
                      }
                      break;
 
@@ -2811,7 +2941,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'q':
-                     arm_decode_shift (given, func, stream, 0);
+                     arm_decode_shift (given, func, stream, FALSE);
                      break;
 
                    case 'o':
@@ -2819,12 +2949,14 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        {
                          int rotate = (given & 0xf00) >> 7;
                          int immed = (given & 0xff);
+
                          immed = (((immed << (32 - rotate))
                                    | (immed >> rotate)) & 0xffffffff);
-                         func (stream, "#%d\t; 0x%x", immed, immed);
+                         func (stream, "#%d", immed);
+                         value_in_comment = immed;
                        }
                      else
-                       arm_decode_shift (given, func, stream, 1);
+                       arm_decode_shift (given, func, stream, TRUE);
                      break;
 
                    case 'p':
@@ -2838,36 +2970,40 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case 'A':
-                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+                     {
+                       int offset = given & 0xff;
 
-                     if ((given & (1 << 24)) != 0)
-                       {
-                         int offset = given & 0xff;
+                       value_in_comment = offset * 4;
+                       if ((given & 0x00800000) == 0)
+                         value_in_comment = - value_in_comment;
 
-                         if (offset)
-                           func (stream, ", #%s%d]%s",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
-                                 offset * 4,
-                                 ((given & 0x00200000) != 0 ? "!" : ""));
-                         else
-                           func (stream, "]");
-                       }
-                     else
-                       {
-                         int offset = given & 0xff;
+                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                         func (stream, "]");
+                       if ((given & (1 << 24)) != 0)
+                         {
+                           if (offset)
+                             func (stream, ", #%d]%s",
+                                   value_in_comment,
+                                   ((given & 0x00200000) != 0 ? "!" : ""));
+                           else
+                             func (stream, "]");
+                         }
+                       else
+                         {
+                           func (stream, "]");
 
-                         if (given & (1 << 21))
-                           {
-                             if (offset)
-                               func (stream, ", #%s%d",
-                                     ((given & 0x00800000) == 0 ? "-" : ""),
-                                     offset * 4);
-                           }
-                         else
-                           func (stream, ", {%d}", offset);
-                       }
+                           if (given & (1 << 21))
+                             {
+                               if (offset)
+                                 func (stream, ", #%d", value_in_comment);
+                             }
+                           else
+                             {
+                               func (stream, ", {%d}", offset);
+                               value_in_comment = offset;
+                             }
+                         }
+                     }
                      break;
 
                    case 'B':
@@ -2908,12 +3044,12 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                    case 'U':
                      switch (given & 0xf)
                        {
-                       case 0xf: func(stream, "sy"); break;
-                       case 0x7: func(stream, "un"); break;
-                       case 0xe: func(stream, "st"); break;
-                       case 0x6: func(stream, "unst"); break;
+                       case 0xf: func (stream, "sy"); break;
+                       case 0x7: func (stream, "un"); break;
+                       case 0xe: func (stream, "st"); break;
+                       case 0x6: func (stream, "unst"); break;
                        default:
-                         func(stream, "#%d", (int)given & 0xf);
+                         func (stream, "#%d", (int) given & 0xf);
                          break;
                        }
                      break;
@@ -2933,12 +3069,15 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                            break;
                          case 'd':
                            func (stream, "%ld", value);
+                           value_in_comment = value;
                            break;
                          case 'b':
                            func (stream, "%ld", value * 8);
+                           value_in_comment = value * 8;
                            break;
                          case 'W':
                            func (stream, "%ld", value + 1);
+                           value_in_comment = value + 1;
                            break;
                          case 'x':
                            func (stream, "0x%08lx", value);
@@ -2952,6 +3091,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                            break;
                          case 'X':
                            func (stream, "%01lx", value & 0xf);
+                           value_in_comment = value;
                            break;
                          case '`':
                            c++;
@@ -2964,7 +3104,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                              func (stream, "%c", *c);
                            break;
                          case '?':
-                           func (stream, "%c", c[(1 << width) - (int)value]);
+                           func (stream, "%c", c[(1 << width) - (int) value]);
                            c += 1 << width;
                            break;
                          default:
@@ -2978,6 +3118,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 
                          imm = (given & 0xf) | ((given & 0xfff00) >> 4);
                          func (stream, "%d", imm);
+                         value_in_comment = imm;
                        }
                        break;
 
@@ -2987,8 +3128,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        {
                          long msb = (given & 0x001f0000) >> 16;
                          long lsb = (given & 0x00000f80) >> 7;
-
                          long width = msb - lsb + 1;
+
                          if (width > 0)
                            func (stream, "#%lu, #%lu", lsb, width);
                          else
@@ -3003,7 +3144,9 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          long hi = (given & 0x000f0000) >> 4;
                          long lo = (given & 0x00000fff);
                          long imm16 = hi | lo;
-                         func (stream, "#%lu\t; 0x%lx", imm16, imm16);
+
+                         func (stream, "#%lu", imm16);
+                         value_in_comment = imm16;
                        }
                        break;
 
@@ -3015,6 +3158,9 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
              else
                func (stream, "%c", *c);
            }
+
+         if (value_in_comment > 32 || value_in_comment < -16)
+           func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
          return;
        }
     }
@@ -3033,7 +3179,9 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
   for (insn = thumb_opcodes; insn->assembler; insn++)
     if ((given & insn->mask) == insn->value)
       {
+       signed long value_in_comment = 0;
        const char *c = insn->assembler;
+
        for (; *c; c++)
          {
            int domaskpc = 0;
@@ -3205,14 +3353,17 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 
                          case 'd':
                            func (stream, "%ld", reg);
+                           value_in_comment = reg;
                            break;
 
                          case 'H':
                            func (stream, "%ld", reg << 1);
+                           value_in_comment = reg << 1;
                            break;
 
                          case 'W':
                            func (stream, "%ld", reg << 2);
+                           value_in_comment = reg << 2;
                            break;
 
                          case 'a':
@@ -3221,6 +3372,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
                               before the calculation.  */
                            info->print_address_func
                              (((pc + 4) & ~3) + (reg << 2), info);
+                           value_in_comment = 0;
                            break;
 
                          case 'x':
@@ -3230,6 +3382,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
                          case 'B':
                            reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                            info->print_address_func (reg * 2 + pc + 4, info);
+                           value_in_comment = 0;
                            break;
 
                          case 'c':
@@ -3266,6 +3419,9 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
                abort ();
              }
          }
+
+       if (value_in_comment > 32 || value_in_comment < -16)
+         func (stream, "\t; 0x%lx", value_in_comment);
        return;
       }
 
@@ -3274,6 +3430,7 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 }
 
 /* Return the name of an V7M special register.  */
+
 static const char *
 psr_name (int regno)
 {
@@ -3315,7 +3472,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
   for (insn = thumb32_opcodes; insn->assembler; insn++)
     if ((given & insn->mask) == insn->value)
       {
+       signed long value_in_comment = 0;
        const char *c = insn->assembler;
+
        for (; *c; c++)
          {
            if (*c != '%')
@@ -3349,16 +3508,19 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 'I':
                {
                  unsigned int imm12 = 0;
+
                  imm12 |= (given & 0x000000ffu);
                  imm12 |= (given & 0x00007000u) >> 4;
                  imm12 |= (given & 0x04000000u) >> 15;
-                 func (stream, "#%u\t; 0x%x", imm12, imm12);
+                 func (stream, "#%u", imm12);
+                 value_in_comment = imm12;
                }
                break;
 
              case 'M':
                {
                  unsigned int bits = 0, imm, imm8, mod;
+
                  bits |= (given & 0x000000ffu);
                  bits |= (given & 0x00007000u) >> 4;
                  bits |= (given & 0x04000000u) >> 15;
@@ -3375,28 +3537,33 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      imm8 = (bits & 0x07f) | 0x80;
                      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
                    }
-                 func (stream, "#%u\t; 0x%x", imm, imm);
+                 func (stream, "#%u", imm);
+                 value_in_comment = imm;
                }
                break;
                  
              case 'J':
                {
                  unsigned int imm = 0;
+
                  imm |= (given & 0x000000ffu);
                  imm |= (given & 0x00007000u) >> 4;
                  imm |= (given & 0x04000000u) >> 15;
                  imm |= (given & 0x000f0000u) >> 4;
-                 func (stream, "#%u\t; 0x%x", imm, imm);
+                 func (stream, "#%u", imm);
+                 value_in_comment = imm;
                }
                break;
 
              case 'K':
                {
                  unsigned int imm = 0;
+
                  imm |= (given & 0x000f0000u) >> 16;
                  imm |= (given & 0x00000ff0u) >> 0;
                  imm |= (given & 0x0000000fu) << 12;
-                 func (stream, "#%u\t; 0x%x", imm, imm);
+                 func (stream, "#%u", imm);
+                 value_in_comment = imm;
                }
                break;
 
@@ -3448,14 +3615,19 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  int offset = 0;
 
                  func (stream, "[%s", arm_regnames[Rn]);
-                 if (U) /* 12-bit positive immediate offset */
-                   offset = i12;
-                 else if (Rn == 15) /* 12-bit negative immediate offset */
-                   offset = -(int)i12;
-                 else if (op == 0x0) /* shifted register offset */
+                 if (U) /* 12-bit positive immediate offset.  */
+                   {
+                     offset = i12;
+                     if (Rn != 15)
+                       value_in_comment = offset;
+                   }
+                 else if (Rn == 15) /* 12-bit negative immediate offset.  */
+                   offset = - (int) i12;
+                 else if (op == 0x0) /* Shifted register offset.  */
                    {
                      unsigned int Rm = (i8 & 0x0f);
                      unsigned int sh = (i8 & 0x30) >> 4;
+
                      func (stream, ", %s", arm_regnames[Rm]);
                      if (sh)
                        func (stream, ", lsl #%u", sh);
@@ -3464,30 +3636,30 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                    }
                  else switch (op)
                    {
-                   case 0xE:  /* 8-bit positive immediate offset */
+                   case 0xE:  /* 8-bit positive immediate offset */
                      offset = i8;
                      break;
 
-                   case 0xC:  /* 8-bit negative immediate offset */
+                   case 0xC:  /* 8-bit negative immediate offset */
                      offset = -i8;
                      break;
 
-                   case 0xF:  /* 8-bit + preindex with wb */
+                   case 0xF:  /* 8-bit + preindex with wb */
                      offset = i8;
                      writeback = TRUE;
                      break;
 
-                   case 0xD:  /* 8-bit - preindex with wb */
+                   case 0xD:  /* 8-bit - preindex with wb */
                      offset = -i8;
                      writeback = TRUE;
                      break;
 
-                   case 0xB:  /* 8-bit + postindex */
+                   case 0xB:  /* 8-bit + postindex */
                      offset = i8;
                      postind = TRUE;
                      break;
 
-                   case 0x9:  /* 8-bit - postindex */
+                   case 0x9:  /* 8-bit - postindex */
                      offset = -i8;
                      postind = TRUE;
                      break;
@@ -3527,7 +3699,10 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  if (P)
                    {
                      if (off || !U)
-                       func (stream, ", #%c%u", U ? '+' : '-', off * 4);
+                       {
+                         func (stream, ", #%c%u", U ? '+' : '-', off * 4);
+                         value_in_comment = off * 4 * U ? 1 : -1;
+                       }
                      func (stream, "]");
                      if (W)
                        func (stream, "!");
@@ -3536,9 +3711,15 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                    {
                      func (stream, "], ");
                      if (W)
-                       func (stream, "#%c%u", U ? '+' : '-', off * 4);
+                       {
+                         func (stream, "#%c%u", U ? '+' : '-', off * 4);
+                         value_in_comment = off * 4 * U ? 1 : -1;
+                       }
                      else
-                       func (stream, "{%u}", off);
+                       {
+                         func (stream, "{%u}", off);
+                         value_in_comment = off;
+                       }
                    }
                }
                break;
@@ -3547,6 +3728,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                {
                  unsigned int Sbit = (given & 0x01000000) >> 24;
                  unsigned int type = (given & 0x00600000) >> 21;
+
                  switch (type)
                    {
                    case 0: func (stream, Sbit ? "sb" : "b"); break;
@@ -3584,6 +3766,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                {
                  unsigned int msb = (given & 0x0000001f);
                  unsigned int lsb = 0;
+
                  lsb |= (given & 0x000000c0u) >> 6;
                  lsb |= (given & 0x00007000u) >> 10;
                  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
@@ -3594,6 +3777,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                {
                  unsigned int width = (given & 0x0000001f) + 1;
                  unsigned int lsb = 0;
+
                  lsb |= (given & 0x000000c0u) >> 6;
                  lsb |= (given & 0x00007000u) >> 10;
                  func (stream, "#%u, #%u", lsb, width);
@@ -3644,6 +3828,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 's':
                {
                  unsigned int shift = 0;
+
                  shift |= (given & 0x000000c0u) >> 6;
                  shift |= (given & 0x00007000u) >> 10;
                  if (given & 0x00200000u)
@@ -3657,6 +3842,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 'R':
                {
                  unsigned int rot = (given & 0x00000030) >> 4;
+
                  if (rot)
                    func (stream, ", ror #%u", rot * 8);
                }
@@ -3665,12 +3851,12 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 'U':
                switch (given & 0xf)
                  {
-                 case 0xf: func(stream, "sy"); break;
-                 case 0x7: func(stream, "un"); break;
-                 case 0xe: func(stream, "st"); break;
-                 case 0x6: func(stream, "unst"); break;
+                 case 0xf: func (stream, "sy"); break;
+                 case 0x7: func (stream, "un"); break;
+                 case 0xe: func (stream, "st"); break;
+                 case 0x6: func (stream, "unst"); break;
                  default:
-                   func(stream, "#%d", (int)given & 0xf);
+                   func (stream, "#%d", (int) given & 0xf);
                    break;
                  }
                break;
@@ -3711,8 +3897,14 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                        
                  switch (*c)
                    {
-                   case 'd': func (stream, "%lu", val); break;
-                   case 'W': func (stream, "%lu", val * 4); break;
+                   case 'd':
+                     func (stream, "%lu", val);
+                     value_in_comment = val;
+                     break;
+                   case 'W':
+                     func (stream, "%lu", val * 4);
+                     value_in_comment = val * 4;
+                     break;
                    case 'r': func (stream, "%s", arm_regnames[val]); break;
 
                    case 'c':
@@ -3732,7 +3924,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      break;
 
                    case '?':
-                     func (stream, "%c", c[(1 << width) - (int)val]);
+                     func (stream, "%c", c[(1 << width) - (int) val]);
                      c += 1 << width;
                      break;
 
@@ -3746,6 +3938,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                abort ();
              }
          }
+
+       if (value_in_comment > 32 || value_in_comment < -16)
+         func (stream, "\t; 0x%lx", value_in_comment);
        return;
       }
 
@@ -3756,7 +3951,8 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 /* Print data bytes on INFO->STREAM.  */
 
 static void
-print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
+print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
+                struct disassemble_info *info,
                 long given)
 {
   switch (info->bytes_per_chunk)
@@ -3852,8 +4048,10 @@ parse_disassembler_options (char *options)
 
 /* Search back through the insn stream to determine if this instruction is
    conditionally executed.  */
+
 static void
-find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
+find_ifthen_state (bfd_vma pc,
+                  struct disassemble_info *info,
                   bfd_boolean little)
 {
   unsigned char b[2];
@@ -3878,7 +4076,7 @@ find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
      IT instruction until we find a definite instruction boundary.  */
   for (;;)
     {
-      if (addr == 0 || info->symbol_at_address_func(addr, info))
+      if (addr == 0 || info->symbol_at_address_func (addr, info))
        {
          /* A symbol must be on an instruction boundary, and will not
             be within an IT block.  */
@@ -3888,7 +4086,7 @@ find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
          return;
        }
       addr -= 2;
-      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
+      status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
       if (status)
        return;
 
@@ -3932,7 +4130,8 @@ find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
    Returns nonzero if *MAP_TYPE was set.  */
 
 static int
-get_sym_code_type (struct disassemble_info *info, int n,
+get_sym_code_type (struct disassemble_info *info,
+                  int n,
                   enum map_type *map_type)
 {
   elf_symbol_type *es;
@@ -3950,7 +4149,7 @@ get_sym_code_type (struct disassemble_info *info, int n,
     }
 
   /* Check for mapping symbols.  */
-  name = bfd_asymbol_name(info->symtab[n]);
+  name = bfd_asymbol_name (info->symtab[n]);
   if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
       && (name[2] == 0 || name[2] == '.'))
     {
@@ -3963,6 +4162,47 @@ get_sym_code_type (struct disassemble_info *info, int n,
   return FALSE;
 }
 
+/* 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.
+
+   FIXME: This could more efficiently implemented as a constant array,
+   although it would also be less robust.  */
+
+static void
+select_arm_features (unsigned long mach,
+                    arm_feature_set * features)
+{
+#undef  ARM_FEATURE
+#define ARM_FEATURE(ARCH,CEXT) \
+  features->core = (ARCH); \
+  features->coproc = (CEXT) | FPU_FPA; \
+  return
+
+  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 (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 (-1UL, -1UL);
+    default:
+      abort ();
+    }
+}
+
+
 /* NOTE: There are no checks in these routines that
    the relevant number of data bytes exist.  */
 
@@ -3974,6 +4214,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
   int           status;
   int           is_thumb = FALSE;
   int           is_data = FALSE;
+  int           little_code;
   unsigned int size = 4;
   void         (*printer) (bfd_vma, struct disassemble_info *, long);
   bfd_boolean   found = FALSE;
@@ -3986,9 +4227,47 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       info->disassembler_options = NULL;
     }
 
+  /* PR 10288: Control which instructions will be disassembled.  */
+  if (info->private_data == NULL)
+    {
+      static arm_feature_set features;
+
+      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
+          machine value (iWMMXt2), which is only equivalent to the V5TE
+          architecture.  ARM architectures have advanced beyond the machine
+          value encoding, and these newer architectures would be ignored if
+          the machine value was used.
+
+          Ie the -m switch is used to restrict which instructions will be
+          disassembled.  If it is necessary to use the -m switch to tell
+          objdump that an ARM binary is being disassembled, eg because the
+          input is a raw binary file, but it is also desired to disassemble
+          all ARM instructions then use "-marm".  This will select the
+          "unknown" arm architecture which is compatible with any ARM
+          instruction.  */
+         info->mach = bfd_mach_arm_unknown;
+
+      /* Compute the architecture bitmask from the machine number.
+        Note: This assumes that the machine number will not change
+        during disassembly....  */
+      select_arm_features (info->mach, & features);
+
+      info->private_data = & features;
+    }
+  
+  /* Decide if our code is going to be little-endian, despite what the
+     function argument might say.  */
+  little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
+
   /* First check the full symtab for a mapping symbol, even if there
      are no usable non-mapping symbols for this address.  */
-  if (info->symtab != NULL
+  if (info->symtab_size != 0
       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
     {
       bfd_vma addr;
@@ -4031,7 +4310,9 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
             for a preceeding one.  */
          for (; n >= 0; n--)
            {
-             if (get_sym_code_type (info, n, &type))
+             if ((info->section == NULL
+                  || info->section == info->symtab[n]->section)
+                 && get_sym_code_type (info, n, &type))
                {
                  last_sym = n;
                  found = TRUE;
@@ -4101,18 +4382,23 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
   if (force_thumb)
     is_thumb = TRUE;
 
-  info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
+  if (is_data)
+    info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
+  else
+    info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
+
   info->bytes_per_line = 4;
 
-  if (is_data)
+  /* PR 10263: Disassemble data if requested to do so by the user.  */
+  if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
     {
       int i;
 
-      /* size was already set above.  */
+      /* Size was already set above.  */
       info->bytes_per_chunk = size;
       printer = print_insn_data;
 
-      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
+      status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
       given = 0;
       if (little)
        for (i = size - 1; i >= 0; i--)
@@ -4129,8 +4415,8 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       info->bytes_per_chunk = 4;
       size = 4;
 
-      status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
-      if (little)
+      status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
+      if (little_code)
        given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
       else
        given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
@@ -4145,8 +4431,8 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       info->bytes_per_chunk = 2;
       size = 2;
 
-      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
-      if (little)
+      status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
+      if (little_code)
        given = (b[0]) | (b[1] << 8);
       else
        given = (b[1]) | (b[0] << 8);
@@ -4159,8 +4445,8 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
              || (given & 0xF800) == 0xF000
              || (given & 0xF800) == 0xE800)
            {
-             status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
-             if (little)
+             status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
+             if (little_code)
                given = (b[0]) | (b[1] << 8) | (given << 16);
              else
                given = (b[1]) | (b[0] << 8) | (given << 16);
@@ -4171,7 +4457,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
        }
 
       if (ifthen_address != pc)
-       find_ifthen_state(pc, info, little);
+       find_ifthen_state (pc, info, little_code);
 
       if (ifthen_state)
        {
@@ -4209,6 +4495,12 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
 int
 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
 {
+  /* Detect BE8-ness and record it in the disassembler info.  */
+  if (info->flavour == bfd_target_elf_flavour
+      && info->section != NULL
+      && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
+    info->endian_code = BFD_ENDIAN_LITTLE;
+
   return print_insn (pc, info, FALSE);
 }