Refactor arm_stack_frame_destroyed_p
[external/binutils.git] / gdb / arm-tdep.c
index 2eb7bb1..6ede3a9 100644 (file)
@@ -3124,19 +3124,14 @@ thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return found_stack_adjust;
 }
 
-/* Implement the stack_frame_destroyed_p gdbarch method.  */
-
 static int
-arm_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+arm_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
   unsigned int insn;
   int found_return;
   CORE_ADDR func_start, func_end;
 
-  if (arm_pc_is_thumb (gdbarch, pc))
-    return thumb_stack_frame_destroyed_p (gdbarch, pc);
-
   if (!find_pc_partial_function (pc, NULL, &func_start, &func_end))
     return 0;
 
@@ -3178,6 +3173,16 @@ arm_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 0;
 }
 
+/* Implement the stack_frame_destroyed_p gdbarch method.  */
+
+static int
+arm_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  if (arm_pc_is_thumb (gdbarch, pc))
+    return thumb_stack_frame_destroyed_p (gdbarch, pc);
+  else
+    return arm_stack_frame_destroyed_p_1 (gdbarch, pc);
+}
 
 /* When arguments must be pushed onto the stack, they go on in reverse
    order.  The code below implements a FILO (stack) to do this.  */
@@ -9884,11 +9889,6 @@ arm_record_extension_space (insn_decode_record *arm_insn_r)
                 {
                   /* SPSR is going to be changed.  */
                   /* We need to get SPSR value, which is yet to be done.  */
-                  printf_unfiltered (_("Process record does not support "
-                                     "instruction  0x%0x at address %s.\n"),
-                                     arm_insn_r->arm_insn,
-                                     paddress (arm_insn_r->gdbarch, 
-                                     arm_insn_r->this_addr));
                   return -1;
                 }
             }
@@ -9929,10 +9929,6 @@ arm_record_extension_space (insn_decode_record *arm_insn_r)
               arm_insn_r->reg_rec_count = 2;
 
               /* Save SPSR also;how?  */
-              printf_unfiltered (_("Process record does not support "
-                                  "instruction 0x%0x at address %s.\n"),
-                                  arm_insn_r->arm_insn,
-                  paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
               return -1;
             }
           else if(8 == bits (arm_insn_r->arm_insn, 4, 7) 
@@ -9978,11 +9974,6 @@ arm_record_extension_space (insn_decode_record *arm_insn_r)
             {
               /* SPSR is going to be changed.  */
               /* we need to get SPSR value, which is yet to be done  */
-              printf_unfiltered (_("Process record does not support "
-                                   "instruction 0x%0x at address %s.\n"),
-                                    arm_insn_r->arm_insn,
-                                    paddress (arm_insn_r->gdbarch, 
-                                    arm_insn_r->this_addr));
               return -1;
             }
         }
@@ -10059,10 +10050,7 @@ arm_record_extension_space (insn_decode_record *arm_insn_r)
 
   /* To be done for ARMv5 and later; as of now we return -1.  */
   if (-1 == ret)
-    printf_unfiltered (_("Process record does not support instruction x%0x "
-                         "at address %s.\n"),arm_insn_r->arm_insn,
-                         paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
-
+    return ret;
 
   REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
   MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
@@ -10148,10 +10136,6 @@ arm_record_data_proc_misc_ld_str (insn_decode_record *arm_insn_r)
         {
           /* SPSR is going to be changed.  */
           /* How to read SPSR value?  */
-          printf_unfiltered (_("Process record does not support instruction "
-                            "0x%0x at address %s.\n"),
-                            arm_insn_r->arm_insn,
-                        paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
           return -1;
         }
     }
@@ -10207,10 +10191,6 @@ arm_record_data_proc_misc_ld_str (insn_decode_record *arm_insn_r)
       arm_insn_r->reg_rec_count = 2;
 
       /* Save SPSR also; how?  */
-      printf_unfiltered (_("Process record does not support instruction "
-                           "0x%0x at address %s.\n"),arm_insn_r->arm_insn,
-                           paddress (arm_insn_r->gdbarch, 
-                           arm_insn_r->this_addr));
       return -1;
     }
   else if (11 == arm_insn_r->decode
@@ -10313,6 +10293,88 @@ arm_record_data_proc_imm (insn_decode_record *arm_insn_r)
   return 0;
 }
 
