PR 10288
authorNick Clifton <nickc@redhat.com>
Thu, 18 Jun 2009 10:31:21 +0000 (10:31 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 18 Jun 2009 10:31:21 +0000 (10:31 +0000)
        * arm-dis.c (print_insn_coprocessor): Check that a user specified
        ARM architecture supports the matched instruction.
        (print_insn_arm): Likewise.
        (select_arm_features): New function.  Fills in the fields of an
        arm_feature_set structure based on a given arm machine number.
        (print_insn): Initialise an arm_feature_set structure.

        * objdump.c (disassemble_bytes): Set the
        USER_SPECIFIED_MACHINE_TYPE flag in the disassemble_info structure
        if the user has invoked the -m switch.
        * doc/binutils.texi: Document the additional behaviour of
        objdump's -m switch for ARM targets.

        * dis-asm.h (USER_SPECIFIED_MACHINE_TYPE): New value for the flags
        field of struct disassemble_info.

        * gas/arm/align.s: Add labels so that COFF based targets can
        correctly locate THUMB code.
        * gas/arm/copro.d: Do not pass --architecture switch to objdump.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/objdump.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/align.s
gas/testsuite/gas/arm/copro.d
include/ChangeLog
include/dis-asm.h
opcodes/ChangeLog
opcodes/arm-dis.c

index f7974f706efeed4421b18ddc7b098210b642f4fd..ddacde192faf2490267476817b68cbc2782f32eb 100644 (file)
@@ -1,8 +1,18 @@
+2009-06-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 10288
+       * objdump.c (disassemble_bytes): Set the
+       USER_SPECIFIED_MACHINE_TYPE flag in the disassemble_info structure
+       if the user has invoked the -m switch.
+       * doc/binutils.texi: Document the additional behaviour of
+       objdump's -m switch for ARM targets.
+
 2009-06-18  Dave Korn  <dave.korn.cygwin@gmail.com>
 
-  Merge cegcc and mingw32ce target name changes from CeGCC project.
+       * configure.in: Merge cegcc and mingw32ce target name changes from
+       CeGCC project.
 
-  2007-12-25  Pedro Alves  <pedro_alves@portugalmail.pt>
+2007-12-25  Pedro Alves  <pedro_alves@portugalmail.pt>
 
        * configure.in: Add arm*-*-cegcc* and arm*-*-mingw32ce* targets.
        * configure: Regenerate.
index 7680c6f3ae7f14312bbaaa57b158eee80185027c..d74b12b86b2a06ad0a796ad47501fac494ef81ea 100644 (file)
@@ -1801,6 +1801,10 @@ expected to contain instructions.
 Like @option{-d}, but disassemble the contents of all sections, not just
 those expected to contain instructions.
 
+If the target is an ARM architecture this switch also has the effect
+of forcing the disassembler to decode pieces of data found in code
+sections as if they were instructions.
+
 @item --prefix-addresses
 When disassembling, print the complete address on each line.  This is
 the older disassembly format.
@@ -1884,6 +1888,13 @@ can be useful when disassembling object files which do not describe
 architecture information, such as S-records.  You can list the available
 architectures with the @option{-i} option.
 
+If the target is an ARM architecture then this switch has an
+additional effect.  It restricts the disassembly to only those
+instructions supported by the architecture specified by @var{machine}.
+If it is necessary to use this switch because the input file does not
+contain any architecture information, but it is also desired to
+disassemble all the instructions use @option{-marm}.
+
 @item -M @var{options}
 @itemx --disassembler-options=@var{options}
 Pass target specific information to the disassembler.  Only supported on
index 3cf03f7eddbe8cc773974999678f0666e2455f53..dfe6a57e16e1339178461f71a4bb8227030cc006 100644 (file)
@@ -1526,6 +1526,8 @@ disassemble_bytes (struct disassemble_info * info,
              info->bytes_per_line = 0;
              info->bytes_per_chunk = 0;
              info->flags = disassemble_all ? DISASSEMBLE_DATA : 0;
+             if (machine)
+               info->flags |= USER_SPECIFIED_MACHINE_TYPE;
 
              if (info->disassembler_needs_relocs
                  && (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
index b2fba43ebe0507d911e524493494f4c9c2fbe7c4..5bac61e29348cc4ec31a8d7847298e8c921076b3 100644 (file)
@@ -1,3 +1,10 @@
+2009-06-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 10288
+       * gas/arm/align.s: Add labels so that COFF based targets can
+       correctly locate THUMB code.
+       * gas/arm/copro.d: Do not pass --architecture switch to objdump.
+
 2009-06-15  Nick Clifton  <nickc@redhat.com>
 
        PR gas/10186
index 43c73ca9a4c0e4a2c6c5cdb650b221e69c99732d..7ed8fbb8694e9274446bb16a1fb98c06a6226cf8 100644 (file)
@@ -1,5 +1,7 @@
        .syntax unified
        .thumb
+       .global foo
+foo:   
        nop
        mov r1,r2
        .p2align 4
@@ -7,6 +9,8 @@
        .p2align 3
 
        .arm
+       .global bar
+bar:   
        nop
        mov r1,r2
        .p2align 4
index ce7903139c71b0379392d532b8d9ee7905e47373..e97d6c430f645df3e1ae451fed68ed8fac30db54 100644 (file)
@@ -1,4 +1,4 @@
-#objdump: -dr --prefix-addresses --show-raw-insn --architecture=armv5te
+#objdump: -dr --prefix-addresses --show-raw-insn 
 #name: ARM CoProcessor Instructions
 #as: -march=armv5te -EL
 
index 6742d24c951061a3322c950e5d3987da70fe096e..8f857749e41c9f974ec4357ecf141d212b2b48de 100644 (file)
@@ -1,11 +1,16 @@
+2009-06-18  Nick Clifton  <nickc@redhat.com>
+
+       * dis-asm.h (USER_SPECIFIED_MACHINE_TYPE): New value for the flags
+       field of struct disassemble_info.
+
 2009-06-09  Ian Lance Taylor  <ian@airs.com>
 
        * ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define for C++.
 
 2009-06-15  Nick Clifton  <nickc@redhat.com>
 
-       * dis-asm.h (struct disassemble_info): New value for the flags
-       field.
+       * dis-asm.h (DISASSEMBLE_DATA): New value for the flags field of
+       struct disassemble_info.
 
 2009-06-02  Ian Lance Taylor  <iant@google.com>
 
index 3872f8b2d427eb7ebe6447b98ac3d472fa7761a7..b7949c177af234cf0d3b5ac9eea15b593cd8eb04 100644 (file)
@@ -113,6 +113,9 @@ typedef struct disassemble_info
 #define INSN_HAS_RELOC  (1 << 31)
   /* Set if the user has requested the disassembly of data as well as code.  */
 #define DISASSEMBLE_DATA (1 << 30)
+  /* Set if the user has specifically set the machine type encoded in the
+     mach field of this structure.  */
+#define USER_SPECIFIED_MACHINE_TYPE (1 << 29)
 
   /* Use internally by the target specific disassembly code.  */
   void *private_data;
index 156a82a0d2959dd079c5365c2a1ee3edd454a160..a3a226350b6542d9249880a41f2ef3ffcd77a773 100644 (file)
@@ -1,3 +1,13 @@
+2009-06-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 10288
+       * arm-dis.c (print_insn_coprocessor): Check that a user specified
+       ARM architecture supports the matched instruction.
+       (print_insn_arm): Likewise.
+       (select_arm_features): New function.  Fills in the fields of an
+       arm_feature_set structure based on a given arm machine number.
+       (print_insn): Initialise an arm_feature_set structure.
+
 2009-06-16  Maciej W. Rozycki  <macro@linux-mips.org>
 
        * vax-dis.c (is_function_entry): Return success for synthetic
index ce724a5f6a792efad839db1597aa0d7408ff8453..fb21f06a5ab5fff57a742307bd2e54d34ea7a9e5 100644 (file)
@@ -1635,6 +1635,8 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
 
   for (insn = coprocessor_opcodes; insn->assembler; insn++)
     {
+      const char *c;
+
       if (insn->value == FIRST_IWMMXT_INSN
          && info->mach != bfd_mach_arm_XScale
          && info->mach != bfd_mach_arm_iWMMXt
@@ -1671,447 +1673,447 @@ 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 & ((arm_feature_set *) info->private_data)->coproc) == 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)
                    {
-                   case '%':
-                     func (stream, "%%");
-                     break;
+                     int offset = given & 0xff;
 
-                   case 'A':
-                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+                     if (offset)
+                       func (stream, ", #%s%d]%s",
+                             ((given & 0x00800000) == 0 ? "-" : ""),
+                             offset * 4,
+                             ((given & 0x00200000) != 0 ? "!" : ""));
+                     else
+                       func (stream, "]");
+                   }
+                 else
+                   {
+                     int offset = given & 0xff;
 
-                     if ((given & (1 << 24)) != 0)
-                       {
-                         int offset = given & 0xff;
+                     func (stream, "]");
 
+                     if (given & (1 << 21))
+                       {
                          if (offset)
-                           func (stream, ", #%s%d]%s",
+                           func (stream, ", #%s%d",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
-                                 offset * 4,
-                                 ((given & 0x00200000) != 0 ? "!" : ""));
-                         else
-                           func (stream, "]");
+                                 offset * 4);
                        }
                      else
-                       {
-                         int offset = given & 0xff;
+                       func (stream, ", {%d}", offset);
+                   }
+                 break;
 
-                         func (stream, "]");
+               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;
 
-                         if (given & (1 << 21))
-                           {
-                             if (offset)
-                               func (stream, ", #%s%d",
-                                     ((given & 0x00800000) == 0 ? "-" : ""),
-                                     offset * 4);
-                           }
-                         else
-                           func (stream, ", {%d}", offset);
-                       }
-                     break;
+               case 'C':
+                 {
+                   int rn = (given >> 16) & 0xf;
+                   int offset = (given & 0xff) * 4;
+                   int add = (given >> 23) & 1;
 
-                   case 'B':
+                   func (stream, "[%s", arm_regnames[rn]);
+
+                   if (offset)
                      {
-                       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);
+                       if (!add)
+                         offset = -offset;
+                       func (stream, ", #%d", offset);
                      }
-                     break;
-                     
-                   case 'C':
+                   func (stream, "]");
+                   if (rn == 15)
                      {
-                       int rn = (given >> 16) & 0xf;
-                       int offset = (given & 0xff) * 4;
-                       int add = (given >> 23) & 1;
-                       
-                       func (stream, "[%s", arm_regnames[rn]);
-                       
-                       if (offset)
-                         {
-                           if (!add)
-                             offset = -offset;
-                           func (stream, ", #%d", offset);
-                         }
-                       func (stream, "]");
-                       if (rn == 15)
-                         {
-                           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, "\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;
+                 }
+                 break;
 
-                   case 'c':
-                     func (stream, "%s", arm_conditional[cond]);
-                     break;
+               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;
+               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;
 
-                       imm = (given & 0xf) | ((given & 0xe0) >> 1);
+                   imm = (given & 0xf) | ((given & 0xe0) >> 1);
 
-                       /* Is ``imm'' a negative number?  */
-                       if (imm & 0x40)
-                         imm |= (-1 << 7);
+                   /* Is ``imm'' a negative number?  */
+                   if (imm & 0x40)
+                     imm |= (-1 << 7);
 
-                       func (stream, "%d", imm);
-                     }
+                   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);
+                       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':
-                       {
-                         int single = *c++ == 'y';
-                         int regno;
-                         
-                         switch (*c)
-                           {
-                           case '4': /* Sm pair */
-                           case '0': /* Sm, Dm */
-                             regno = given & 0x0000000f;
-                             if (single)
-                               {
-                                 regno <<= 1;
-                                 regno += (given >> 5) & 1;
-                               }
-                              else
-                                regno += ((given >> 5) & 1) << 4;
-                             break;
+                     case 'x':
+                       func (stream, "0x%lx", value);
+                       break;
 
-                           case '1': /* Sd, Dd */
-                             regno = (given >> 12) & 0x0000000f;
-                             if (single)
-                               {
-                                 regno <<= 1;
-                                 regno += (given >> 22) & 1;
-                               }
-                              else
-                                regno += ((given >> 22) & 1) << 4;
-                             break;
+                     case '`':
+                       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 '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 'y':
+                 case 'z':
+                   {
+                     int single = *c++ == 'y';
+                     int regno;
+
+                     switch (*c)
+                       {
+                       case '4': /* Sm pair */
+                       case '0': /* Sm, Dm */
+                         regno = given & 0x0000000f;
+                         if (single)
+                           {
+                             regno <<= 1;
+                             regno += (given >> 5) & 1;
                            }
+                         else
+                           regno += ((given >> 5) & 1) << 4;
+                         break;
 
-                         func (stream, "%c%d", single ? 's' : 'd', regno);
+                       case '1': /* Sd, Dd */
+                         regno = (given >> 12) & 0x0000000f;
+                         if (single)
+                           {
+                             regno <<= 1;
+                             regno += (given >> 22) & 1;
+                           }
+                         else
+                           regno += ((given >> 22) & 1) << 4;
+                         break;
 
-                         if (*c == '3')
+                       case '2': /* Sn, Dn */
+                         regno = (given >> 16) & 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 >> 7) & 1;
                            }
-                         else if (*c == '4')
-                           func (stream, ", %c%d", single ? 's' : 'd',
-                                 regno + 1);
-                       }
-                       break;
+                         else
+                           regno += ((given >> 7) & 1) << 4;
+                         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 '3': /* List */
+                         func (stream, "{");
+                         regno = (given >> 12) & 0x0000000f;
+                         if (single)
+                           {
+                             regno <<= 1;
+                             regno += (given >> 22) & 1;
+                           }
+                         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;
-
-                           default:
-                             func (stream, "INVALID");
-                           }
+                 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;
+
+                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+
+                     if (offset)
+                       {
+                         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;
+
+                 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 'i':
+                     switch (puw_bits)
                        {
-                         long imm5;
-                         imm5 = ((given & 0x100) >> 4) | (given & 0xf);
-                         func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
+                       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;
+                   }
+                   break;
 
-                     default:
-                       abort ();
-                     }
+                 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);
        }
+      return TRUE;
     }
   return FALSE;
 }
@@ -2221,7 +2223,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;
@@ -2687,13 +2689,18 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
          && 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))
        {
          const char *c;
 
@@ -3967,6 +3974,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.  */
 
@@ -3991,6 +4039,40 @@ 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);
@@ -4146,7 +4228,7 @@ 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);
+      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
@@ -4176,7 +4258,7 @@ 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);
+             status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
              if (little_code)
                given = (b[0]) | (b[1] << 8) | (given << 16);
              else
@@ -4188,7 +4270,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
        }
 
       if (ifthen_address != pc)
-       find_ifthen_state(pc, info, little_code);
+       find_ifthen_state (pc, info, little_code);
 
       if (ifthen_state)
        {