PR binutils/10924
authorNick Clifton <nickc@redhat.com>
Wed, 11 Nov 2009 09:44:45 +0000 (09:44 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 11 Nov 2009 09:44:45 +0000 (09:44 +0000)
        * arm-dis.c (UNPREDICTABLE_INSTRUCTION): New macro.
        (print_insn_arm): Extend %s format control code to check for
        unpredictable addressing modes.  Add support for %S format control
        code which suppresses this check.
        (W_BIT, I_BIT, U_BIT, P_BIT): New macros.
        (WRITEBACK_BIT_SET, IMMEDIATE_BIT_SET, NEGATIVE_BIT_SET,
        PRE_BIT_SET): New macros.
        (print_insn_coprocessor): Use the new macros instead of magic
        constants.
        (print_arm_address): Likewise.
        (pirnt_insn_arm): Likewise.
        (print_insn_thumb32): Likewise.

opcodes/ChangeLog
opcodes/arm-dis.c

index a8854ea2b9db7ab2865f07ec0dd3b8a544294516..e0f48e973cd5a12ad908fe07ddb67661bef414dc 100644 (file)
@@ -1,3 +1,19 @@
+2009-11-11  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/10924
+       * arm-dis.c (UNPREDICTABLE_INSTRUCTION): New macro.
+       (print_insn_arm): Extend %s format control code to check for
+       unpredictable addressing modes.  Add support for %S format control
+       code which suppresses this check.
+       (W_BIT, I_BIT, U_BIT, P_BIT): New macros.
+       (WRITEBACK_BIT_SET, IMMEDIATE_BIT_SET, NEGATIVE_BIT_SET,
+       PRE_BIT_SET): New macros.
+       (print_insn_coprocessor): Use the new macros instead of magic
+       constants.
+       (print_arm_address): Likewise.
+       (pirnt_insn_arm): Likewise.
+       (print_insn_thumb32): Likewise.
+
 2009-11-11  Nick Clifton  <nickc@redhat.com>
 
        * po/id.po: Updated Indonesian translation.
index 1616fed92d406ef28c3dda8f5c37b0ee7f69644a..28e503e81c8f2f438648340450361bfd4e96bd2f 100644 (file)
@@ -113,7 +113,8 @@ enum opcode_sentinel_enum
   SENTINEL_GENERIC_START
 } opcode_sentinels;
 
-#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
+#define UNDEFINED_INSTRUCTION      "undefined instruction %0-31x"
+#define UNPREDICTABLE_INSTRUCTION  "\t; <UNPREDICTABLE>"
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
 
@@ -776,6 +777,7 @@ static const struct opcode32 neon_opcodes[] =
 
    %a                  print address for ldr/str instruction
    %s                   print address for ldr/str halfword/signextend instruction
+   %S                   like %s but allow UNPREDICTABLE addressing
    %b                  print branch destination
    %c                  print condition code (always bits 28-31)
    %m                  print register mask for ldm/stm instruction