+static int
+arm_record_media (insn_decode_record *arm_insn_r)
+{
+  uint32_t record_buf[8];
+
+  switch (bits (arm_insn_r->arm_insn, 22, 24))
+    {
+    case 0:
+      /* Parallel addition and subtraction, signed */
+    case 1:
+      /* Parallel addition and subtraction, unsigned */
+    case 2:
+    case 3:
+      /* Packing, unpacking, saturation and reversal */
+      {
+       int rd = bits (arm_insn_r->arm_insn, 12, 15);
+
+       record_buf[arm_insn_r->reg_rec_count++] = rd;
+      }
+      break;
+
+    case 4:
+    case 5:
+      /* Signed multiplies */
+      {
+       int rd = bits (arm_insn_r->arm_insn, 16, 19);
+       unsigned int op1 = bits (arm_insn_r->arm_insn, 20, 22);
+
+       record_buf[arm_insn_r->reg_rec_count++] = rd;
+       if (op1 == 0x0)
+         record_buf[arm_insn_r->reg_rec_count++] = ARM_PS_REGNUM;
+       else if (op1 == 0x4)
+         record_buf[arm_insn_r->reg_rec_count++]
+           = bits (arm_insn_r->arm_insn, 12, 15);
+      }
+      break;
+
+    case 6:
+      {
+       if (bit (arm_insn_r->arm_insn, 21)
+           && bits (arm_insn_r->arm_insn, 5, 6) == 0x2)
+         {
+           /* SBFX */
+           record_buf[arm_insn_r->reg_rec_count++]
+             = bits (arm_insn_r->arm_insn, 12, 15);
+         }
+       else if (bits (arm_insn_r->arm_insn, 20, 21) == 0x0
+                && bits (arm_insn_r->arm_insn, 5, 7) == 0x0)
+         {
+           /* USAD8 and USADA8 */
+           record_buf[arm_insn_r->reg_rec_count++]
+             = bits (arm_insn_r->arm_insn, 16, 19);
+         }
+      }
+      break;
+
+    case 7:
+      {
+       if (bits (arm_insn_r->arm_insn, 20, 21) == 0x3
+           && bits (arm_insn_r->arm_insn, 5, 7) == 0x7)
+         {
+           /* Permanently UNDEFINED */
+           return -1;
+         }
+       else
+         {
+           /* BFC, BFI and UBFX */
+           record_buf[arm_insn_r->reg_rec_count++]
+             = bits (arm_insn_r->arm_insn, 12, 15);
+         }
+      }
+      break;
+
+    default:
+      return -1;
+    }
+
+  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
+
+  return 0;
+}
+
 /* Handle ARM mode instructions with opcode 010.  */
 
 static int
@@ -10419,6 +10481,9 @@ arm_record_ld_st_reg_offset (insn_decode_record *arm_insn_r)
   LONGEST s_word;
   ULONGEST u_regval[2];
 
+  if (bit (arm_insn_r->arm_insn, 4))
+    return arm_record_media (arm_insn_r);
+
   arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
   arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
 
@@ -10825,12 +10890,7 @@ arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
       /* Handle VMOV instruction.  */
       if (bits_a == 0x00)
         {
-          if (bit (arm_insn_r->arm_insn, 20))
-            record_buf[0] = reg_t;
-          else
-            record_buf[0] = num_regs + (bit (arm_insn_r->arm_insn, 7) |
-                            (reg_v << 1));
-
+         record_buf[0] = reg_t;
           arm_insn_r->reg_rec_count = 1;
         }
       /* Handle VMRS instruction.  */
@@ -10848,11 +10908,7 @@ arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
       /* Handle VMOV instruction.  */
       if (bits_a == 0x00)
         {
-          if (bit (arm_insn_r->arm_insn, 20))
-            record_buf[0] = reg_t;
-          else
-            record_buf[0] = num_regs + (bit (arm_insn_r->arm_insn, 7) |
-                            (reg_v << 1));
+         record_buf[0] = ARM_D0_REGNUM + reg_v;
 
           arm_insn_r->reg_rec_count = 1;
         }
@@ -12720,13 +12776,20 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
     {
       arm_record->cond = bits (arm_record->arm_insn, 28, 31);
       insn_id = bits (arm_record->arm_insn, 25, 27);
-      ret = arm_record_extension_space (arm_record);
-      /* If this insn has fallen into extension space
-        then we need not decode it anymore.  */
-      if (ret != -1 && !INSN_RECORDED(arm_record))
+
+      if (arm_record->cond == 0xf)
+       ret = arm_record_extension_space (arm_record);
+      else
        {
+         /* If this insn has fallen into extension space
+            then we need not decode it anymore.  */
          ret = arm_handle_insn[insn_id] (arm_record);
        }
+      if (ret != ARM_RECORD_SUCCESS)
+       {
+         arm_record_unsupported_insn (arm_record);
+         ret = -1;
+       }
     }
   else if (THUMB_RECORD == record_type)
     {
@@ -12734,6 +12797,11 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
       arm_record->cond = -1;
       insn_id = bits (arm_record->arm_insn, 13, 15);
       ret = thumb_handle_insn[insn_id] (arm_record);
+      if (ret != ARM_RECORD_SUCCESS)
+       {
+         arm_record_unsupported_insn (arm_record);
+         ret = -1;
+       }
     }
   else if (THUMB2_RECORD == record_type)
     {
@@ -12744,9 +12812,9 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
       arm_record->arm_insn
        = (arm_record->arm_insn >> 16) | (arm_record->arm_insn << 16);
 
-      insn_id = thumb2_record_decode_insn_handler (arm_record);
+      ret = thumb2_record_decode_insn_handler (arm_record);
 
-      if (insn_id != ARM_RECORD_SUCCESS)
+      if (ret != ARM_RECORD_SUCCESS)
        {
          arm_record_unsupported_insn (arm_record);
          ret = -1;