@@ -823,8 +825,8 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
   {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
   {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
-  {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
-  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
+  {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
+  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %S"},
   {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
   {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
   {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
@@ -1701,6 +1703,16 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
     }
 }
 
+#define W_BIT 21
+#define I_BIT 22
+#define U_BIT 23
+#define P_BIT 24
+
+#define WRITEBACK_BIT_SET   (given & (1 << W_BIT))
+#define IMMEDIATE_BIT_SET   (given & (1 << I_BIT))
+#define NEGATIVE_BIT_SET   ((given & (1 << U_BIT)) == 0)
+#define PRE_BIT_SET         (given & (1 << P_BIT))
+
 /* Print one coprocessor instruction on INFO->STREAM.
    Return TRUE if the instuction matched, FALSE if this is not a
    recognised coprocessor instruction.  */
@@ -1801,15 +1813,15 @@ print_insn_coprocessor (bfd_vma pc,
                    func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
                    value_in_comment = offset * 4;
-                   if ((given & 0x00800000) == 0)
+                   if (NEGATIVE_BIT_SET)
                      value_in_comment = - value_in_comment;
                    
-                   if ((given & (1 << 24)) != 0)
+                   if (PRE_BIT_SET)
                      {
                        if (offset)
                          func (stream, ", #%d]%s",
                                value_in_comment,
-                               ((given & 0x00200000) != 0 ? "!" : ""));
+                               WRITEBACK_BIT_SET ? "!" : "");
                        else
                          func (stream, "]");
                      }
@@ -1817,7 +1829,7 @@ print_insn_coprocessor (bfd_vma pc,
                      {
                        func (stream, "]");
 
-                       if (given & (1 << 21))
+                       if (WRITEBACK_BIT_SET)
                          {
                            if (offset)
                              func (stream, ", #%d", value_in_comment);
@@ -1849,14 +1861,13 @@ print_insn_coprocessor (bfd_vma pc,
                  {
                    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;
+                       if (NEGATIVE_BIT_SET)
+                         offset = - offset;
                        func (stream, ", #%d", offset);
                        if (rn != 15)
                          value_in_comment = offset;
@@ -2159,20 +2170,20 @@ print_insn_coprocessor (bfd_vma pc,
                      if (multiplier > 1)
                        {
                          value_in_comment = offset * multiplier;
-                         if ((given & 0x00800000) == 0)
+                         if (NEGATIVE_BIT_SET)
                            value_in_comment = - value_in_comment;
                        }
 
                      if (offset)
                        {
-                         if ((given & 0x01000000) != 0)
+                         if (PRE_BIT_SET)
                            func (stream, ", #%s%d]%s",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 NEGATIVE_BIT_SET ? "-" : "",
                                  offset * multiplier,
-                                 ((given & 0x00200000) != 0 ? "!" : ""));
+                                 WRITEBACK_BIT_SET ? "!" : "");
                          else
                            func (stream, "], #%s%d",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 NEGATIVE_BIT_SET ? "-" : "",
                                  offset * multiplier);
                        }
                      else
@@ -2183,8 +2194,8 @@ print_insn_coprocessor (bfd_vma pc,
                  case 'r':
                    {
                      int imm4 = (given >> 4) & 0xf;
-                     int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
-                     int ubit = (given >> 23) & 1;
+                     int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
+                     int ubit = ! NEGATIVE_BIT_SET;
                      const char *rm = arm_regnames [given & 0xf];
                      const char *rn = arm_regnames [(given >> 16) & 0xf];
 
@@ -2259,9 +2270,9 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
 
       func (stream, "[pc");
 
-      if (given & 0x01000000)
+      if (PRE_BIT_SET)
        {
-         if ((given & 0x00800000) == 0)
+         if (NEGATIVE_BIT_SET)
            offset = - offset;
 
          /* Pre-indexed.  */
@@ -2273,15 +2284,14 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
             being used.  Probably a very dangerous thing
             for the programmer to do, but who are we to
             argue ?  */
-         if (given & 0x00200000)
+         if (WRITEBACK_BIT_SET)
            func (stream, "!");
        }
-      else
+      else  /* Post indexed.  */
        {
-         /* Post indexed.  */
          func (stream, "], #%d", offset);
 
-         /* ie ignore the offset.  */
+         /* Ie ignore the offset.  */
          offset = pc + 8;
        }
 
@@ -2293,26 +2303,25 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
     {
       func (stream, "[%s",
            arm_regnames[(given >> 16) & 0xf]);
-      if ((given & 0x01000000) != 0)
+
+      if (PRE_BIT_SET)
        {
          if ((given & 0x02000000) == 0)
            {
              offset = given & 0xfff;
              if (offset)
                func (stream, ", #%s%d",
-                     (((given & 0x00800000) == 0)
-                      ? "-" : ""), offset);
+                     NEGATIVE_BIT_SET ? "-" : "", offset);
            }
          else
            {
              func (stream, ", %s",
-                   (((given & 0x00800000) == 0)
-                    ? "-" : ""));
+                   NEGATIVE_BIT_SET ? "-" : "");
              arm_decode_shift (given, func, stream, TRUE);
            }
 
          func (stream, "]%s",
-               ((given & 0x00200000) != 0) ? "!" : "");
+               WRITEBACK_BIT_SET ? "!" : "");
        }
       else
        {
@@ -2321,16 +2330,14 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
              offset = given & 0xfff;
              if (offset)
                func (stream, "], #%s%d",
-                     (((given & 0x00800000) == 0)
-                      ? "-" : ""), offset);
+                     NEGATIVE_BIT_SET ? "-" : "", offset);
              else
                func (stream, "]");
            }
          else
            {
              func (stream, "], %s",
-                   (((given & 0x00800000) == 0)
-                    ? "-" : ""));
+                   NEGATIVE_BIT_SET ? "-" : "");
              arm_decode_shift (given, func, stream, TRUE);
            }
        }
@@ -2669,16 +2676,16 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                                 valbytes[3] = (value >> 24) & 0xff;
                                 
                                 floatformat_to_double 
-                                  (&floatformat_ieee_single_little, valbytes,
-                                  &fvalue);
+                                  (& floatformat_ieee_single_little, valbytes,
+                                  & fvalue);
                                                                 
                                 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
                                       value);
                               }
                             else
                               func (stream, "#%ld\t; 0x%.8lx",
-                               (long) ((value & 0x80000000)
-                                       ? value | ~0xffffffffl : value), value);
+                                   (long) (NEGATIVE_BIT_SET ? value | ~0xffffffffL : value),
+                                   value);
                             break;
 
                           case 64:
@@ -2841,6 +2848,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
            {
              if (*c == '%')
                {
+                 bfd_boolean allow_unpredictable = FALSE;
+
                  switch (*++c)
                    {
                    case '%':
@@ -2854,58 +2863,54 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                    case 'P':
                      /* Set P address bit and use normal address
                         printing routine.  */
-                     value_in_comment = print_arm_address (pc, info, given | (1 << 24));
+                     value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
                      break;
 
+                   case 'S':
+                     allow_unpredictable = TRUE;
                    case 's':
                       if ((given & 0x004f0000) == 0x004f0000)
                        {
                           /* PC relative with immediate offset.  */
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
 
-                         if ((given & 0x00800000) == 0)
-                           offset = -offset;
+                         if (NEGATIVE_BIT_SET)
+                           offset = - offset;
 
                          func (stream, "[pc, #%d]\t; ", offset);
                          info->print_address_func (offset + pc + 8, info);
                        }
                      else
                        {
-                         bfd_boolean negative = (given & 0x00800000) == 0;
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
 
-                         if (negative)
-                           offset = -offset;
+                         if (NEGATIVE_BIT_SET)
+                           offset = - offset;
 
                          func (stream, "[%s",
                                arm_regnames[(given >> 16) & 0xf]);
 
-                         if ((given & 0x01000000) != 0)
+                         if (PRE_BIT_SET)
                            {
                               /* Pre-indexed.  */
-                             if ((given & 0x00400000) == 0x00400000)
+                             if (IMMEDIATE_BIT_SET)
                                {
-                                  /* Immediate.  */
                                  if (offset)
                                    func (stream, ", #%d", offset);
                                  value_in_comment = offset;
                                }
-                             else
-                               {
-                                  /* Register.  */
-                                 func (stream, ", %s%s", negative ? "-" : "",
-                                        arm_regnames[given & 0xf]);
-                               }
+                             else /* Register.  */
+                               func (stream, ", %s%s",
+                                     NEGATIVE_BIT_SET ? "-" : "",
+                                     arm_regnames[given & 0xf]);
 
                              func (stream, "]%s",
-                                   ((given & 0x00200000) != 0) ? "!" : "");
+                                   WRITEBACK_BIT_SET ? "!" : "");
                            }
-                         else
+                         else /* Post-indexed.  */
                            {
-                              /* Post-indexed.  */
-                             if ((given & 0x00400000) == 0x00400000)
+                             if (IMMEDIATE_BIT_SET)
                                {
-                                  /* Immediate.  */
                                  if (offset)
                                    func (stream, "], #%d", offset);
                                  else
@@ -2913,12 +2918,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 
                                  value_in_comment = offset;
                                }
-                             else
-                               {
-                                  /* Register.  */
-                                 func (stream, "], %s%s", negative ? "-" : "",
-                                        arm_regnames[given & 0xf]);
-                               }
+                             else /* Register.  */
+                               func (stream, "], %s%s",
+                                     NEGATIVE_BIT_SET ? "-" : "",
+                                     arm_regnames[given & 0xf]);
+
+                             if (WRITEBACK_BIT_SET && ! allow_unpredictable)
+                               func (stream, UNPREDICTABLE_INSTRUCTION);
                            }
                        }
                      break;
@@ -2988,17 +2994,17 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        int offset = given & 0xff;
 
                        value_in_comment = offset * 4;
-                       if ((given & 0x00800000) == 0)
+                       if (NEGATIVE_BIT_SET)
                          value_in_comment = - value_in_comment;
 
                        func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                       if ((given & (1 << 24)) != 0)
+                       if (PRE_BIT_SET)
                          {
                            if (offset)
                              func (stream, ", #%d]%s",
                                    value_in_comment,
-                                   ((given & 0x00200000) != 0 ? "!" : ""));
+                                   WRITEBACK_BIT_SET ? "!" : "");
                            else
                              func (stream, "]");
                          }
@@ -3006,7 +3012,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          {
                            func (stream, "]");
 
-                           if (given & (1 << 21))
+                           if (WRITEBACK_BIT_SET)
                              {
                                if (offset)
                                  func (stream, ", #%d", value_in_comment);
@@ -3026,7 +3032,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        bfd_vma address;
                        bfd_vma offset = 0;
 
-                       if (given & 0x00800000)
+                       if (! NEGATIVE_BIT_SET)
                          /* Is signed, hi bits should be ones.  */
                          offset = (-1) ^ 0x00ffffff;
 
@@ -3543,9 +3549,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  switch (mod)
                    {
                    case 0: imm = imm8; break;
-                   case 1: imm = ((imm8<<16) | imm8); break;
-                   case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
-                   case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
+                   case 1: imm = ((imm8 << 16) | imm8); break;
+                   case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
+                   case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
                    default:
                      mod  = (bits & 0xf80) >> 7;
                      imm8 = (bits & 0x07f) | 0x80;
@@ -3621,7 +3627,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 'a':
                {
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
-                 unsigned int U   = (given & 0x00800000) >> 23;
+                 unsigned int U   = ! NEGATIVE_BIT_SET;
                  unsigned int op  = (given & 0x00000f00) >> 8;
                  unsigned int i12 = (given & 0x00000fff);
                  unsigned int i8  = (given & 0x000000ff);
@@ -3703,14 +3709,14 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 
              case 'A':
                {
-                 unsigned int P   = (given & 0x01000000) >> 24;
-                 unsigned int U   = (given & 0x00800000) >> 23;
-                 unsigned int W   = (given & 0x00400000) >> 21;
+                 unsigned int U   = ! NEGATIVE_BIT_SET;
+                 unsigned int W   = WRITEBACK_BIT_SET;
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
                  unsigned int off = (given & 0x000000ff);
 
                  func (stream, "[%s", arm_regnames[Rn]);
-                 if (P)
+
+                 if (PRE_BIT_SET)
                    {
                      if (off || !U)
                        {
@@ -3845,7 +3851,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 
                  shift |= (given & 0x000000c0u) >> 6;
                  shift |= (given & 0x00007000u) >> 10;
-                 if (given & 0x00200000u)
+                 if (WRITEBACK_BIT_SET)
                    func (stream, ", asr #%u", shift);
                  else if (shift)
                    func (stream, ", lsl #%u", shift);