public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
                   ` (3 preceding siblings ...)
  2014-08-13 13:13 ` [PATCH v3 3/6] Implement support for recording VFP data processing instructions Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-27  9:09   ` Omair Javaid
  2014-08-27 10:34   ` Pedro Alves
  2014-08-13 13:13 ` [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn Omair Javaid
  2014-08-27  9:05 ` [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
  6 siblings, 2 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

This patch fixes failures to reverse-step or reverse-next over solib functions in absence of line information.
The problem is fixed by making sure that in solib functions we keep doing reverse single stepping in absence of line information.

Tested with no regressions on arm, aarch64 and x86_64.

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* infrun.c (process_event_stop_test): Updated.

---
 gdb/infrun.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gdb/infrun.c b/gdb/infrun.c
index c18267f..db8f15b 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4905,12 +4905,15 @@ process_event_stop_test (struct execution_control_state *ecs)
       return;
     }
 
+  stop_pc_sal = find_pc_line (stop_pc, 0);
+
   /* Reverse stepping through solib trampolines.  */
 
   if (execution_direction == EXEC_REVERSE
       && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
     {
       if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
+	  || stop_pc_sal.line == 0
 	  || (ecs->stop_func_start == 0
 	      && in_solib_dynsym_resolve_code (stop_pc)))
 	{
@@ -4939,8 +4942,6 @@ process_event_stop_test (struct execution_control_state *ecs)
 	}
     }
 
-  stop_pc_sal = find_pc_line (stop_pc, 0);
-
   /* NOTE: tausq/2004-05-24: This if block used to be done before all
      the trampoline processing logic, however, there are some trampolines 
      that have no names, so we should do trampoline handling first.  */
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-13 14:10   ` Will Newton
  2014-08-13 13:13 ` [PATCH v3 5/6] Implement support for recording vector data transfer instructions Omair Javaid
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_asimd_vfp_coproc): Updated.
	(arm_record_exreg_ld_st_insn): Added record handler for ex-register
	load/store instructions.

---
 gdb/arm-tdep.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 165 insertions(+), 2 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index d003619..315b5b0 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -11990,6 +11990,169 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for extension register load/store instructions.  */
+
+static int
+arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t opcode, single_reg;
+  uint8_t op_vldm_vstm;
+  uint32_t record_buf[8], record_buf_mem[128];
+  ULONGEST u_regval = 0;
+
+  struct regcache *reg_cache = arm_insn_r->regcache;
+  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
+
+  opcode = bits (arm_insn_r->arm_insn, 20, 24);
+  single_reg = bit (arm_insn_r->arm_insn, 8);
+  op_vldm_vstm = opcode & 0x1b;
+
+  /* Handle VMOV instructions.  */
+  if ((opcode & 0x1e) == 0x04)
+    {
+      if (bit (arm_insn_r->arm_insn, 4))
+        {
+          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
+          arm_insn_r->reg_rec_count = 2;
+        }
+      else
+        {
+          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
+                          | bit (arm_insn_r->arm_insn, 5);
+
+          if (!single_reg)
+            {
+              record_buf[0] = num_regs + reg_m;
+              record_buf[1] = num_regs + reg_m + 1;
+              arm_insn_r->reg_rec_count = 2;
+            }
+          else
+            {
+              record_buf[0] = reg_m + ARM_D0_REGNUM;
+              arm_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+  /* Handle VSTM and VPUSH instructions.  */
+  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
+          || op_vldm_vstm == 0x12)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        {
+          record_buf[0] = reg_rn;
+          arm_insn_r->reg_rec_count = 1;
+        }
+
+      while (memory_count)
+        {
+          if (!single_reg)
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              start_address = start_address + 4;
+              memory_index = memory_index + 2;
+            }
+          else
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              record_buf_mem[memory_index + 2] = start_address + 4;
+              record_buf_mem[memory_index + 3] = 4;
+              start_address = start_address + 8;
+              memory_index = memory_index + 4;
+            }
+          memory_count--;
+        }
+    }
+  /* Handle VLDM instructions.  */
+  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
+          || op_vldm_vstm == 0x13)
+    {
+      uint32_t reg_count, reg_vd;
+      uint32_t reg_index = 0;
+
+      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
+
+      if (single_reg)
+        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 0) << 4);
+      else
+        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 0);
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
+
+      while (reg_count)
+        {
+          if (single_reg)
+              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
+          else
+              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
+
+          reg_count--;
+        }
+    }
+  /* VSTR Vector store register.  */
+  else if ((opcode & 0x13) == 0x10)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval + imm_off32;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (single_reg)
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+        }
+      else
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+          record_buf_mem[memory_index + 2] = start_address + 4;
+          record_buf_mem[memory_index + 3] = 4;
+        }
+    }
+  /* VLDR Vector load register.  */
+  else if ((opcode & 0x13) == 0x11)
+    {
+      uint8_t single_reg = 0;
+      uint8_t special_case;
+
+      record_buf[0] = 0;
+      record_buf[1] = 0;
+      arm_insn_r->reg_rec_count = 2;
+    }
+
+  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);
+  return 0;
+}
+
 /* Record handler for arm/thumb mode VFP data processing instructions.  */
 
 static int
@@ -12218,11 +12381,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
     {
       /* Handle extension register ld/st instructions.  */
       if (!(op1 & 0x20))
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
 
       /* 64-bit transfers between arm core and extension registers.  */
       if ((op1 & 0x3e) == 0x04)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
     }
   else
     {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 3/6] Implement support for recording VFP data processing instructions
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
                   ` (2 preceding siblings ...)
  2014-08-13 13:13 ` [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-13 14:10   ` Will Newton
  2014-08-13 13:13 ` [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code Omair Javaid
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_coproc_data_proc): Updated.
	(arm_record_vfp_data_proc_insn): Added record handler for VFP data
	processing instructions.

---
 gdb/arm-tdep.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 212 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index adee197..d003619 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -11990,6 +11990,217 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for arm/thumb mode VFP data processing instructions.  */
+
+static int
+arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t opc1, opc2, opc3, dp_op_sz, bit_d, reg_vd;
+  uint32_t record_buf[4];
+  enum insn_types {INSN_T0, INSN_T1, INSN_T2, INSN_T3, INSN_INV};
+  enum insn_types curr_insn_type = INSN_INV;
+
+  reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+  opc1 = bits (arm_insn_r->arm_insn, 20, 23);
+  opc2 = bits (arm_insn_r->arm_insn, 16, 19);
+  opc3 = bits (arm_insn_r->arm_insn, 6, 7);
+  dp_op_sz = bit (arm_insn_r->arm_insn, 8);
+  bit_d = bit (arm_insn_r->arm_insn, 22);
+  opc1 = opc1 & 0x04;
+
+  /* Handle VMLA, VMLS.  */
+  if (opc1 == 0x00)
+    {
+      if (bit (arm_insn_r->arm_insn, 10))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VNMLA, VNMLS, VNMUL.  */
+  else if (opc1 == 0x01)
+    {
+      if (dp_op_sz)
+        curr_insn_type = INSN_T1;
+      else
+        curr_insn_type = INSN_T2;
+    }
+  /* Handle VMUL.  */
+  else if (opc1 == 0x02 && !(opc3 & 0x01))
+    {
+      if (bit (arm_insn_r->arm_insn, 10))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VADD, VSUB.  */
+  else if (opc1 == 0x03)
+    {
+      if (!bit (arm_insn_r->arm_insn, 9))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VDIV.  */
+  else if (opc1 == 0x0b)
+    {
+      if (dp_op_sz)
+        curr_insn_type = INSN_T1;
+      else
+        curr_insn_type = INSN_T2;
+    }
+  /* Handle all other vfp data processing instructions.  */
+  else if (opc1 == 0x0b)
+    {
+      /* Handle VMOV.  */
+      if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
+        {
+          if (bit (arm_insn_r->arm_insn, 4))
+            {
+              if (bit (arm_insn_r->arm_insn, 6))
+                curr_insn_type = INSN_T0;
+              else
+                curr_insn_type = INSN_T1;
+            }
+          else
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+        }
+      /* Handle VNEG and VABS.  */
+      else if ((opc2 == 0x01 && opc3 == 0x01)
+              || (opc2 == 0x00 && opc3 == 0x03))
+        {
+          if (!bit (arm_insn_r->arm_insn, 11))
+            {
+              if (bit (arm_insn_r->arm_insn, 6))
+                curr_insn_type = INSN_T0;
+              else
+                curr_insn_type = INSN_T1;
+            }
+          else
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+        }
+      /* Handle VSQRT.  */
+      else if (opc2 == 0x01 && opc3 == 0x03)
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+      /* Handle VCVT.  */
+      else if (opc2 == 0x07 && opc3 == 0x03)
+        {
+          if (!dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+      else if (opc3 & 0x01)
+        {
+          /* Handle VCVT.  */
+          if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
+            {
+              if (!bit (arm_insn_r->arm_insn, 18))
+                curr_insn_type = INSN_T2;
+              else
+                {
+                  if (dp_op_sz)
+                    curr_insn_type = INSN_T1;
+                  else
+                    curr_insn_type = INSN_T2;
+                }
+            }
+          /* Handle VCVT.  */
+          else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+          /* Handle VCVTB, VCVTT.  */
+          else if ((opc2 & 0x0e) == 0x02)
+            curr_insn_type = INSN_T2;
+          /* Handle VCMP, VCMPE.  */
+          else if ((opc2 & 0x0e) == 0x04)
+            curr_insn_type = INSN_T3;
+        }
+    }
+
+  switch (curr_insn_type)
+    {
+      case INSN_T0:
+        reg_vd = reg_vd | (bit_d << 4);
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
+        arm_insn_r->reg_rec_count = 2;
+        break;
+
+      case INSN_T1:
+        reg_vd = reg_vd | (bit_d << 4);
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      case INSN_T2:
+        reg_vd = (reg_vd << 1) | bit_d;
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      case INSN_T3:
+        record_buf[0] = ARM_FPSCR_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      default:
+        gdb_assert_not_reached ("no decoding pattern found");
+        break;
+    }
+
+  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
+  return 0;
+}
+
 /* Handling opcode 110 insns.  */
 
 static int
@@ -12089,7 +12300,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
     {
       /* VFP data-processing instructions.  */
       if (!op1_sbit && !op)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_vfp_data_proc_insn (arm_insn_r);
 
       /* Advanced SIMD, VFP instructions.  */
       if (!op1_sbit && op)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 0/6] ARM process record/replay improvements
@ 2014-08-13 13:13 Omair Javaid
  2014-08-13 13:13 ` [PATCH v3 4/6] Implement support for recording extension register ld/st insn Omair Javaid
                   ` (6 more replies)
  0 siblings, 7 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

This set of patches is an update to a previously posted patch set here:
version 1) https://www.sourceware.org/ml/gdb-patches/2013-11/msg00749.html
version 2) https://sourceware.org/ml/gdb-patches/2014-02/msg00703.html

New series splits the previous patch by feature and also makes appropriate
changes required to accomodate recently committed changes in arm process record
code.

This patch series further improves arm process record instruction coverage and
fixes a few more testsuite failures in gdb.record. 

This patch set has been tested with latest gdb trunk on ARM and x86_64 targets with no regressions.

All gdb.reverse tests now pass on arm targets.

Omair Javaid (6):
  Implements support for recording arm/thumb mode coprocessor
    instructions
  Implements support for recording thumb2 ASIMD struct ld/st insn
  Implement support for recording VFP data processing instructions
  Implement support for recording extension register ld/st insn
  Implement support for recording vector data transfer instructions
  Fix reverse-step and reverse-next over undebuggable solib code

 gdb/arm-tdep.c | 784 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 gdb/infrun.c   |   5 +-
 2 files changed, 776 insertions(+), 13 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 5/6] Implement support for recording vector data transfer instructions
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
  2014-08-13 13:13 ` [PATCH v3 4/6] Implement support for recording extension register ld/st insn Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-13 14:10   ` Will Newton
  2014-08-13 13:13 ` [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions Omair Javaid
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_vdata_transfer_insn): Added record handler for
	vector data transfer instructions.
	(arm_record_coproc_data_proc): Updated.

---
 gdb/arm-tdep.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 315b5b0..7f651bc 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -11990,6 +11990,102 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for vector data transfer instructions.  */
+
+static int
+arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t bits_a, bit_c, bit_l, reg_t, reg_v;
+  uint32_t record_buf[4];
+
+  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
+  reg_t = bits (arm_insn_r->arm_insn, 12, 15);
+  reg_v = bits (arm_insn_r->arm_insn, 21, 23);
+  bits_a = bits (arm_insn_r->arm_insn, 21, 23);
+  bit_l = bit (arm_insn_r->arm_insn, 20);
+  bit_c = bit (arm_insn_r->arm_insn, 8);
+
+  /* Handle VMOV instruction.  */
+  if (bit_l && bit_c)
+    {
+      record_buf[0] = reg_t;
+      arm_insn_r->reg_rec_count = 1;
+    }
+  else if (bit_l && !bit_c)
+    {
+      /* 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));
+
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VMRS instruction.  */
+      else if (bits_a == 0x07)
+        {
+          if (reg_t == 15)
+            reg_t = ARM_PS_REGNUM;
+
+          record_buf[0] = reg_t;
+          arm_insn_r->reg_rec_count = 1;
+        }
+    }
+  else if (!bit_l && !bit_c)
+    {
+      /* 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));
+
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VMSR instruction.  */
+      else if (bits_a == 0x07)
+        {
+          record_buf[0] = ARM_FPSCR_REGNUM;
+          arm_insn_r->reg_rec_count = 1;
+        }
+    }
+  else if (!bit_l && bit_c)
+    {
+      /* Handle VMOV instruction.  */
+      if (!(bits_a & 0x04))
+        {
+          record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
+                          + ARM_D0_REGNUM;
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VDUP instruction.  */
+      else
+        {
+          if (bit (arm_insn_r->arm_insn, 21))
+            {
+              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+              record_buf[0] = reg_v + ARM_D0_REGNUM;
+              record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
+              arm_insn_r->reg_rec_count = 2;
+            }
+          else
+            {
+              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+              record_buf[0] = reg_v + ARM_D0_REGNUM;
+              arm_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+
+  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
+  return 0;
+}
+
 /* Record handler for extension register load/store instructions.  */
 
 static int
@@ -12467,7 +12563,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
 
       /* Advanced SIMD, VFP instructions.  */
       if (!op1_sbit && op)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_vdata_transfer_insn (arm_insn_r);
     }
   else
     {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
  2014-08-13 13:13 ` [PATCH v3 4/6] Implement support for recording extension register ld/st insn Omair Javaid
  2014-08-13 13:13 ` [PATCH v3 5/6] Implement support for recording vector data transfer instructions Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-13 14:10   ` Will Newton
  2014-08-13 13:13 ` [PATCH v3 3/6] Implement support for recording VFP data processing instructions Omair Javaid
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_coproc_data_proc): Updated.
	(arm_record_asimd_vfp_coproc): Added record handler for asimd, vfp
	and coprocessor insn.
	(thumb2_record_coproc_insn): New function.
	(thumb2_record_decode_insn_handler): Updated.
	(decode_insn): Updated.

---
 gdb/arm-tdep.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 112 insertions(+), 10 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index b746eee..607b92e 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -11990,20 +11990,80 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Handling opcode 110 insns.  */
+
+static int
+arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
+{
+  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
+
+  coproc = bits (arm_insn_r->arm_insn, 8, 11);
+  op1 = bits (arm_insn_r->arm_insn, 20, 25);
+  op1_sbit = bit (arm_insn_r->arm_insn, 24);
+  op1_ebit = bit (arm_insn_r->arm_insn, 20);
+  op = bit (arm_insn_r->arm_insn, 4);
+
+  if ((coproc & 0x0e) == 0x0a)
+    {
+      /* Handle extension register ld/st instructions.  */
+      if (!(op1 & 0x20))
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* 64-bit transfers between arm core and extension registers.  */
+      if ((op1 & 0x3e) == 0x04)
+        return arm_record_unsupported_insn (arm_insn_r);
+    }
+  else
+    {
+      /* Handle coprocessor ld/st instructions.  */
+      if (!(op1 & 0x3a))
+        {
+          /* Store.  */
+          if (!op1_ebit)
+            return arm_record_unsupported_insn (arm_insn_r);
+          else
+            /* Load.  */
+            return arm_record_unsupported_insn (arm_insn_r);
+        }
+
+      /* Move to coprocessor from two arm core registers.  */
+      if (op1 == 0x4)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to two arm core registers from coprocessor.  */
+      if (op1 == 0x5)
+        {
+          uint32_t reg_t[2];
+
+          reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
+          arm_insn_r->reg_rec_count = 2;
+
+          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
+          return 0;
+       }
+    }
+  return arm_record_unsupported_insn (arm_insn_r);
+}
+
 /* Handling opcode 111 insns.  */
 
 static int
 arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
 {
+  uint32_t op, op1_sbit, op1_ebit, coproc;
   struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
   struct regcache *reg_cache = arm_insn_r->regcache;
-  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
   ULONGEST u_regval = 0;
 
   arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
+  coproc = bits (arm_insn_r->arm_insn, 8, 11);
+  op1_sbit = bit (arm_insn_r->arm_insn, 24);
+  op1_ebit = bit (arm_insn_r->arm_insn, 20);
+  op = bit (arm_insn_r->arm_insn, 4);
 
   /* Handle arm SWI/SVC system call instructions.  */
-  if (15 == arm_insn_r->opcode)
+  if (op1_sbit)
     {
       if (tdep->arm_syscall_record != NULL)
         {
@@ -12016,21 +12076,52 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
           else /* EABI.  */
             regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
 
-          ret = tdep->arm_syscall_record (reg_cache, svc_number);
+          return tdep->arm_syscall_record (reg_cache, svc_number);
         }
       else
         {
           printf_unfiltered (_("no syscall record support\n"));
-          ret = -1;
+          return -1;
         }
     }
+
+  if ((coproc & 0x0e) == 0x0a)
+    {
+      /* VFP data-processing instructions.  */
+      if (!op1_sbit && !op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Advanced SIMD, VFP instructions.  */
+      if (!op1_sbit && op)
+        return arm_record_unsupported_insn (arm_insn_r);
+    }
   else
     {
-      arm_record_unsupported_insn (arm_insn_r);
-      ret = -1;
+      /* Coprocessor data operations.  */
+      if (!op1_sbit && !op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to Coprocessor from ARM core register.  */
+      if (!op1_sbit && !op1_ebit && op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to arm core register from coprocessor.  */
+      if (!op1_sbit && op1_ebit && op)
+        {
+          uint32_t record_buf[1];
+
+          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          if (record_buf[0] == 15)
+            record_buf[0] = ARM_PS_REGNUM;
+
+          arm_insn_r->reg_rec_count = 1;
+          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
+                     record_buf);
+          return 0;
+        }
     }
 
-  return ret;
+  return arm_record_unsupported_insn (arm_insn_r);
 }
 
 /* Handling opcode 000 insns.  */
@@ -12946,6 +13037,17 @@ thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
   return ARM_RECORD_SUCCESS;
 }
 
+/* Record handler for thumb32 coprocessor instructions.  */
+
+static int
+thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
+{
+  if (bit (thumb2_insn_r->arm_insn, 25))
+    return arm_record_coproc_data_proc (thumb2_insn_r);
+  else
+    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
+}
+
 /* Decodes thumb2 instruction type and invokes its record handler.  */
 
 static unsigned int
@@ -12977,7 +13079,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (op2 & 0x40)
         {
           /* Co-processor instructions.  */
-          arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_coproc_insn (thumb2_insn_r);
         }
     }
   else if (op1 == 0x02)
@@ -13043,7 +13145,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (op2 & 0x40)
         {
           /* Co-processor instructions.  */
-          return arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_coproc_insn (thumb2_insn_r);
         }
    }
 
@@ -13087,7 +13189,7 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
     arm_record_ld_st_reg_offset,        /* 011.  */
     arm_record_ld_st_multiple,          /* 100.  */
     arm_record_b_bl,                    /* 101.  */
-    arm_record_unsupported_insn,        /* 110.  */
+    arm_record_asimd_vfp_coproc,        /* 110.  */
     arm_record_coproc_data_proc         /* 111.  */
   };
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
                   ` (4 preceding siblings ...)
  2014-08-13 13:13 ` [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code Omair Javaid
@ 2014-08-13 13:13 ` Omair Javaid
  2014-08-13 14:10   ` Will Newton
  2014-08-27  9:05 ` [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
  6 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-13 13:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (thumb2_record_asimd_struct_ld_st): Added record handler
	for advance SIMD struct ld/st insn.
	(thumb2_record_decode_insn_handler): Updated.

---
 gdb/arm-tdep.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 191 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 607b92e..adee197 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -13048,6 +13048,196 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
     return arm_record_asimd_vfp_coproc (thumb2_insn_r);
 }
 
+/* Record handler for advance SIMD structure load/store instructions.  */
+
+static int
+thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
+{
+  struct regcache *reg_cache = thumb2_insn_r->regcache;
+  uint32_t l_bit, a_bit, b_bits;
+  uint32_t record_buf[128], record_buf_mem[128];
+  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
+  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
+  uint8_t bf_align, f_ebytes;
+
+  l_bit = bit (thumb2_insn_r->arm_insn, 21);
+  a_bit = bit (thumb2_insn_r->arm_insn, 23);
+  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
+  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);
+  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
+  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
+  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
+  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
+  f_esize = 8 * f_ebytes;
+  f_elem = 8 / f_ebytes;
+
+  if (!l_bit)
+    {
+      ULONGEST u_regval = 0;
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      address = u_regval;
+
+      if (!a_bit)
+        {
+          /* Handle VST1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            {
+              if (b_bits == 0x07)
+                bf_regs = 1;
+              else if (b_bits == 0x0a)
+                bf_regs = 2;
+              else if (b_bits == 0x06)
+                bf_regs = 3;
+              else if (b_bits == 0x02)
+                bf_regs = 4;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                {
+                  for (index_e = 0; index_e < f_elem; index_e++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address;
+                      address = address + f_ebytes;
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                }
+            }
+          /* Handle VST2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            {
+              if (b_bits == 0x09 || b_bits == 0x08)
+                bf_regs = 1;
+              else if (b_bits == 0x03)
+                bf_regs = 2;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                for (index_e = 0; index_e < f_elem; index_e++)
+                  {
+                    for (loop_t = 0; loop_t < 2; loop_t++)
+                      {
+                        record_buf_mem[index_m++] = f_ebytes;
+                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                        thumb2_insn_r->mem_rec_count += 1;
+                      }
+                    address = address + (2 * f_ebytes);
+                  }
+            }
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 3; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (3 * f_ebytes);
+                }
+            }
+          /* Handle VST4.  */
+          else if (!(b_bits & 0x0e))
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 4; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (4 * f_ebytes);
+                }
+            }
+        }
+      else
+        {
+          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
+
+          if (bft_size == 0x00)
+            f_ebytes = 1;
+          else if (bft_size == 0x01)
+            f_ebytes = 2;
+          else if (bft_size == 0x02)
+            f_ebytes = 4;
+          else
+            f_ebytes = 0;
+
+          /* Handle VST1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08)
+            thumb2_insn_r->mem_rec_count = 1;
+          /* Handle VST2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
+            thumb2_insn_r->mem_rec_count = 2;
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
+            thumb2_insn_r->mem_rec_count = 3;
+          /* Handle VST4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
+            thumb2_insn_r->mem_rec_count = 4;
+
+          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
+            {
+              record_buf_mem[index_m] = f_ebytes;
+              record_buf_mem[index_m] = address + (index_m * f_ebytes);
+            }
+        }
+    }
+  else
+    {
+      if (!a_bit)
+        {
+          /* Handle VLD1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if (!(b_bits & 0x0e))
+            thumb2_insn_r->reg_rec_count = 4;
+        }
+      else
+        {
+          /* Handle VLD1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
+            thumb2_insn_r->reg_rec_count = 4;
+
+          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
+            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
+        }
+    }
+
+  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
+    {
+      record_buf[index_r] = reg_rn;
+      thumb2_insn_r->reg_rec_count += 1;
+    }
+
+  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
+            record_buf);
+  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
+            record_buf_mem);
+  return 0;
+}
+
 /* Decodes thumb2 instruction type and invokes its record handler.  */
 
 static unsigned int
@@ -13110,7 +13300,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (!((op2 & 0x71) ^ 0x10))
         {
           /* Advanced SIMD or structure load/store instructions.  */
-          return arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
         }
       else if (!((op2 & 0x67) ^ 0x01))
         {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 3/6] Implement support for recording VFP data processing instructions
  2014-08-13 13:13 ` [PATCH v3 3/6] Implement support for recording VFP data processing instructions Omair Javaid
@ 2014-08-13 14:10   ` Will Newton
  2014-08-27  9:10     ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-08-13 14:10 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.
>         (arm_record_vfp_data_proc_insn): Added record handler for VFP data
>         processing instructions.
>
> ---
>  gdb/arm-tdep.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 212 insertions(+), 1 deletion(-)

Looks ok to me.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index adee197..d003619 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -11990,6 +11990,217 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Record handler for arm/thumb mode VFP data processing instructions.  */
> +
> +static int
> +arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t opc1, opc2, opc3, dp_op_sz, bit_d, reg_vd;
> +  uint32_t record_buf[4];
> +  enum insn_types {INSN_T0, INSN_T1, INSN_T2, INSN_T3, INSN_INV};
> +  enum insn_types curr_insn_type = INSN_INV;
> +
> +  reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +  opc1 = bits (arm_insn_r->arm_insn, 20, 23);
> +  opc2 = bits (arm_insn_r->arm_insn, 16, 19);
> +  opc3 = bits (arm_insn_r->arm_insn, 6, 7);
> +  dp_op_sz = bit (arm_insn_r->arm_insn, 8);
> +  bit_d = bit (arm_insn_r->arm_insn, 22);
> +  opc1 = opc1 & 0x04;
> +
> +  /* Handle VMLA, VMLS.  */
> +  if (opc1 == 0x00)
> +    {
> +      if (bit (arm_insn_r->arm_insn, 10))
> +        {
> +          if (bit (arm_insn_r->arm_insn, 6))
> +            curr_insn_type = INSN_T0;
> +          else
> +            curr_insn_type = INSN_T1;
> +        }
> +      else
> +        {
> +          if (dp_op_sz)
> +            curr_insn_type = INSN_T1;
> +          else
> +            curr_insn_type = INSN_T2;
> +        }
> +    }
> +  /* Handle VNMLA, VNMLS, VNMUL.  */
> +  else if (opc1 == 0x01)
> +    {
> +      if (dp_op_sz)
> +        curr_insn_type = INSN_T1;
> +      else
> +        curr_insn_type = INSN_T2;
> +    }
> +  /* Handle VMUL.  */
> +  else if (opc1 == 0x02 && !(opc3 & 0x01))
> +    {
> +      if (bit (arm_insn_r->arm_insn, 10))
> +        {
> +          if (bit (arm_insn_r->arm_insn, 6))
> +            curr_insn_type = INSN_T0;
> +          else
> +            curr_insn_type = INSN_T1;
> +        }
> +      else
> +        {
> +          if (dp_op_sz)
> +            curr_insn_type = INSN_T1;
> +          else
> +            curr_insn_type = INSN_T2;
> +        }
> +    }
> +  /* Handle VADD, VSUB.  */
> +  else if (opc1 == 0x03)
> +    {
> +      if (!bit (arm_insn_r->arm_insn, 9))
> +        {
> +          if (bit (arm_insn_r->arm_insn, 6))
> +            curr_insn_type = INSN_T0;
> +          else
> +            curr_insn_type = INSN_T1;
> +        }
> +      else
> +        {
> +          if (dp_op_sz)
> +            curr_insn_type = INSN_T1;
> +          else
> +            curr_insn_type = INSN_T2;
> +        }
> +    }
> +  /* Handle VDIV.  */
> +  else if (opc1 == 0x0b)
> +    {
> +      if (dp_op_sz)
> +        curr_insn_type = INSN_T1;
> +      else
> +        curr_insn_type = INSN_T2;
> +    }
> +  /* Handle all other vfp data processing instructions.  */
> +  else if (opc1 == 0x0b)
> +    {
> +      /* Handle VMOV.  */
> +      if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
> +        {
> +          if (bit (arm_insn_r->arm_insn, 4))
> +            {
> +              if (bit (arm_insn_r->arm_insn, 6))
> +                curr_insn_type = INSN_T0;
> +              else
> +                curr_insn_type = INSN_T1;
> +            }
> +          else
> +            {
> +              if (dp_op_sz)
> +                curr_insn_type = INSN_T1;
> +              else
> +                curr_insn_type = INSN_T2;
> +            }
> +        }
> +      /* Handle VNEG and VABS.  */
> +      else if ((opc2 == 0x01 && opc3 == 0x01)
> +              || (opc2 == 0x00 && opc3 == 0x03))
> +        {
> +          if (!bit (arm_insn_r->arm_insn, 11))
> +            {
> +              if (bit (arm_insn_r->arm_insn, 6))
> +                curr_insn_type = INSN_T0;
> +              else
> +                curr_insn_type = INSN_T1;
> +            }
> +          else
> +            {
> +              if (dp_op_sz)
> +                curr_insn_type = INSN_T1;
> +              else
> +                curr_insn_type = INSN_T2;
> +            }
> +        }
> +      /* Handle VSQRT.  */
> +      else if (opc2 == 0x01 && opc3 == 0x03)
> +        {
> +          if (dp_op_sz)
> +            curr_insn_type = INSN_T1;
> +          else
> +            curr_insn_type = INSN_T2;
> +        }
> +      /* Handle VCVT.  */
> +      else if (opc2 == 0x07 && opc3 == 0x03)
> +        {
> +          if (!dp_op_sz)
> +            curr_insn_type = INSN_T1;
> +          else
> +            curr_insn_type = INSN_T2;
> +        }
> +      else if (opc3 & 0x01)
> +        {
> +          /* Handle VCVT.  */
> +          if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
> +            {
> +              if (!bit (arm_insn_r->arm_insn, 18))
> +                curr_insn_type = INSN_T2;
> +              else
> +                {
> +                  if (dp_op_sz)
> +                    curr_insn_type = INSN_T1;
> +                  else
> +                    curr_insn_type = INSN_T2;
> +                }
> +            }
> +          /* Handle VCVT.  */
> +          else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
> +            {
> +              if (dp_op_sz)
> +                curr_insn_type = INSN_T1;
> +              else
> +                curr_insn_type = INSN_T2;
> +            }
> +          /* Handle VCVTB, VCVTT.  */
> +          else if ((opc2 & 0x0e) == 0x02)
> +            curr_insn_type = INSN_T2;
> +          /* Handle VCMP, VCMPE.  */
> +          else if ((opc2 & 0x0e) == 0x04)
> +            curr_insn_type = INSN_T3;
> +        }
> +    }
> +
> +  switch (curr_insn_type)
> +    {
> +      case INSN_T0:
> +        reg_vd = reg_vd | (bit_d << 4);
> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
> +        record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
> +        arm_insn_r->reg_rec_count = 2;
> +        break;
> +
> +      case INSN_T1:
> +        reg_vd = reg_vd | (bit_d << 4);
> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
> +        arm_insn_r->reg_rec_count = 1;
> +        break;
> +
> +      case INSN_T2:
> +        reg_vd = (reg_vd << 1) | bit_d;
> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
> +        arm_insn_r->reg_rec_count = 1;
> +        break;
> +
> +      case INSN_T3:
> +        record_buf[0] = ARM_FPSCR_REGNUM;
> +        arm_insn_r->reg_rec_count = 1;
> +        break;
> +
> +      default:
> +        gdb_assert_not_reached ("no decoding pattern found");
> +        break;
> +    }
> +
> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
> +  return 0;
> +}
> +
>  /* Handling opcode 110 insns.  */
>
>  static int
> @@ -12089,7 +12300,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>      {
>        /* VFP data-processing instructions.  */
>        if (!op1_sbit && !op)
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_vfp_data_proc_insn (arm_insn_r);
>
>        /* Advanced SIMD, VFP instructions.  */
>        if (!op1_sbit && op)
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-13 13:13 ` [PATCH v3 4/6] Implement support for recording extension register ld/st insn Omair Javaid
@ 2014-08-13 14:10   ` Will Newton
  2014-08-27  9:21     ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-08-13 14:10 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_asimd_vfp_coproc): Updated.
>         (arm_record_exreg_ld_st_insn): Added record handler for ex-register
>         load/store instructions.
>
> ---
>  gdb/arm-tdep.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 165 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index d003619..315b5b0 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -11990,6 +11990,169 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Record handler for extension register load/store instructions.  */
> +
> +static int
> +arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t opcode, single_reg;
> +  uint8_t op_vldm_vstm;
> +  uint32_t record_buf[8], record_buf_mem[128];
> +  ULONGEST u_regval = 0;
> +
> +  struct regcache *reg_cache = arm_insn_r->regcache;
> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
> +
> +  opcode = bits (arm_insn_r->arm_insn, 20, 24);
> +  single_reg = bit (arm_insn_r->arm_insn, 8);
> +  op_vldm_vstm = opcode & 0x1b;
> +
> +  /* Handle VMOV instructions.  */
> +  if ((opcode & 0x1e) == 0x04)
> +    {
> +      if (bit (arm_insn_r->arm_insn, 4))
> +        {
> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
> +          arm_insn_r->reg_rec_count = 2;
> +        }
> +      else
> +        {
> +          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
> +                          | bit (arm_insn_r->arm_insn, 5);
> +
> +          if (!single_reg)
> +            {
> +              record_buf[0] = num_regs + reg_m;
> +              record_buf[1] = num_regs + reg_m + 1;
> +              arm_insn_r->reg_rec_count = 2;
> +            }
> +          else
> +            {
> +              record_buf[0] = reg_m + ARM_D0_REGNUM;
> +              arm_insn_r->reg_rec_count = 1;
> +            }
> +        }
> +    }
> +  /* Handle VSTM and VPUSH instructions.  */
> +  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
> +          || op_vldm_vstm == 0x12)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        {
> +          record_buf[0] = reg_rn;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +
> +      while (memory_count)
> +        {
> +          if (!single_reg)
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              start_address = start_address + 4;
> +              memory_index = memory_index + 2;
> +            }
> +          else
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              record_buf_mem[memory_index + 2] = start_address + 4;
> +              record_buf_mem[memory_index + 3] = 4;
> +              start_address = start_address + 8;
> +              memory_index = memory_index + 4;
> +            }
> +          memory_count--;
> +        }
> +    }
> +  /* Handle VLDM instructions.  */
> +  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
> +          || op_vldm_vstm == 0x13)
> +    {
> +      uint32_t reg_count, reg_vd;
> +      uint32_t reg_index = 0;
> +
> +      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
> +
> +      if (single_reg)
> +        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 0) << 4);
> +      else
> +        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 0);
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
> +
> +      while (reg_count)
> +        {
> +          if (single_reg)
> +              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
> +          else
> +              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
> +
> +          reg_count--;
> +        }
> +    }
> +  /* VSTR Vector store register.  */
> +  else if ((opcode & 0x13) == 0x10)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval + imm_off32;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (single_reg)
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +        }
> +      else
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +          record_buf_mem[memory_index + 2] = start_address + 4;
> +          record_buf_mem[memory_index + 3] = 4;
> +        }
> +    }
> +  /* VLDR Vector load register.  */
> +  else if ((opcode & 0x13) == 0x11)
> +    {
> +      uint8_t single_reg = 0;
> +      uint8_t special_case;

Is there some missing code here? Should there be a TODO comment?

> +
> +      record_buf[0] = 0;
> +      record_buf[1] = 0;
> +      arm_insn_r->reg_rec_count = 2;
> +    }
> +
> +  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);
> +  return 0;
> +}
> +
>  /* Record handler for arm/thumb mode VFP data processing instructions.  */
>
>  static int
> @@ -12218,11 +12381,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>      {
>        /* Handle extension register ld/st instructions.  */
>        if (!(op1 & 0x20))
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>
>        /* 64-bit transfers between arm core and extension registers.  */
>        if ((op1 & 0x3e) == 0x04)
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>      }
>    else
>      {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 5/6] Implement support for recording vector data transfer instructions
  2014-08-13 13:13 ` [PATCH v3 5/6] Implement support for recording vector data transfer instructions Omair Javaid
@ 2014-08-13 14:10   ` Will Newton
  2014-08-27  9:09     ` Omair Javaid
  2014-08-27 10:19     ` Pedro Alves
  0 siblings, 2 replies; 37+ messages in thread
From: Will Newton @ 2014-08-13 14:10 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_vdata_transfer_insn): Added record handler for
>         vector data transfer instructions.
>         (arm_record_coproc_data_proc): Updated.
>
> ---
>  gdb/arm-tdep.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 97 insertions(+), 1 deletion(-)

Looks ok to me.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 315b5b0..7f651bc 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -11990,6 +11990,102 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Record handler for vector data transfer instructions.  */
> +
> +static int
> +arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t bits_a, bit_c, bit_l, reg_t, reg_v;
> +  uint32_t record_buf[4];
> +
> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
> +  reg_t = bits (arm_insn_r->arm_insn, 12, 15);
> +  reg_v = bits (arm_insn_r->arm_insn, 21, 23);
> +  bits_a = bits (arm_insn_r->arm_insn, 21, 23);
> +  bit_l = bit (arm_insn_r->arm_insn, 20);
> +  bit_c = bit (arm_insn_r->arm_insn, 8);
> +
> +  /* Handle VMOV instruction.  */
> +  if (bit_l && bit_c)
> +    {
> +      record_buf[0] = reg_t;
> +      arm_insn_r->reg_rec_count = 1;
> +    }
> +  else if (bit_l && !bit_c)
> +    {
> +      /* 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));
> +
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +      /* Handle VMRS instruction.  */
> +      else if (bits_a == 0x07)
> +        {
> +          if (reg_t == 15)
> +            reg_t = ARM_PS_REGNUM;
> +
> +          record_buf[0] = reg_t;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +    }
> +  else if (!bit_l && !bit_c)
> +    {
> +      /* 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));
> +
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +      /* Handle VMSR instruction.  */
> +      else if (bits_a == 0x07)
> +        {
> +          record_buf[0] = ARM_FPSCR_REGNUM;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +    }
> +  else if (!bit_l && bit_c)
> +    {
> +      /* Handle VMOV instruction.  */
> +      if (!(bits_a & 0x04))
> +        {
> +          record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
> +                          + ARM_D0_REGNUM;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +      /* Handle VDUP instruction.  */
> +      else
> +        {
> +          if (bit (arm_insn_r->arm_insn, 21))
> +            {
> +              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
> +              record_buf[0] = reg_v + ARM_D0_REGNUM;
> +              record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
> +              arm_insn_r->reg_rec_count = 2;
> +            }
> +          else
> +            {
> +              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
> +              record_buf[0] = reg_v + ARM_D0_REGNUM;
> +              arm_insn_r->reg_rec_count = 1;
> +            }
> +        }
> +    }
> +
> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
> +  return 0;
> +}
> +
>  /* Record handler for extension register load/store instructions.  */
>
>  static int
> @@ -12467,7 +12563,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>
>        /* Advanced SIMD, VFP instructions.  */
>        if (!op1_sbit && op)
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_vdata_transfer_insn (arm_insn_r);
>      }
>    else
>      {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions
  2014-08-13 13:13 ` [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions Omair Javaid
@ 2014-08-13 14:10   ` Will Newton
  2014-08-27  9:07     ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-08-13 14:10 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.
>         (arm_record_asimd_vfp_coproc): Added record handler for asimd, vfp
>         and coprocessor insn.
>         (thumb2_record_coproc_insn): New function.
>         (thumb2_record_decode_insn_handler): Updated.
>         (decode_insn): Updated.
>
> ---
>  gdb/arm-tdep.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 112 insertions(+), 10 deletions(-)
>
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index b746eee..607b92e 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -11990,20 +11990,80 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Handling opcode 110 insns.  */
> +
> +static int
> +arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
> +
> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
> +  op1 = bits (arm_insn_r->arm_insn, 20, 25);
> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
> +  op = bit (arm_insn_r->arm_insn, 4);

op abd op1_sbit appear to be unused.

> +
> +  if ((coproc & 0x0e) == 0x0a)
> +    {
> +      /* Handle extension register ld/st instructions.  */
> +      if (!(op1 & 0x20))
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* 64-bit transfers between arm core and extension registers.  */
> +      if ((op1 & 0x3e) == 0x04)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +    }
> +  else
> +    {
> +      /* Handle coprocessor ld/st instructions.  */
> +      if (!(op1 & 0x3a))
> +        {
> +          /* Store.  */
> +          if (!op1_ebit)
> +            return arm_record_unsupported_insn (arm_insn_r);
> +          else
> +            /* Load.  */
> +            return arm_record_unsupported_insn (arm_insn_r);
> +        }
> +
> +      /* Move to coprocessor from two arm core registers.  */
> +      if (op1 == 0x4)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to two arm core registers from coprocessor.  */
> +      if (op1 == 0x5)
> +        {
> +          uint32_t reg_t[2];
> +
> +          reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
> +          arm_insn_r->reg_rec_count = 2;
> +
> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
> +          return 0;
> +       }
> +    }
> +  return arm_record_unsupported_insn (arm_insn_r);
> +}
> +
>  /* Handling opcode 111 insns.  */
>
>  static int
>  arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>  {
> +  uint32_t op, op1_sbit, op1_ebit, coproc;
>    struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
>    struct regcache *reg_cache = arm_insn_r->regcache;
> -  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
>    ULONGEST u_regval = 0;
>
>    arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
> +  op = bit (arm_insn_r->arm_insn, 4);
>
>    /* Handle arm SWI/SVC system call instructions.  */
> -  if (15 == arm_insn_r->opcode)
> +  if (op1_sbit)
>      {
>        if (tdep->arm_syscall_record != NULL)
>          {
> @@ -12016,21 +12076,52 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>            else /* EABI.  */
>              regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
>
> -          ret = tdep->arm_syscall_record (reg_cache, svc_number);
> +          return tdep->arm_syscall_record (reg_cache, svc_number);
>          }
>        else
>          {
>            printf_unfiltered (_("no syscall record support\n"));
> -          ret = -1;
> +          return -1;
>          }
>      }
> +
> +  if ((coproc & 0x0e) == 0x0a)
> +    {
> +      /* VFP data-processing instructions.  */
> +      if (!op1_sbit && !op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Advanced SIMD, VFP instructions.  */
> +      if (!op1_sbit && op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +    }
>    else
>      {
> -      arm_record_unsupported_insn (arm_insn_r);
> -      ret = -1;
> +      /* Coprocessor data operations.  */
> +      if (!op1_sbit && !op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to Coprocessor from ARM core register.  */
> +      if (!op1_sbit && !op1_ebit && op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to arm core register from coprocessor.  */
> +      if (!op1_sbit && op1_ebit && op)
> +        {
> +          uint32_t record_buf[1];
> +
> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          if (record_buf[0] == 15)
> +            record_buf[0] = ARM_PS_REGNUM;
> +
> +          arm_insn_r->reg_rec_count = 1;
> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
> +                     record_buf);
> +          return 0;
> +        }
>      }
>
> -  return ret;
> +  return arm_record_unsupported_insn (arm_insn_r);
>  }
>
>  /* Handling opcode 000 insns.  */
> @@ -12946,6 +13037,17 @@ thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
>    return ARM_RECORD_SUCCESS;
>  }
>
> +/* Record handler for thumb32 coprocessor instructions.  */
> +
> +static int
> +thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
> +{
> +  if (bit (thumb2_insn_r->arm_insn, 25))
> +    return arm_record_coproc_data_proc (thumb2_insn_r);
> +  else
> +    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
> +}
> +
>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>
>  static unsigned int
> @@ -12977,7 +13079,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (op2 & 0x40)
>          {
>            /* Co-processor instructions.  */
> -          arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>          }
>      }
>    else if (op1 == 0x02)
> @@ -13043,7 +13145,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (op2 & 0x40)
>          {
>            /* Co-processor instructions.  */
> -          return arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>          }
>     }
>
> @@ -13087,7 +13189,7 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
>      arm_record_ld_st_reg_offset,        /* 011.  */
>      arm_record_ld_st_multiple,          /* 100.  */
>      arm_record_b_bl,                    /* 101.  */
> -    arm_record_unsupported_insn,        /* 110.  */
> +    arm_record_asimd_vfp_coproc,        /* 110.  */
>      arm_record_coproc_data_proc         /* 111.  */
>    };
>
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn
  2014-08-13 13:13 ` [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn Omair Javaid
@ 2014-08-13 14:10   ` Will Newton
  2014-08-27  9:08     ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-08-13 14:10 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (thumb2_record_asimd_struct_ld_st): Added record handler
>         for advance SIMD struct ld/st insn.
>         (thumb2_record_decode_insn_handler): Updated.
>
> ---
>  gdb/arm-tdep.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 191 insertions(+), 1 deletion(-)
>
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 607b92e..adee197 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -13048,6 +13048,196 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
>      return arm_record_asimd_vfp_coproc (thumb2_insn_r);
>  }
>
> +/* Record handler for advance SIMD structure load/store instructions.  */
> +
> +static int
> +thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
> +{
> +  struct regcache *reg_cache = thumb2_insn_r->regcache;
> +  uint32_t l_bit, a_bit, b_bits;
> +  uint32_t record_buf[128], record_buf_mem[128];
> +  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
> +  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
> +  uint8_t bf_align, f_ebytes;
> +
> +  l_bit = bit (thumb2_insn_r->arm_insn, 21);
> +  a_bit = bit (thumb2_insn_r->arm_insn, 23);
> +  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
> +  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);

bf_align does not appear to be used.

> +  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
> +  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
> +  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
> +  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));

The outer brackets are redundant.

> +  f_esize = 8 * f_ebytes;
> +  f_elem = 8 / f_ebytes;
> +
> +  if (!l_bit)
> +    {
> +      ULONGEST u_regval = 0;
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      address = u_regval;
> +
> +      if (!a_bit)
> +        {
> +          /* Handle VST1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            {
> +              if (b_bits == 0x07)
> +                bf_regs = 1;
> +              else if (b_bits == 0x0a)
> +                bf_regs = 2;
> +              else if (b_bits == 0x06)
> +                bf_regs = 3;
> +              else if (b_bits == 0x02)
> +                bf_regs = 4;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                {
> +                  for (index_e = 0; index_e < f_elem; index_e++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address;
> +                      address = address + f_ebytes;
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                }
> +            }
> +          /* Handle VST2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            {
> +              if (b_bits == 0x09 || b_bits == 0x08)
> +                bf_regs = 1;
> +              else if (b_bits == 0x03)
> +                bf_regs = 2;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                for (index_e = 0; index_e < f_elem; index_e++)
> +                  {
> +                    for (loop_t = 0; loop_t < 2; loop_t++)
> +                      {
> +                        record_buf_mem[index_m++] = f_ebytes;
> +                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                        thumb2_insn_r->mem_rec_count += 1;
> +                      }
> +                    address = address + (2 * f_ebytes);
> +                  }
> +            }
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 3; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (3 * f_ebytes);
> +                }
> +            }
> +          /* Handle VST4.  */
> +          else if (!(b_bits & 0x0e))
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 4; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (4 * f_ebytes);
> +                }
> +            }
> +        }
> +      else
> +        {
> +          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
> +
> +          if (bft_size == 0x00)
> +            f_ebytes = 1;
> +          else if (bft_size == 0x01)
> +            f_ebytes = 2;
> +          else if (bft_size == 0x02)
> +            f_ebytes = 4;
> +          else
> +            f_ebytes = 0;
> +
> +          /* Handle VST1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08)
> +            thumb2_insn_r->mem_rec_count = 1;
> +          /* Handle VST2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
> +            thumb2_insn_r->mem_rec_count = 2;
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
> +            thumb2_insn_r->mem_rec_count = 3;
> +          /* Handle VST4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
> +            thumb2_insn_r->mem_rec_count = 4;
> +
> +          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
> +            {
> +              record_buf_mem[index_m] = f_ebytes;
> +              record_buf_mem[index_m] = address + (index_m * f_ebytes);
> +            }
> +        }
> +    }
> +  else
> +    {
> +      if (!a_bit)
> +        {
> +          /* Handle VLD1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if (!(b_bits & 0x0e))
> +            thumb2_insn_r->reg_rec_count = 4;
> +        }
> +      else
> +        {
> +          /* Handle VLD1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
> +            thumb2_insn_r->reg_rec_count = 4;
> +
> +          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
> +            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
> +        }
> +    }
> +
> +  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
> +    {
> +      record_buf[index_r] = reg_rn;
> +      thumb2_insn_r->reg_rec_count += 1;
> +    }
> +
> +  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
> +            record_buf);
> +  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
> +            record_buf_mem);
> +  return 0;
> +}
> +
>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>
>  static unsigned int
> @@ -13110,7 +13300,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (!((op2 & 0x71) ^ 0x10))
>          {
>            /* Advanced SIMD or structure load/store instructions.  */
> -          return arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
>          }
>        else if (!((op2 & 0x67) ^ 0x01))
>          {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 0/6] ARM process record/replay improvements
  2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
                   ` (5 preceding siblings ...)
  2014-08-13 13:13 ` [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn Omair Javaid
@ 2014-08-27  9:05 ` Omair Javaid
  6 siblings, 0 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:05 UTC (permalink / raw)
  To: gdb-patches

On 13 August 2014 18:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> This set of patches is an update to a previously posted patch set here:
> version 1) https://www.sourceware.org/ml/gdb-patches/2013-11/msg00749.html
> version 2) https://sourceware.org/ml/gdb-patches/2014-02/msg00703.html
>
> New series splits the previous patch by feature and also makes appropriate
> changes required to accomodate recently committed changes in arm process record
> code.
>
> This patch series further improves arm process record instruction coverage and
> fixes a few more testsuite failures in gdb.record.
>
> This patch set has been tested with latest gdb trunk on ARM and x86_64 targets with no regressions.
>
> All gdb.reverse tests now pass on arm targets.
>
> Omair Javaid (6):
>   Implements support for recording arm/thumb mode coprocessor
>     instructions
>   Implements support for recording thumb2 ASIMD struct ld/st insn
>   Implement support for recording VFP data processing instructions
>   Implement support for recording extension register ld/st insn
>   Implement support for recording vector data transfer instructions
>   Fix reverse-step and reverse-next over undebuggable solib code
>
>  gdb/arm-tdep.c | 784 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  gdb/infrun.c   |   5 +-
>  2 files changed, 776 insertions(+), 13 deletions(-)
>
> --
> 1.9.1
>

Ping! Any more comments on this patch series?

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions
  2014-08-13 14:10   ` Will Newton
@ 2014-08-27  9:07     ` Omair Javaid
  2014-08-27 10:05       ` Pedro Alves
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:07 UTC (permalink / raw)
  To: Will Newton; +Cc: gdb-patches

On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.
>>         (arm_record_asimd_vfp_coproc): Added record handler for asimd, vfp
>>         and coprocessor insn.
>>         (thumb2_record_coproc_insn): New function.
>>         (thumb2_record_decode_insn_handler): Updated.
>>         (decode_insn): Updated.
>>
>> ---
>>  gdb/arm-tdep.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>>  1 file changed, 112 insertions(+), 10 deletions(-)
>>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index b746eee..607b92e 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -11990,20 +11990,80 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>>    return -1;
>>  }
>>
>> +/* Handling opcode 110 insns.  */
>> +
>> +static int
>> +arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
>> +
>> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
>> +  op1 = bits (arm_insn_r->arm_insn, 20, 25);
>> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
>> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
>> +  op = bit (arm_insn_r->arm_insn, 4);
>
> op abd op1_sbit appear to be unused.
>
>> +
>> +  if ((coproc & 0x0e) == 0x0a)
>> +    {
>> +      /* Handle extension register ld/st instructions.  */
>> +      if (!(op1 & 0x20))
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +
>> +      /* 64-bit transfers between arm core and extension registers.  */
>> +      if ((op1 & 0x3e) == 0x04)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +    }
>> +  else
>> +    {
>> +      /* Handle coprocessor ld/st instructions.  */
>> +      if (!(op1 & 0x3a))
>> +        {
>> +          /* Store.  */
>> +          if (!op1_ebit)
>> +            return arm_record_unsupported_insn (arm_insn_r);
>> +          else
>> +            /* Load.  */
>> +            return arm_record_unsupported_insn (arm_insn_r);
>> +        }
>> +
>> +      /* Move to coprocessor from two arm core registers.  */
>> +      if (op1 == 0x4)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +
>> +      /* Move to two arm core registers from coprocessor.  */
>> +      if (op1 == 0x5)
>> +        {
>> +          uint32_t reg_t[2];
>> +
>> +          reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +          reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
>> +          arm_insn_r->reg_rec_count = 2;
>> +
>> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
>> +          return 0;
>> +       }
>> +    }
>> +  return arm_record_unsupported_insn (arm_insn_r);
>> +}
>> +
>>  /* Handling opcode 111 insns.  */
>>
>>  static int
>>  arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>>  {
>> +  uint32_t op, op1_sbit, op1_ebit, coproc;
>>    struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
>>    struct regcache *reg_cache = arm_insn_r->regcache;
>> -  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
>>    ULONGEST u_regval = 0;
>>
>>    arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
>> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
>> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
>> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
>> +  op = bit (arm_insn_r->arm_insn, 4);
>>
>>    /* Handle arm SWI/SVC system call instructions.  */
>> -  if (15 == arm_insn_r->opcode)
>> +  if (op1_sbit)
>>      {
>>        if (tdep->arm_syscall_record != NULL)
>>          {
>> @@ -12016,21 +12076,52 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>>            else /* EABI.  */
>>              regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
>>
>> -          ret = tdep->arm_syscall_record (reg_cache, svc_number);
>> +          return tdep->arm_syscall_record (reg_cache, svc_number);
>>          }
>>        else
>>          {
>>            printf_unfiltered (_("no syscall record support\n"));
>> -          ret = -1;
>> +          return -1;
>>          }
>>      }
>> +
>> +  if ((coproc & 0x0e) == 0x0a)
>> +    {
>> +      /* VFP data-processing instructions.  */
>> +      if (!op1_sbit && !op)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +
>> +      /* Advanced SIMD, VFP instructions.  */
>> +      if (!op1_sbit && op)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +    }
>>    else
>>      {
>> -      arm_record_unsupported_insn (arm_insn_r);
>> -      ret = -1;
>> +      /* Coprocessor data operations.  */
>> +      if (!op1_sbit && !op)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +
>> +      /* Move to Coprocessor from ARM core register.  */
>> +      if (!op1_sbit && !op1_ebit && op)
>> +        return arm_record_unsupported_insn (arm_insn_r);
>> +
>> +      /* Move to arm core register from coprocessor.  */
>> +      if (!op1_sbit && op1_ebit && op)
>> +        {
>> +          uint32_t record_buf[1];
>> +
>> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +          if (record_buf[0] == 15)
>> +            record_buf[0] = ARM_PS_REGNUM;
>> +
>> +          arm_insn_r->reg_rec_count = 1;
>> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
>> +                     record_buf);
>> +          return 0;
>> +        }
>>      }
>>
>> -  return ret;
>> +  return arm_record_unsupported_insn (arm_insn_r);
>>  }
>>
>>  /* Handling opcode 000 insns.  */
>> @@ -12946,6 +13037,17 @@ thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
>>    return ARM_RECORD_SUCCESS;
>>  }
>>
>> +/* Record handler for thumb32 coprocessor instructions.  */
>> +
>> +static int
>> +thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
>> +{
>> +  if (bit (thumb2_insn_r->arm_insn, 25))
>> +    return arm_record_coproc_data_proc (thumb2_insn_r);
>> +  else
>> +    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
>> +}
>> +
>>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>>
>>  static unsigned int
>> @@ -12977,7 +13079,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>>        else if (op2 & 0x40)
>>          {
>>            /* Co-processor instructions.  */
>> -          arm_record_unsupported_insn (thumb2_insn_r);
>> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>>          }
>>      }
>>    else if (op1 == 0x02)
>> @@ -13043,7 +13145,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>>        else if (op2 & 0x40)
>>          {
>>            /* Co-processor instructions.  */
>> -          return arm_record_unsupported_insn (thumb2_insn_r);
>> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>>          }
>>     }
>>
>> @@ -13087,7 +13189,7 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
>>      arm_record_ld_st_reg_offset,        /* 011.  */
>>      arm_record_ld_st_multiple,          /* 100.  */
>>      arm_record_b_bl,                    /* 101.  */
>> -    arm_record_unsupported_insn,        /* 110.  */
>> +    arm_record_asimd_vfp_coproc,        /* 110.  */
>>      arm_record_coproc_data_proc         /* 111.  */
>>    };
>>
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro

Ping! Kindly provide your feedback and help me approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn
  2014-08-13 14:10   ` Will Newton
@ 2014-08-27  9:08     ` Omair Javaid
  2014-08-27 10:09       ` Pedro Alves
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:08 UTC (permalink / raw)
  To: Will Newton; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (thumb2_record_asimd_struct_ld_st): Added record handler
>>         for advance SIMD struct ld/st insn.
>>         (thumb2_record_decode_insn_handler): Updated.
>>
>> ---
>>  gdb/arm-tdep.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 191 insertions(+), 1 deletion(-)
>>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index 607b92e..adee197 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -13048,6 +13048,196 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
>>      return arm_record_asimd_vfp_coproc (thumb2_insn_r);
>>  }
>>
>> +/* Record handler for advance SIMD structure load/store instructions.  */
>> +
>> +static int
>> +thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
>> +{
>> +  struct regcache *reg_cache = thumb2_insn_r->regcache;
>> +  uint32_t l_bit, a_bit, b_bits;
>> +  uint32_t record_buf[128], record_buf_mem[128];
>> +  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
>> +  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
>> +  uint8_t bf_align, f_ebytes;
>> +
>> +  l_bit = bit (thumb2_insn_r->arm_insn, 21);
>> +  a_bit = bit (thumb2_insn_r->arm_insn, 23);
>> +  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
>> +  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);
>
> bf_align does not appear to be used.
>
>> +  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
>> +  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
>> +  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
>> +  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
>
> The outer brackets are redundant.
>
>> +  f_esize = 8 * f_ebytes;
>> +  f_elem = 8 / f_ebytes;
>> +
>> +  if (!l_bit)
>> +    {
>> +      ULONGEST u_regval = 0;
>> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
>> +      address = u_regval;
>> +
>> +      if (!a_bit)
>> +        {
>> +          /* Handle VST1.  */
>> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
>> +            {
>> +              if (b_bits == 0x07)
>> +                bf_regs = 1;
>> +              else if (b_bits == 0x0a)
>> +                bf_regs = 2;
>> +              else if (b_bits == 0x06)
>> +                bf_regs = 3;
>> +              else if (b_bits == 0x02)
>> +                bf_regs = 4;
>> +              else
>> +                bf_regs = 0;
>> +
>> +              for (index_r = 0; index_r < bf_regs; index_r++)
>> +                {
>> +                  for (index_e = 0; index_e < f_elem; index_e++)
>> +                    {
>> +                      record_buf_mem[index_m++] = f_ebytes;
>> +                      record_buf_mem[index_m++] = address;
>> +                      address = address + f_ebytes;
>> +                      thumb2_insn_r->mem_rec_count += 1;
>> +                    }
>> +                }
>> +            }
>> +          /* Handle VST2.  */
>> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
>> +            {
>> +              if (b_bits == 0x09 || b_bits == 0x08)
>> +                bf_regs = 1;
>> +              else if (b_bits == 0x03)
>> +                bf_regs = 2;
>> +              else
>> +                bf_regs = 0;
>> +
>> +              for (index_r = 0; index_r < bf_regs; index_r++)
>> +                for (index_e = 0; index_e < f_elem; index_e++)
>> +                  {
>> +                    for (loop_t = 0; loop_t < 2; loop_t++)
>> +                      {
>> +                        record_buf_mem[index_m++] = f_ebytes;
>> +                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
>> +                        thumb2_insn_r->mem_rec_count += 1;
>> +                      }
>> +                    address = address + (2 * f_ebytes);
>> +                  }
>> +            }
>> +          /* Handle VST3.  */
>> +          else if ((b_bits & 0x0e) == 0x04)
>> +            {
>> +              for (index_e = 0; index_e < f_elem; index_e++)
>> +                {
>> +                  for (loop_t = 0; loop_t < 3; loop_t++)
>> +                    {
>> +                      record_buf_mem[index_m++] = f_ebytes;
>> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
>> +                      thumb2_insn_r->mem_rec_count += 1;
>> +                    }
>> +                  address = address + (3 * f_ebytes);
>> +                }
>> +            }
>> +          /* Handle VST4.  */
>> +          else if (!(b_bits & 0x0e))
>> +            {
>> +              for (index_e = 0; index_e < f_elem; index_e++)
>> +                {
>> +                  for (loop_t = 0; loop_t < 4; loop_t++)
>> +                    {
>> +                      record_buf_mem[index_m++] = f_ebytes;
>> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
>> +                      thumb2_insn_r->mem_rec_count += 1;
>> +                    }
>> +                  address = address + (4 * f_ebytes);
>> +                }
>> +            }
>> +        }
>> +      else
>> +        {
>> +          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
>> +
>> +          if (bft_size == 0x00)
>> +            f_ebytes = 1;
>> +          else if (bft_size == 0x01)
>> +            f_ebytes = 2;
>> +          else if (bft_size == 0x02)
>> +            f_ebytes = 4;
>> +          else
>> +            f_ebytes = 0;
>> +
>> +          /* Handle VST1.  */
>> +          if (!(b_bits & 0x0b) || b_bits == 0x08)
>> +            thumb2_insn_r->mem_rec_count = 1;
>> +          /* Handle VST2.  */
>> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
>> +            thumb2_insn_r->mem_rec_count = 2;
>> +          /* Handle VST3.  */
>> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
>> +            thumb2_insn_r->mem_rec_count = 3;
>> +          /* Handle VST4.  */
>> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
>> +            thumb2_insn_r->mem_rec_count = 4;
>> +
>> +          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
>> +            {
>> +              record_buf_mem[index_m] = f_ebytes;
>> +              record_buf_mem[index_m] = address + (index_m * f_ebytes);
>> +            }
>> +        }
>> +    }
>> +  else
>> +    {
>> +      if (!a_bit)
>> +        {
>> +          /* Handle VLD1.  */
>> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
>> +            thumb2_insn_r->reg_rec_count = 1;
>> +          /* Handle VLD2.  */
>> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
>> +            thumb2_insn_r->reg_rec_count = 2;
>> +          /* Handle VLD3.  */
>> +          else if ((b_bits & 0x0e) == 0x04)
>> +            thumb2_insn_r->reg_rec_count = 3;
>> +          /* Handle VLD4.  */
>> +          else if (!(b_bits & 0x0e))
>> +            thumb2_insn_r->reg_rec_count = 4;
>> +        }
>> +      else
>> +        {
>> +          /* Handle VLD1.  */
>> +          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
>> +            thumb2_insn_r->reg_rec_count = 1;
>> +          /* Handle VLD2.  */
>> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
>> +            thumb2_insn_r->reg_rec_count = 2;
>> +          /* Handle VLD3.  */
>> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
>> +            thumb2_insn_r->reg_rec_count = 3;
>> +          /* Handle VLD4.  */
>> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
>> +            thumb2_insn_r->reg_rec_count = 4;
>> +
>> +          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
>> +            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
>> +        }
>> +    }
>> +
>> +  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
>> +    {
>> +      record_buf[index_r] = reg_rn;
>> +      thumb2_insn_r->reg_rec_count += 1;
>> +    }
>> +
>> +  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
>> +            record_buf);
>> +  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
>> +            record_buf_mem);
>> +  return 0;
>> +}
>> +
>>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>>
>>  static unsigned int
>> @@ -13110,7 +13300,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>>        else if (!((op2 & 0x71) ^ 0x10))
>>          {
>>            /* Advanced SIMD or structure load/store instructions.  */
>> -          return arm_record_unsupported_insn (thumb2_insn_r);
>> +          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
>>          }
>>        else if (!((op2 & 0x67) ^ 0x01))
>>          {
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro

Ping! Kindly provide your feedback and help me approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 5/6] Implement support for recording vector data transfer instructions
  2014-08-13 14:10   ` Will Newton
@ 2014-08-27  9:09     ` Omair Javaid
  2014-08-27 10:19     ` Pedro Alves
  1 sibling, 0 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:09 UTC (permalink / raw)
  To: Will Newton; +Cc: gdb-patches

On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (arm_record_vdata_transfer_insn): Added record handler for
>>         vector data transfer instructions.
>>         (arm_record_coproc_data_proc): Updated.
>>
>> ---
>>  gdb/arm-tdep.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 97 insertions(+), 1 deletion(-)
>
> Looks ok to me.
>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index 315b5b0..7f651bc 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -11990,6 +11990,102 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>>    return -1;
>>  }
>>
>> +/* Record handler for vector data transfer instructions.  */
>> +
>> +static int
>> +arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t bits_a, bit_c, bit_l, reg_t, reg_v;
>> +  uint32_t record_buf[4];
>> +
>> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
>> +  reg_t = bits (arm_insn_r->arm_insn, 12, 15);
>> +  reg_v = bits (arm_insn_r->arm_insn, 21, 23);
>> +  bits_a = bits (arm_insn_r->arm_insn, 21, 23);
>> +  bit_l = bit (arm_insn_r->arm_insn, 20);
>> +  bit_c = bit (arm_insn_r->arm_insn, 8);
>> +
>> +  /* Handle VMOV instruction.  */
>> +  if (bit_l && bit_c)
>> +    {
>> +      record_buf[0] = reg_t;
>> +      arm_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (bit_l && !bit_c)
>> +    {
>> +      /* 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));
>> +
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      /* Handle VMRS instruction.  */
>> +      else if (bits_a == 0x07)
>> +        {
>> +          if (reg_t == 15)
>> +            reg_t = ARM_PS_REGNUM;
>> +
>> +          record_buf[0] = reg_t;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +    }
>> +  else if (!bit_l && !bit_c)
>> +    {
>> +      /* 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));
>> +
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      /* Handle VMSR instruction.  */
>> +      else if (bits_a == 0x07)
>> +        {
>> +          record_buf[0] = ARM_FPSCR_REGNUM;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +    }
>> +  else if (!bit_l && bit_c)
>> +    {
>> +      /* Handle VMOV instruction.  */
>> +      if (!(bits_a & 0x04))
>> +        {
>> +          record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
>> +                          + ARM_D0_REGNUM;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      /* Handle VDUP instruction.  */
>> +      else
>> +        {
>> +          if (bit (arm_insn_r->arm_insn, 21))
>> +            {
>> +              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
>> +              record_buf[0] = reg_v + ARM_D0_REGNUM;
>> +              record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
>> +              arm_insn_r->reg_rec_count = 2;
>> +            }
>> +          else
>> +            {
>> +              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
>> +              record_buf[0] = reg_v + ARM_D0_REGNUM;
>> +              arm_insn_r->reg_rec_count = 1;
>> +            }
>> +        }
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  return 0;
>> +}
>> +
>>  /* Record handler for extension register load/store instructions.  */
>>
>>  static int
>> @@ -12467,7 +12563,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>>
>>        /* Advanced SIMD, VFP instructions.  */
>>        if (!op1_sbit && op)
>> -        return arm_record_unsupported_insn (arm_insn_r);
>> +        return arm_record_vdata_transfer_insn (arm_insn_r);
>>      }
>>    else
>>      {
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro

Ping! Kindly provide your feedback and help me approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code
  2014-08-13 13:13 ` [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code Omair Javaid
@ 2014-08-27  9:09   ` Omair Javaid
  2014-08-27 10:34   ` Pedro Alves
  1 sibling, 0 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:09 UTC (permalink / raw)
  To: gdb-patches

On 13 August 2014 18:12, Omair Javaid <omair.javaid@linaro.org> wrote:
> This patch fixes failures to reverse-step or reverse-next over solib functions in absence of line information.
> The problem is fixed by making sure that in solib functions we keep doing reverse single stepping in absence of line information.
>
> Tested with no regressions on arm, aarch64 and x86_64.
>
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * infrun.c (process_event_stop_test): Updated.
>
> ---
>  gdb/infrun.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index c18267f..db8f15b 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -4905,12 +4905,15 @@ process_event_stop_test (struct execution_control_state *ecs)
>        return;
>      }
>
> +  stop_pc_sal = find_pc_line (stop_pc, 0);
> +
>    /* Reverse stepping through solib trampolines.  */
>
>    if (execution_direction == EXEC_REVERSE
>        && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
>      {
>        if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
> +         || stop_pc_sal.line == 0
>           || (ecs->stop_func_start == 0
>               && in_solib_dynsym_resolve_code (stop_pc)))
>         {
> @@ -4939,8 +4942,6 @@ process_event_stop_test (struct execution_control_state *ecs)
>         }
>      }
>
> -  stop_pc_sal = find_pc_line (stop_pc, 0);
> -
>    /* NOTE: tausq/2004-05-24: This if block used to be done before all
>       the trampoline processing logic, however, there are some trampolines
>       that have no names, so we should do trampoline handling first.  */
> --
> 1.9.1
>

Ping! Kindly provide your feedback and help me approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 3/6] Implement support for recording VFP data processing instructions
  2014-08-13 14:10   ` Will Newton
@ 2014-08-27  9:10     ` Omair Javaid
  2014-08-27 10:11       ` Pedro Alves
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:10 UTC (permalink / raw)
  To: Will Newton; +Cc: gdb-patches

On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.
>>         (arm_record_vfp_data_proc_insn): Added record handler for VFP data
>>         processing instructions.
>>
>> ---
>>  gdb/arm-tdep.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 212 insertions(+), 1 deletion(-)
>
> Looks ok to me.
>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index adee197..d003619 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -11990,6 +11990,217 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>>    return -1;
>>  }
>>
>> +/* Record handler for arm/thumb mode VFP data processing instructions.  */
>> +
>> +static int
>> +arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t opc1, opc2, opc3, dp_op_sz, bit_d, reg_vd;
>> +  uint32_t record_buf[4];
>> +  enum insn_types {INSN_T0, INSN_T1, INSN_T2, INSN_T3, INSN_INV};
>> +  enum insn_types curr_insn_type = INSN_INV;
>> +
>> +  reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
>> +  opc1 = bits (arm_insn_r->arm_insn, 20, 23);
>> +  opc2 = bits (arm_insn_r->arm_insn, 16, 19);
>> +  opc3 = bits (arm_insn_r->arm_insn, 6, 7);
>> +  dp_op_sz = bit (arm_insn_r->arm_insn, 8);
>> +  bit_d = bit (arm_insn_r->arm_insn, 22);
>> +  opc1 = opc1 & 0x04;
>> +
>> +  /* Handle VMLA, VMLS.  */
>> +  if (opc1 == 0x00)
>> +    {
>> +      if (bit (arm_insn_r->arm_insn, 10))
>> +        {
>> +          if (bit (arm_insn_r->arm_insn, 6))
>> +            curr_insn_type = INSN_T0;
>> +          else
>> +            curr_insn_type = INSN_T1;
>> +        }
>> +      else
>> +        {
>> +          if (dp_op_sz)
>> +            curr_insn_type = INSN_T1;
>> +          else
>> +            curr_insn_type = INSN_T2;
>> +        }
>> +    }
>> +  /* Handle VNMLA, VNMLS, VNMUL.  */
>> +  else if (opc1 == 0x01)
>> +    {
>> +      if (dp_op_sz)
>> +        curr_insn_type = INSN_T1;
>> +      else
>> +        curr_insn_type = INSN_T2;
>> +    }
>> +  /* Handle VMUL.  */
>> +  else if (opc1 == 0x02 && !(opc3 & 0x01))
>> +    {
>> +      if (bit (arm_insn_r->arm_insn, 10))
>> +        {
>> +          if (bit (arm_insn_r->arm_insn, 6))
>> +            curr_insn_type = INSN_T0;
>> +          else
>> +            curr_insn_type = INSN_T1;
>> +        }
>> +      else
>> +        {
>> +          if (dp_op_sz)
>> +            curr_insn_type = INSN_T1;
>> +          else
>> +            curr_insn_type = INSN_T2;
>> +        }
>> +    }
>> +  /* Handle VADD, VSUB.  */
>> +  else if (opc1 == 0x03)
>> +    {
>> +      if (!bit (arm_insn_r->arm_insn, 9))
>> +        {
>> +          if (bit (arm_insn_r->arm_insn, 6))
>> +            curr_insn_type = INSN_T0;
>> +          else
>> +            curr_insn_type = INSN_T1;
>> +        }
>> +      else
>> +        {
>> +          if (dp_op_sz)
>> +            curr_insn_type = INSN_T1;
>> +          else
>> +            curr_insn_type = INSN_T2;
>> +        }
>> +    }
>> +  /* Handle VDIV.  */
>> +  else if (opc1 == 0x0b)
>> +    {
>> +      if (dp_op_sz)
>> +        curr_insn_type = INSN_T1;
>> +      else
>> +        curr_insn_type = INSN_T2;
>> +    }
>> +  /* Handle all other vfp data processing instructions.  */
>> +  else if (opc1 == 0x0b)
>> +    {
>> +      /* Handle VMOV.  */
>> +      if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
>> +        {
>> +          if (bit (arm_insn_r->arm_insn, 4))
>> +            {
>> +              if (bit (arm_insn_r->arm_insn, 6))
>> +                curr_insn_type = INSN_T0;
>> +              else
>> +                curr_insn_type = INSN_T1;
>> +            }
>> +          else
>> +            {
>> +              if (dp_op_sz)
>> +                curr_insn_type = INSN_T1;
>> +              else
>> +                curr_insn_type = INSN_T2;
>> +            }
>> +        }
>> +      /* Handle VNEG and VABS.  */
>> +      else if ((opc2 == 0x01 && opc3 == 0x01)
>> +              || (opc2 == 0x00 && opc3 == 0x03))
>> +        {
>> +          if (!bit (arm_insn_r->arm_insn, 11))
>> +            {
>> +              if (bit (arm_insn_r->arm_insn, 6))
>> +                curr_insn_type = INSN_T0;
>> +              else
>> +                curr_insn_type = INSN_T1;
>> +            }
>> +          else
>> +            {
>> +              if (dp_op_sz)
>> +                curr_insn_type = INSN_T1;
>> +              else
>> +                curr_insn_type = INSN_T2;
>> +            }
>> +        }
>> +      /* Handle VSQRT.  */
>> +      else if (opc2 == 0x01 && opc3 == 0x03)
>> +        {
>> +          if (dp_op_sz)
>> +            curr_insn_type = INSN_T1;
>> +          else
>> +            curr_insn_type = INSN_T2;
>> +        }
>> +      /* Handle VCVT.  */
>> +      else if (opc2 == 0x07 && opc3 == 0x03)
>> +        {
>> +          if (!dp_op_sz)
>> +            curr_insn_type = INSN_T1;
>> +          else
>> +            curr_insn_type = INSN_T2;
>> +        }
>> +      else if (opc3 & 0x01)
>> +        {
>> +          /* Handle VCVT.  */
>> +          if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
>> +            {
>> +              if (!bit (arm_insn_r->arm_insn, 18))
>> +                curr_insn_type = INSN_T2;
>> +              else
>> +                {
>> +                  if (dp_op_sz)
>> +                    curr_insn_type = INSN_T1;
>> +                  else
>> +                    curr_insn_type = INSN_T2;
>> +                }
>> +            }
>> +          /* Handle VCVT.  */
>> +          else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
>> +            {
>> +              if (dp_op_sz)
>> +                curr_insn_type = INSN_T1;
>> +              else
>> +                curr_insn_type = INSN_T2;
>> +            }
>> +          /* Handle VCVTB, VCVTT.  */
>> +          else if ((opc2 & 0x0e) == 0x02)
>> +            curr_insn_type = INSN_T2;
>> +          /* Handle VCMP, VCMPE.  */
>> +          else if ((opc2 & 0x0e) == 0x04)
>> +            curr_insn_type = INSN_T3;
>> +        }
>> +    }
>> +
>> +  switch (curr_insn_type)
>> +    {
>> +      case INSN_T0:
>> +        reg_vd = reg_vd | (bit_d << 4);
>> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
>> +        record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
>> +        arm_insn_r->reg_rec_count = 2;
>> +        break;
>> +
>> +      case INSN_T1:
>> +        reg_vd = reg_vd | (bit_d << 4);
>> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
>> +        arm_insn_r->reg_rec_count = 1;
>> +        break;
>> +
>> +      case INSN_T2:
>> +        reg_vd = (reg_vd << 1) | bit_d;
>> +        record_buf[0] = reg_vd + ARM_D0_REGNUM;
>> +        arm_insn_r->reg_rec_count = 1;
>> +        break;
>> +
>> +      case INSN_T3:
>> +        record_buf[0] = ARM_FPSCR_REGNUM;
>> +        arm_insn_r->reg_rec_count = 1;
>> +        break;
>> +
>> +      default:
>> +        gdb_assert_not_reached ("no decoding pattern found");
>> +        break;
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  return 0;
>> +}
>> +
>>  /* Handling opcode 110 insns.  */
>>
>>  static int
>> @@ -12089,7 +12300,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>>      {
>>        /* VFP data-processing instructions.  */
>>        if (!op1_sbit && !op)
>> -        return arm_record_unsupported_insn (arm_insn_r);
>> +        return arm_record_vfp_data_proc_insn (arm_insn_r);
>>
>>        /* Advanced SIMD, VFP instructions.  */
>>        if (!op1_sbit && op)
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro

Ping! Kindly provide your feedback and help me approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-13 14:10   ` Will Newton
@ 2014-08-27  9:21     ` Omair Javaid
  2014-08-27 10:17       ` Pedro Alves
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-27  9:21 UTC (permalink / raw)
  To: Will Newton; +Cc: gdb-patches, Patch Tracking

On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (arm_record_asimd_vfp_coproc): Updated.
>>         (arm_record_exreg_ld_st_insn): Added record handler for ex-register
>>         load/store instructions.
>>
>> ---
>>  gdb/arm-tdep.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 165 insertions(+), 2 deletions(-)
>>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index d003619..315b5b0 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -11990,6 +11990,169 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>>    return -1;
>>  }
>>
>> +/* Record handler for extension register load/store instructions.  */
>> +
>> +static int
>> +arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t opcode, single_reg;
>> +  uint8_t op_vldm_vstm;
>> +  uint32_t record_buf[8], record_buf_mem[128];
>> +  ULONGEST u_regval = 0;
>> +
>> +  struct regcache *reg_cache = arm_insn_r->regcache;
>> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
>> +
>> +  opcode = bits (arm_insn_r->arm_insn, 20, 24);
>> +  single_reg = bit (arm_insn_r->arm_insn, 8);
>> +  op_vldm_vstm = opcode & 0x1b;
>> +
>> +  /* Handle VMOV instructions.  */
>> +  if ((opcode & 0x1e) == 0x04)
>> +    {
>> +      if (bit (arm_insn_r->arm_insn, 4))
>> +        {
>> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
>> +          arm_insn_r->reg_rec_count = 2;
>> +        }
>> +      else
>> +        {
>> +          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
>> +                          | bit (arm_insn_r->arm_insn, 5);
>> +
>> +          if (!single_reg)
>> +            {
>> +              record_buf[0] = num_regs + reg_m;
>> +              record_buf[1] = num_regs + reg_m + 1;
>> +              arm_insn_r->reg_rec_count = 2;
>> +            }
>> +          else
>> +            {
>> +              record_buf[0] = reg_m + ARM_D0_REGNUM;
>> +              arm_insn_r->reg_rec_count = 1;
>> +            }
>> +        }
>> +    }
>> +  /* Handle VSTM and VPUSH instructions.  */
>> +  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
>> +          || op_vldm_vstm == 0x12)
>> +    {
>> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
>> +      uint32_t memory_index = 0;
>> +
>> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
>> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
>> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
>> +      imm_off32 = imm_off8 << 24;
>> +      memory_count = imm_off8;
>> +
>> +      if (bit (arm_insn_r->arm_insn, 23))
>> +        start_address = u_regval;
>> +      else
>> +        start_address = u_regval - imm_off32;
>> +
>> +      if (bit (arm_insn_r->arm_insn, 21))
>> +        {
>> +          record_buf[0] = reg_rn;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +
>> +      while (memory_count)
>> +        {
>> +          if (!single_reg)
>> +            {
>> +              record_buf_mem[memory_index] = start_address;
>> +              record_buf_mem[memory_index + 1] = 4;
>> +              start_address = start_address + 4;
>> +              memory_index = memory_index + 2;
>> +            }
>> +          else
>> +            {
>> +              record_buf_mem[memory_index] = start_address;
>> +              record_buf_mem[memory_index + 1] = 4;
>> +              record_buf_mem[memory_index + 2] = start_address + 4;
>> +              record_buf_mem[memory_index + 3] = 4;
>> +              start_address = start_address + 8;
>> +              memory_index = memory_index + 4;
>> +            }
>> +          memory_count--;
>> +        }
>> +    }
>> +  /* Handle VLDM instructions.  */
>> +  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
>> +          || op_vldm_vstm == 0x13)
>> +    {
>> +      uint32_t reg_count, reg_vd;
>> +      uint32_t reg_index = 0;
>> +
>> +      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
>> +      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
>> +
>> +      if (single_reg)
>> +        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 0) << 4);
>> +      else
>> +        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 0);
>> +
>> +      if (bit (arm_insn_r->arm_insn, 21))
>> +        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
>> +
>> +      while (reg_count)
>> +        {
>> +          if (single_reg)
>> +              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
>> +          else
>> +              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
>> +
>> +          reg_count--;
>> +        }
>> +    }
>> +  /* VSTR Vector store register.  */
>> +  else if ((opcode & 0x13) == 0x10)
>> +    {
>> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
>> +      uint32_t memory_index = 0;
>> +
>> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
>> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
>> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
>> +      imm_off32 = imm_off8 << 24;
>> +      memory_count = imm_off8;
>> +
>> +      if (bit (arm_insn_r->arm_insn, 23))
>> +        start_address = u_regval + imm_off32;
>> +      else
>> +        start_address = u_regval - imm_off32;
>> +
>> +      if (single_reg)
>> +        {
>> +          record_buf_mem[memory_index] = start_address;
>> +          record_buf_mem[memory_index + 1] = 4;
>> +        }
>> +      else
>> +        {
>> +          record_buf_mem[memory_index] = start_address;
>> +          record_buf_mem[memory_index + 1] = 4;
>> +          record_buf_mem[memory_index + 2] = start_address + 4;
>> +          record_buf_mem[memory_index + 3] = 4;
>> +        }
>> +    }
>> +  /* VLDR Vector load register.  */
>> +  else if ((opcode & 0x13) == 0x11)
>> +    {
>> +      uint8_t single_reg = 0;
>> +      uint8_t special_case;
>
> Is there some missing code here? Should there be a TODO comment?

Seems like a bit of code missing here will update it in the final patch.
>
>> +
>> +      record_buf[0] = 0;
>> +      record_buf[1] = 0;
>> +      arm_insn_r->reg_rec_count = 2;
>> +    }
>> +
>> +  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);
>> +  return 0;
>> +}
>> +
>>  /* Record handler for arm/thumb mode VFP data processing instructions.  */
>>
>>  static int
>> @@ -12218,11 +12381,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>>      {
>>        /* Handle extension register ld/st instructions.  */
>>        if (!(op1 & 0x20))
>> -        return arm_record_unsupported_insn (arm_insn_r);
>> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>>
>>        /* 64-bit transfers between arm core and extension registers.  */
>>        if ((op1 & 0x3e) == 0x04)
>> -        return arm_record_unsupported_insn (arm_insn_r);
>> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>>      }
>>    else
>>      {
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro

Ping! Kindly provide your feedback any further comments will help me
approve this patch series.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions
  2014-08-27  9:07     ` Omair Javaid
@ 2014-08-27 10:05       ` Pedro Alves
  2014-08-28  9:50         ` [PATCH] Implement " Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:05 UTC (permalink / raw)
  To: Omair Javaid, Will Newton; +Cc: gdb-patches

Hi Omair,

On 08/27/2014 10:07 AM, Omair Javaid wrote:
> On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
>> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>>> gdb:
>>>

From the nit department:

>>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>>
>>>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.

please use imperative, present tense in logs.  Also in the $subject
line when that gets into the commit log: s/Implements/Implement/.

And, updated how?  What changed?  Please write something
like:

	* arm-tdep.c (arm_record_coproc_data_proc): Handle foo instructions.

with 'foo' replaced, of course.  :-)

>>>         (arm_record_asimd_vfp_coproc): Added record handler for asimd, vfp
>>>         and coprocessor insn.

'Add'.

>>>         (thumb2_record_coproc_insn): New function.
>>>         (thumb2_record_decode_insn_handler): Updated.

Likewise, updated how?

>>>         (decode_insn): Updated.

Say something like:
	
	(decode_insn): Install arm_record_asimd_vfp_coproc as handler for
	opcode 110 insns.

>>> +/* Handling opcode 110 insns.  */
>>> +
>>> +static int
>>> +arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>>> +{
>>> +  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
>>> +
>>> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
>>> +  op1 = bits (arm_insn_r->arm_insn, 20, 25);
>>> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
>>> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
>>> +  op = bit (arm_insn_r->arm_insn, 4);
>>
>> op abd op1_sbit appear to be unused.

> Ping! Kindly provide your feedback and help me approve this patch series.

I didn't see a reply to Will's comment.  Should op1_sbit haven been used?

This patch is OK once Will is happy with it.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn
  2014-08-27  9:08     ` Omair Javaid
@ 2014-08-27 10:09       ` Pedro Alves
  2014-08-28 10:56         ` [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:09 UTC (permalink / raw)
  To: Omair Javaid, Will Newton; +Cc: gdb-patches, Patch Tracking

On 08/27/2014 10:07 AM, Omair Javaid wrote:
> On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
>> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>>> gdb:
>>>

Same comments as previous patch on ChangeLog and $subject.
Please likewise adjust all patches in the series.

>>> +static int
>>> +thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
>>> +{
>>> +  struct regcache *reg_cache = thumb2_insn_r->regcache;
>>> +  uint32_t l_bit, a_bit, b_bits;
>>> +  uint32_t record_buf[128], record_buf_mem[128];
>>> +  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
>>> +  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
>>> +  uint8_t bf_align, f_ebytes;
>>> +
>>> +  l_bit = bit (thumb2_insn_r->arm_insn, 21);
>>> +  a_bit = bit (thumb2_insn_r->arm_insn, 23);
>>> +  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
>>> +  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);
>>
>> bf_align does not appear to be used.
>>
>>> +  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
>>> +  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
>>> +  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
>>> +  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
>>
>> The outer brackets are redundant.


> Ping! Kindly provide your feedback and help me approve this patch series.

This is OK with Will's comments addressed.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 3/6] Implement support for recording VFP data processing instructions
  2014-08-27  9:10     ` Omair Javaid
@ 2014-08-27 10:11       ` Pedro Alves
  2014-08-28 11:06         ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:11 UTC (permalink / raw)
  To: Omair Javaid, Will Newton; +Cc: gdb-patches

On 08/27/2014 10:10 AM, Omair Javaid wrote:
> On 13 August 2014 19:10, Will Newton <will.newton@linaro.org> wrote:
>> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>>> gdb:
>>>
>>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>>
>>>         * arm-tdep.c (arm_record_coproc_data_proc): Updated.
>>>         (arm_record_vfp_data_proc_insn): Added record handler for VFP data
>>>         processing instructions.
>>>
>>> ---
>>>  gdb/arm-tdep.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 212 insertions(+), 1 deletion(-)
>>
>> Looks ok to me.

Thanks both.

This is OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-27  9:21     ` Omair Javaid
@ 2014-08-27 10:17       ` Pedro Alves
  2014-08-28 12:56         ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:17 UTC (permalink / raw)
  To: Omair Javaid, Will Newton; +Cc: gdb-patches, Patch Tracking

On 08/27/2014 10:21 AM, Omair Javaid wrote:

> +      while (memory_count)
> +        {

> +      while (reg_count)


Not implicit boolean coercion please.  Write
'memory_count != 0' or 'memory_count > 0'.

>>> >> +  /* VLDR Vector load register.  */
>>> >> +  else if ((opcode & 0x13) == 0x11)
>>> >> +    {
>>> >> +      uint8_t single_reg = 0;
>>> >> +      uint8_t special_case;
>> >
>> > Is there some missing code here? Should there be a TODO comment?
> Seems like a bit of code missing here will update it in the final patch.

It's kind of hard to review code that we don't see... :-)
Please post the updated patch.

> Ping! Kindly provide your feedback any further comments will help me
> approve this patch series.

This is OK if Will is happy with the updated patch.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 5/6] Implement support for recording vector data transfer instructions
  2014-08-13 14:10   ` Will Newton
  2014-08-27  9:09     ` Omair Javaid
@ 2014-08-27 10:19     ` Pedro Alves
  2014-08-28 13:07       ` Omair Javaid
  1 sibling, 1 reply; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:19 UTC (permalink / raw)
  To: Will Newton, Omair Javaid; +Cc: gdb-patches, Patch Tracking

On 08/13/2014 03:10 PM, Will Newton wrote:
> On 13 August 2014 14:12, Omair Javaid <omair.javaid@linaro.org> wrote:
>> gdb:
>>
>> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>>
>>         * arm-tdep.c (arm_record_vdata_transfer_insn): Added record handler for
>>         vector data transfer instructions.
>>         (arm_record_coproc_data_proc): Updated.
>>
>> ---
>>  gdb/arm-tdep.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 97 insertions(+), 1 deletion(-)
> 
> Looks ok to me.

This is OK then.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code
  2014-08-13 13:13 ` [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code Omair Javaid
  2014-08-27  9:09   ` Omair Javaid
@ 2014-08-27 10:34   ` Pedro Alves
  1 sibling, 0 replies; 37+ messages in thread
From: Pedro Alves @ 2014-08-27 10:34 UTC (permalink / raw)
  To: Omair Javaid, gdb-patches; +Cc: patches

(This patch doesn't look specific to ARM, and thus could/should
be split out from the rest of the series.)

On 08/13/2014 02:12 PM, Omair Javaid wrote:
> This patch fixes failures to reverse-step or reverse-next over solib functions in absence of line information.

Could you describe the failure a little more please?  What happens instead?

> The problem is fixed by making sure that in solib functions we keep doing reverse single stepping in absence of line information.
> 
> Tested with no regressions on arm, aarch64 and x86_64.

Is there a test in the testsuite that fails before this patch?
If not, could you add one?

There's another similarly looking piece of code above
with the same comment: "Reverse stepping through solib trampolines
that I'm wondering whether it needs treatment as well.

Thanks!

> 
> gdb:
> 
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
> 
> 	* infrun.c (process_event_stop_test): Updated.

Same remark as previous patches here.

> 
> ---
>  gdb/infrun.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index c18267f..db8f15b 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -4905,12 +4905,15 @@ process_event_stop_test (struct execution_control_state *ecs)
>        return;
>      }
>  
> +  stop_pc_sal = find_pc_line (stop_pc, 0);
> +
>    /* Reverse stepping through solib trampolines.  */
>  
>    if (execution_direction == EXEC_REVERSE
>        && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
>      {
>        if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
> +	  || stop_pc_sal.line == 0
>  	  || (ecs->stop_func_start == 0
>  	      && in_solib_dynsym_resolve_code (stop_pc)))
>  	{
> @@ -4939,8 +4942,6 @@ process_event_stop_test (struct execution_control_state *ecs)
>  	}
>      }
>  
> -  stop_pc_sal = find_pc_line (stop_pc, 0);
> -
>    /* NOTE: tausq/2004-05-24: This if block used to be done before all
>       the trampoline processing logic, however, there are some trampolines 
>       that have no names, so we should do trampoline handling first.  */
> 

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH] Implement support for recording arm/thumb mode coprocessor instructions
  2014-08-27 10:05       ` Pedro Alves
@ 2014-08-28  9:50         ` Omair Javaid
  2014-09-02 14:51           ` Will Newton
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-28  9:50 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_coproc_data_proc): Add record handler stubs
	for asimd, vfp and coprocessor insns.
	(arm_record_asimd_vfp_coproc): Add record handler for asimd, vfp
	and coprocessor insns.
	(thumb2_record_coproc_insn): New function.
	(thumb2_record_decode_insn_handler): Update coprocessor insns record
        handlers.
	(decode_insn): Install arm_record_asimd_vfp_coproc as handler for
        opcode 110 insns.

---
 gdb/arm-tdep.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 110 insertions(+), 10 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 9bc6507..d659897 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -12022,20 +12022,78 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Handling opcode 110 insns.  */
+
+static int
+arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
+{
+  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
+
+  coproc = bits (arm_insn_r->arm_insn, 8, 11);
+  op1 = bits (arm_insn_r->arm_insn, 20, 25);
+  op1_ebit = bit (arm_insn_r->arm_insn, 20);
+
+  if ((coproc & 0x0e) == 0x0a)
+    {
+      /* Handle extension register ld/st instructions.  */
+      if (!(op1 & 0x20))
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* 64-bit transfers between arm core and extension registers.  */
+      if ((op1 & 0x3e) == 0x04)
+        return arm_record_unsupported_insn (arm_insn_r);
+    }
+  else
+    {
+      /* Handle coprocessor ld/st instructions.  */
+      if (!(op1 & 0x3a))
+        {
+          /* Store.  */
+          if (!op1_ebit)
+            return arm_record_unsupported_insn (arm_insn_r);
+          else
+            /* Load.  */
+            return arm_record_unsupported_insn (arm_insn_r);
+        }
+
+      /* Move to coprocessor from two arm core registers.  */
+      if (op1 == 0x4)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to two arm core registers from coprocessor.  */
+      if (op1 == 0x5)
+        {
+          uint32_t reg_t[2];
+
+          reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
+          arm_insn_r->reg_rec_count = 2;
+
+          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
+          return 0;
+       }
+    }
+  return arm_record_unsupported_insn (arm_insn_r);
+}
+
 /* Handling opcode 111 insns.  */
 
 static int
 arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
 {
+  uint32_t op, op1_sbit, op1_ebit, coproc;
   struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
   struct regcache *reg_cache = arm_insn_r->regcache;
-  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
   ULONGEST u_regval = 0;
 
   arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
+  coproc = bits (arm_insn_r->arm_insn, 8, 11);
+  op1_sbit = bit (arm_insn_r->arm_insn, 24);
+  op1_ebit = bit (arm_insn_r->arm_insn, 20);
+  op = bit (arm_insn_r->arm_insn, 4);
 
   /* Handle arm SWI/SVC system call instructions.  */
-  if (15 == arm_insn_r->opcode)
+  if (op1_sbit)
     {
       if (tdep->arm_syscall_record != NULL)
         {
@@ -12048,21 +12106,52 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
           else /* EABI.  */
             regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
 
-          ret = tdep->arm_syscall_record (reg_cache, svc_number);
+          return tdep->arm_syscall_record (reg_cache, svc_number);
         }
       else
         {
           printf_unfiltered (_("no syscall record support\n"));
-          ret = -1;
+          return -1;
         }
     }
+
+  if ((coproc & 0x0e) == 0x0a)
+    {
+      /* VFP data-processing instructions.  */
+      if (!op1_sbit && !op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Advanced SIMD, VFP instructions.  */
+      if (!op1_sbit && op)
+        return arm_record_unsupported_insn (arm_insn_r);
+    }
   else
     {
-      arm_record_unsupported_insn (arm_insn_r);
-      ret = -1;
+      /* Coprocessor data operations.  */
+      if (!op1_sbit && !op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to Coprocessor from ARM core register.  */
+      if (!op1_sbit && !op1_ebit && op)
+        return arm_record_unsupported_insn (arm_insn_r);
+
+      /* Move to arm core register from coprocessor.  */
+      if (!op1_sbit && op1_ebit && op)
+        {
+          uint32_t record_buf[1];
+
+          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          if (record_buf[0] == 15)
+            record_buf[0] = ARM_PS_REGNUM;
+
+          arm_insn_r->reg_rec_count = 1;
+          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
+                     record_buf);
+          return 0;
+        }
     }
 
-  return ret;
+  return arm_record_unsupported_insn (arm_insn_r);
 }
 
 /* Handling opcode 000 insns.  */
@@ -12978,6 +13067,17 @@ thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
   return ARM_RECORD_SUCCESS;
 }
 
+/* Record handler for thumb32 coprocessor instructions.  */
+
+static int
+thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
+{
+  if (bit (thumb2_insn_r->arm_insn, 25))
+    return arm_record_coproc_data_proc (thumb2_insn_r);
+  else
+    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
+}
+
 /* Decodes thumb2 instruction type and invokes its record handler.  */
 
 static unsigned int
@@ -13009,7 +13109,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (op2 & 0x40)
         {
           /* Co-processor instructions.  */
-          arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_coproc_insn (thumb2_insn_r);
         }
     }
   else if (op1 == 0x02)
@@ -13075,7 +13175,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (op2 & 0x40)
         {
           /* Co-processor instructions.  */
-          return arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_coproc_insn (thumb2_insn_r);
         }
    }
 
@@ -13119,7 +13219,7 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
     arm_record_ld_st_reg_offset,        /* 011.  */
     arm_record_ld_st_multiple,          /* 100.  */
     arm_record_b_bl,                    /* 101.  */
-    arm_record_unsupported_insn,        /* 110.  */
+    arm_record_asimd_vfp_coproc,        /* 110.  */
     arm_record_coproc_data_proc         /* 111.  */
   };
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns
  2014-08-27 10:09       ` Pedro Alves
@ 2014-08-28 10:56         ` Omair Javaid
  2014-09-02 14:55           ` Will Newton
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-28 10:56 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (thumb2_record_asimd_struct_ld_st): Add record handler
	for advance SIMD struct ld/st insn.
	(thumb2_record_decode_insn_handler): Replace stub handler with
	thumb2_record_asimd_struct_ld_st.

---
 gdb/arm-tdep.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 191 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index d659897..a4a7f15 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -13078,6 +13078,196 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
     return arm_record_asimd_vfp_coproc (thumb2_insn_r);
 }
 
+/* Record handler for advance SIMD structure load/store instructions.  */
+
+static int
+thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
+{
+  struct regcache *reg_cache = thumb2_insn_r->regcache;
+  uint32_t l_bit, a_bit, b_bits;
+  uint32_t record_buf[128], record_buf_mem[128];
+  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
+  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
+  uint8_t bf_align, f_ebytes;
+
+  l_bit = bit (thumb2_insn_r->arm_insn, 21);
+  a_bit = bit (thumb2_insn_r->arm_insn, 23);
+  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
+  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);
+  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
+  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
+  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
+  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
+  f_esize = 8 * f_ebytes;
+  f_elem = 8 / f_ebytes;
+
+  if (!l_bit)
+    {
+      ULONGEST u_regval = 0;
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      address = u_regval;
+
+      if (!a_bit)
+        {
+          /* Handle VST1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            {
+              if (b_bits == 0x07)
+                bf_regs = 1;
+              else if (b_bits == 0x0a)
+                bf_regs = 2;
+              else if (b_bits == 0x06)
+                bf_regs = 3;
+              else if (b_bits == 0x02)
+                bf_regs = 4;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                {
+                  for (index_e = 0; index_e < f_elem; index_e++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address;
+                      address = address + f_ebytes;
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                }
+            }
+          /* Handle VST2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            {
+              if (b_bits == 0x09 || b_bits == 0x08)
+                bf_regs = 1;
+              else if (b_bits == 0x03)
+                bf_regs = 2;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                for (index_e = 0; index_e < f_elem; index_e++)
+                  {
+                    for (loop_t = 0; loop_t < 2; loop_t++)
+                      {
+                        record_buf_mem[index_m++] = f_ebytes;
+                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                        thumb2_insn_r->mem_rec_count += 1;
+                      }
+                    address = address + (2 * f_ebytes);
+                  }
+            }
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 3; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (3 * f_ebytes);
+                }
+            }
+          /* Handle VST4.  */
+          else if (!(b_bits & 0x0e))
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 4; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (4 * f_ebytes);
+                }
+            }
+        }
+      else
+        {
+          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
+
+          if (bft_size == 0x00)
+            f_ebytes = 1;
+          else if (bft_size == 0x01)
+            f_ebytes = 2;
+          else if (bft_size == 0x02)
+            f_ebytes = 4;
+          else
+            f_ebytes = 0;
+
+          /* Handle VST1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08)
+            thumb2_insn_r->mem_rec_count = 1;
+          /* Handle VST2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
+            thumb2_insn_r->mem_rec_count = 2;
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
+            thumb2_insn_r->mem_rec_count = 3;
+          /* Handle VST4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
+            thumb2_insn_r->mem_rec_count = 4;
+
+          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
+            {
+              record_buf_mem[index_m] = f_ebytes;
+              record_buf_mem[index_m] = address + (index_m * f_ebytes);
+            }
+        }
+    }
+  else
+    {
+      if (!a_bit)
+        {
+          /* Handle VLD1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if (!(b_bits & 0x0e))
+            thumb2_insn_r->reg_rec_count = 4;
+        }
+      else
+        {
+          /* Handle VLD1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
+            thumb2_insn_r->reg_rec_count = 4;
+
+          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
+            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
+        }
+    }
+
+  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
+    {
+      record_buf[index_r] = reg_rn;
+      thumb2_insn_r->reg_rec_count += 1;
+    }
+
+  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
+            record_buf);
+  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
+            record_buf_mem);
+  return 0;
+}
+
 /* Decodes thumb2 instruction type and invokes its record handler.  */
 
 static unsigned int
@@ -13140,7 +13330,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (!((op2 & 0x71) ^ 0x10))
         {
           /* Advanced SIMD or structure load/store instructions.  */
-          return arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
         }
       else if (!((op2 & 0x67) ^ 0x01))
         {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 3/6] Implement support for recording VFP data processing instructions
  2014-08-27 10:11       ` Pedro Alves
@ 2014-08-28 11:06         ` Omair Javaid
  0 siblings, 0 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-28 11:06 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_coproc_data_proc): Update handler for VFP data
	processing insns.
	(arm_record_vfp_data_proc_insn): Add record handler for VFP data
	processing insns.

---
 gdb/arm-tdep.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 212 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index a4a7f15..8d55105 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -12022,6 +12022,217 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for arm/thumb mode VFP data processing instructions.  */
+
+static int
+arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t opc1, opc2, opc3, dp_op_sz, bit_d, reg_vd;
+  uint32_t record_buf[4];
+  enum insn_types {INSN_T0, INSN_T1, INSN_T2, INSN_T3, INSN_INV};
+  enum insn_types curr_insn_type = INSN_INV;
+
+  reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+  opc1 = bits (arm_insn_r->arm_insn, 20, 23);
+  opc2 = bits (arm_insn_r->arm_insn, 16, 19);
+  opc3 = bits (arm_insn_r->arm_insn, 6, 7);
+  dp_op_sz = bit (arm_insn_r->arm_insn, 8);
+  bit_d = bit (arm_insn_r->arm_insn, 22);
+  opc1 = opc1 & 0x04;
+
+  /* Handle VMLA, VMLS.  */
+  if (opc1 == 0x00)
+    {
+      if (bit (arm_insn_r->arm_insn, 10))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VNMLA, VNMLS, VNMUL.  */
+  else if (opc1 == 0x01)
+    {
+      if (dp_op_sz)
+        curr_insn_type = INSN_T1;
+      else
+        curr_insn_type = INSN_T2;
+    }
+  /* Handle VMUL.  */
+  else if (opc1 == 0x02 && !(opc3 & 0x01))
+    {
+      if (bit (arm_insn_r->arm_insn, 10))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VADD, VSUB.  */
+  else if (opc1 == 0x03)
+    {
+      if (!bit (arm_insn_r->arm_insn, 9))
+        {
+          if (bit (arm_insn_r->arm_insn, 6))
+            curr_insn_type = INSN_T0;
+          else
+            curr_insn_type = INSN_T1;
+        }
+      else
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+    }
+  /* Handle VDIV.  */
+  else if (opc1 == 0x0b)
+    {
+      if (dp_op_sz)
+        curr_insn_type = INSN_T1;
+      else
+        curr_insn_type = INSN_T2;
+    }
+  /* Handle all other vfp data processing instructions.  */
+  else if (opc1 == 0x0b)
+    {
+      /* Handle VMOV.  */
+      if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
+        {
+          if (bit (arm_insn_r->arm_insn, 4))
+            {
+              if (bit (arm_insn_r->arm_insn, 6))
+                curr_insn_type = INSN_T0;
+              else
+                curr_insn_type = INSN_T1;
+            }
+          else
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+        }
+      /* Handle VNEG and VABS.  */
+      else if ((opc2 == 0x01 && opc3 == 0x01)
+              || (opc2 == 0x00 && opc3 == 0x03))
+        {
+          if (!bit (arm_insn_r->arm_insn, 11))
+            {
+              if (bit (arm_insn_r->arm_insn, 6))
+                curr_insn_type = INSN_T0;
+              else
+                curr_insn_type = INSN_T1;
+            }
+          else
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+        }
+      /* Handle VSQRT.  */
+      else if (opc2 == 0x01 && opc3 == 0x03)
+        {
+          if (dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+      /* Handle VCVT.  */
+      else if (opc2 == 0x07 && opc3 == 0x03)
+        {
+          if (!dp_op_sz)
+            curr_insn_type = INSN_T1;
+          else
+            curr_insn_type = INSN_T2;
+        }
+      else if (opc3 & 0x01)
+        {
+          /* Handle VCVT.  */
+          if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
+            {
+              if (!bit (arm_insn_r->arm_insn, 18))
+                curr_insn_type = INSN_T2;
+              else
+                {
+                  if (dp_op_sz)
+                    curr_insn_type = INSN_T1;
+                  else
+                    curr_insn_type = INSN_T2;
+                }
+            }
+          /* Handle VCVT.  */
+          else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
+            {
+              if (dp_op_sz)
+                curr_insn_type = INSN_T1;
+              else
+                curr_insn_type = INSN_T2;
+            }
+          /* Handle VCVTB, VCVTT.  */
+          else if ((opc2 & 0x0e) == 0x02)
+            curr_insn_type = INSN_T2;
+          /* Handle VCMP, VCMPE.  */
+          else if ((opc2 & 0x0e) == 0x04)
+            curr_insn_type = INSN_T3;
+        }
+    }
+
+  switch (curr_insn_type)
+    {
+      case INSN_T0:
+        reg_vd = reg_vd | (bit_d << 4);
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
+        arm_insn_r->reg_rec_count = 2;
+        break;
+
+      case INSN_T1:
+        reg_vd = reg_vd | (bit_d << 4);
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      case INSN_T2:
+        reg_vd = (reg_vd << 1) | bit_d;
+        record_buf[0] = reg_vd + ARM_D0_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      case INSN_T3:
+        record_buf[0] = ARM_FPSCR_REGNUM;
+        arm_insn_r->reg_rec_count = 1;
+        break;
+
+      default:
+        gdb_assert_not_reached ("no decoding pattern found");
+        break;
+    }
+
+  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
+  return 0;
+}
+
 /* Handling opcode 110 insns.  */
 
 static int
@@ -12119,7 +12330,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
     {
       /* VFP data-processing instructions.  */
       if (!op1_sbit && !op)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_vfp_data_proc_insn (arm_insn_r);
 
       /* Advanced SIMD, VFP instructions.  */
       if (!op1_sbit && op)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-27 10:17       ` Pedro Alves
@ 2014-08-28 12:56         ` Omair Javaid
  2014-09-02 14:59           ` Will Newton
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-08-28 12:56 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_asimd_vfp_coproc): Replace stub handler with
	arm_record_exreg_ld_st_insn.
	(arm_record_exreg_ld_st_insn): Add record handler for ex-register
	load/store insns.

---
 gdb/arm-tdep.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 176 insertions(+), 2 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 8d55105..df62069 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -12022,6 +12022,180 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for extension register load/store instructions.  */
+
+static int
+arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t opcode, single_reg;
+  uint8_t op_vldm_vstm;
+  uint32_t record_buf[8], record_buf_mem[128];
+  ULONGEST u_regval = 0;
+
+  struct regcache *reg_cache = arm_insn_r->regcache;
+  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
+
+  opcode = bits (arm_insn_r->arm_insn, 20, 24);
+  single_reg = bit (arm_insn_r->arm_insn, 8);
+  op_vldm_vstm = opcode & 0x1b;
+
+  /* Handle VMOV instructions.  */
+  if ((opcode & 0x1e) == 0x04)
+    {
+      if (bit (arm_insn_r->arm_insn, 4))
+        {
+          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
+          arm_insn_r->reg_rec_count = 2;
+        }
+      else
+        {
+          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
+                          | bit (arm_insn_r->arm_insn, 5);
+
+          if (!single_reg)
+            {
+              record_buf[0] = num_regs + reg_m;
+              record_buf[1] = num_regs + reg_m + 1;
+              arm_insn_r->reg_rec_count = 2;
+            }
+          else
+            {
+              record_buf[0] = reg_m + ARM_D0_REGNUM;
+              arm_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+  /* Handle VSTM and VPUSH instructions.  */
+  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
+          || op_vldm_vstm == 0x12)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        {
+          record_buf[0] = reg_rn;
+          arm_insn_r->reg_rec_count = 1;
+        }
+
+      while (memory_count)
+        {
+          if (!single_reg)
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              start_address = start_address + 4;
+              memory_index = memory_index + 2;
+            }
+          else
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              record_buf_mem[memory_index + 2] = start_address + 4;
+              record_buf_mem[memory_index + 3] = 4;
+              start_address = start_address + 8;
+              memory_index = memory_index + 4;
+            }
+          memory_count--;
+        }
+      arm_insn_r->mem_rec_count = (memory_index >> 1);
+    }
+  /* Handle VLDM instructions.  */
+  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
+          || op_vldm_vstm == 0x13)
+    {
+      uint32_t reg_count, reg_vd;
+      uint32_t reg_index = 0;
+
+      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
+
+      if (single_reg)
+        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
+      else
+        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
+
+      while (reg_count)
+        {
+          if (single_reg)
+              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
+          else
+              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
+
+          reg_count--;
+        }
+      arm_insn_r->reg_rec_count = reg_index;
+    }
+  /* VSTR Vector store register.  */
+  else if ((opcode & 0x13) == 0x10)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval + imm_off32;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (single_reg)
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+          arm_insn_r->mem_rec_count = 1;
+        }
+      else
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+          record_buf_mem[memory_index + 2] = start_address + 4;
+          record_buf_mem[memory_index + 3] = 4;
+          arm_insn_r->mem_rec_count = 2;
+        }
+    }
+  /* VLDR Vector load register.  */
+  else if ((opcode & 0x13) == 0x11)
+    {
+      uint32_t reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+
+      if (!single_reg)
+        {
+          reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
+          record_buf[0] = ARM_D0_REGNUM + reg_vd;
+        }
+      else
+        {
+          reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
+          record_buf[0] = num_regs + reg_vd;
+        }
+      arm_insn_r->reg_rec_count = 1;
+    }
+
+  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);
+  return 0;
+}
+
 /* Record handler for arm/thumb mode VFP data processing instructions.  */
 
 static int
@@ -12248,11 +12422,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
     {
       /* Handle extension register ld/st instructions.  */
       if (!(op1 & 0x20))
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
 
       /* 64-bit transfers between arm core and extension registers.  */
       if ((op1 & 0x3e) == 0x04)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
     }
   else
     {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 5/6] Implement support for recording vector data transfer instructions
  2014-08-27 10:19     ` Pedro Alves
@ 2014-08-28 13:07       ` Omair Javaid
  0 siblings, 0 replies; 37+ messages in thread
From: Omair Javaid @ 2014-08-28 13:07 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_vdata_transfer_insn): Add record handler for
	vector data transfer instructions.
	(arm_record_coproc_data_proc): Replace stub handler with
	arm_record_vdata_transfer_insn.

---
 gdb/arm-tdep.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index df62069..76e5f4d 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -12022,6 +12022,102 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for vector data transfer instructions.  */
+
+static int
+arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t bits_a, bit_c, bit_l, reg_t, reg_v;
+  uint32_t record_buf[4];
+
+  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
+  reg_t = bits (arm_insn_r->arm_insn, 12, 15);
+  reg_v = bits (arm_insn_r->arm_insn, 21, 23);
+  bits_a = bits (arm_insn_r->arm_insn, 21, 23);
+  bit_l = bit (arm_insn_r->arm_insn, 20);
+  bit_c = bit (arm_insn_r->arm_insn, 8);
+
+  /* Handle VMOV instruction.  */
+  if (bit_l && bit_c)
+    {
+      record_buf[0] = reg_t;
+      arm_insn_r->reg_rec_count = 1;
+    }
+  else if (bit_l && !bit_c)
+    {
+      /* 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));
+
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VMRS instruction.  */
+      else if (bits_a == 0x07)
+        {
+          if (reg_t == 15)
+            reg_t = ARM_PS_REGNUM;
+
+          record_buf[0] = reg_t;
+          arm_insn_r->reg_rec_count = 1;
+        }
+    }
+  else if (!bit_l && !bit_c)
+    {
+      /* 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));
+
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VMSR instruction.  */
+      else if (bits_a == 0x07)
+        {
+          record_buf[0] = ARM_FPSCR_REGNUM;
+          arm_insn_r->reg_rec_count = 1;
+        }
+    }
+  else if (!bit_l && bit_c)
+    {
+      /* Handle VMOV instruction.  */
+      if (!(bits_a & 0x04))
+        {
+          record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
+                          + ARM_D0_REGNUM;
+          arm_insn_r->reg_rec_count = 1;
+        }
+      /* Handle VDUP instruction.  */
+      else
+        {
+          if (bit (arm_insn_r->arm_insn, 21))
+            {
+              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+              record_buf[0] = reg_v + ARM_D0_REGNUM;
+              record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
+              arm_insn_r->reg_rec_count = 2;
+            }
+          else
+            {
+              reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
+              record_buf[0] = reg_v + ARM_D0_REGNUM;
+              arm_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+
+  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
+  return 0;
+}
+
 /* Record handler for extension register load/store instructions.  */
 
 static int
@@ -12508,7 +12604,7 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
 
       /* Advanced SIMD, VFP instructions.  */
       if (!op1_sbit && op)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_vdata_transfer_insn (arm_insn_r);
     }
   else
     {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH] Implement support for recording arm/thumb mode coprocessor instructions
  2014-08-28  9:50         ` [PATCH] Implement " Omair Javaid
@ 2014-09-02 14:51           ` Will Newton
  0 siblings, 0 replies; 37+ messages in thread
From: Will Newton @ 2014-09-02 14:51 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

On 28 August 2014 10:50, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_coproc_data_proc): Add record handler stubs
>         for asimd, vfp and coprocessor insns.
>         (arm_record_asimd_vfp_coproc): Add record handler for asimd, vfp
>         and coprocessor insns.
>         (thumb2_record_coproc_insn): New function.
>         (thumb2_record_decode_insn_handler): Update coprocessor insns record
>         handlers.
>         (decode_insn): Install arm_record_asimd_vfp_coproc as handler for
>         opcode 110 insns.
>
> ---
>  gdb/arm-tdep.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 110 insertions(+), 10 deletions(-)

This looks OK to me.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 9bc6507..d659897 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -12022,20 +12022,78 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Handling opcode 110 insns.  */
> +
> +static int
> +arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t op, op1, op1_sbit, op1_ebit, coproc;
> +
> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
> +  op1 = bits (arm_insn_r->arm_insn, 20, 25);
> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
> +
> +  if ((coproc & 0x0e) == 0x0a)
> +    {
> +      /* Handle extension register ld/st instructions.  */
> +      if (!(op1 & 0x20))
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* 64-bit transfers between arm core and extension registers.  */
> +      if ((op1 & 0x3e) == 0x04)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +    }
> +  else
> +    {
> +      /* Handle coprocessor ld/st instructions.  */
> +      if (!(op1 & 0x3a))
> +        {
> +          /* Store.  */
> +          if (!op1_ebit)
> +            return arm_record_unsupported_insn (arm_insn_r);
> +          else
> +            /* Load.  */
> +            return arm_record_unsupported_insn (arm_insn_r);
> +        }
> +
> +      /* Move to coprocessor from two arm core registers.  */
> +      if (op1 == 0x4)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to two arm core registers from coprocessor.  */
> +      if (op1 == 0x5)
> +        {
> +          uint32_t reg_t[2];
> +
> +          reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
> +          arm_insn_r->reg_rec_count = 2;
> +
> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
> +          return 0;
> +       }
> +    }
> +  return arm_record_unsupported_insn (arm_insn_r);
> +}
> +
>  /* Handling opcode 111 insns.  */
>
>  static int
>  arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>  {
> +  uint32_t op, op1_sbit, op1_ebit, coproc;
>    struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
>    struct regcache *reg_cache = arm_insn_r->regcache;
> -  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
>    ULONGEST u_regval = 0;
>
>    arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
> +  coproc = bits (arm_insn_r->arm_insn, 8, 11);
> +  op1_sbit = bit (arm_insn_r->arm_insn, 24);
> +  op1_ebit = bit (arm_insn_r->arm_insn, 20);
> +  op = bit (arm_insn_r->arm_insn, 4);
>
>    /* Handle arm SWI/SVC system call instructions.  */
> -  if (15 == arm_insn_r->opcode)
> +  if (op1_sbit)
>      {
>        if (tdep->arm_syscall_record != NULL)
>          {
> @@ -12048,21 +12106,52 @@ arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
>            else /* EABI.  */
>              regcache_raw_read_unsigned (reg_cache, 7, &svc_number);
>
> -          ret = tdep->arm_syscall_record (reg_cache, svc_number);
> +          return tdep->arm_syscall_record (reg_cache, svc_number);
>          }
>        else
>          {
>            printf_unfiltered (_("no syscall record support\n"));
> -          ret = -1;
> +          return -1;
>          }
>      }
> +
> +  if ((coproc & 0x0e) == 0x0a)
> +    {
> +      /* VFP data-processing instructions.  */
> +      if (!op1_sbit && !op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Advanced SIMD, VFP instructions.  */
> +      if (!op1_sbit && op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +    }
>    else
>      {
> -      arm_record_unsupported_insn (arm_insn_r);
> -      ret = -1;
> +      /* Coprocessor data operations.  */
> +      if (!op1_sbit && !op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to Coprocessor from ARM core register.  */
> +      if (!op1_sbit && !op1_ebit && op)
> +        return arm_record_unsupported_insn (arm_insn_r);
> +
> +      /* Move to arm core register from coprocessor.  */
> +      if (!op1_sbit && op1_ebit && op)
> +        {
> +          uint32_t record_buf[1];
> +
> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          if (record_buf[0] == 15)
> +            record_buf[0] = ARM_PS_REGNUM;
> +
> +          arm_insn_r->reg_rec_count = 1;
> +          REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
> +                     record_buf);
> +          return 0;
> +        }
>      }
>
> -  return ret;
> +  return arm_record_unsupported_insn (arm_insn_r);
>  }
>
>  /* Handling opcode 000 insns.  */
> @@ -12978,6 +13067,17 @@ thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
>    return ARM_RECORD_SUCCESS;
>  }
>
> +/* Record handler for thumb32 coprocessor instructions.  */
> +
> +static int
> +thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
> +{
> +  if (bit (thumb2_insn_r->arm_insn, 25))
> +    return arm_record_coproc_data_proc (thumb2_insn_r);
> +  else
> +    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
> +}
> +
>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>
>  static unsigned int
> @@ -13009,7 +13109,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (op2 & 0x40)
>          {
>            /* Co-processor instructions.  */
> -          arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>          }
>      }
>    else if (op1 == 0x02)
> @@ -13075,7 +13175,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (op2 & 0x40)
>          {
>            /* Co-processor instructions.  */
> -          return arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_coproc_insn (thumb2_insn_r);
>          }
>     }
>
> @@ -13119,7 +13219,7 @@ decode_insn (insn_decode_record *arm_record, record_type_t record_type,
>      arm_record_ld_st_reg_offset,        /* 011.  */
>      arm_record_ld_st_multiple,          /* 100.  */
>      arm_record_b_bl,                    /* 101.  */
> -    arm_record_unsupported_insn,        /* 110.  */
> +    arm_record_asimd_vfp_coproc,        /* 110.  */
>      arm_record_coproc_data_proc         /* 111.  */
>    };
>
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns
  2014-08-28 10:56         ` [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns Omair Javaid
@ 2014-09-02 14:55           ` Will Newton
  2014-09-10 11:16             ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-09-02 14:55 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

On 28 August 2014 11:56, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (thumb2_record_asimd_struct_ld_st): Add record handler
>         for advance SIMD struct ld/st insn.
>         (thumb2_record_decode_insn_handler): Replace stub handler with
>         thumb2_record_asimd_struct_ld_st.
>
> ---
>  gdb/arm-tdep.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 191 insertions(+), 1 deletion(-)

This version does not seem to address the issues raised in my previous
review e.g. bf_align variable.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index d659897..a4a7f15 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -13078,6 +13078,196 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
>      return arm_record_asimd_vfp_coproc (thumb2_insn_r);
>  }
>
> +/* Record handler for advance SIMD structure load/store instructions.  */
> +
> +static int
> +thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
> +{
> +  struct regcache *reg_cache = thumb2_insn_r->regcache;
> +  uint32_t l_bit, a_bit, b_bits;
> +  uint32_t record_buf[128], record_buf_mem[128];
> +  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
> +  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
> +  uint8_t bf_align, f_ebytes;
> +
> +  l_bit = bit (thumb2_insn_r->arm_insn, 21);
> +  a_bit = bit (thumb2_insn_r->arm_insn, 23);
> +  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
> +  bf_align = bits (thumb2_insn_r->arm_insn, 4, 5);
> +  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
> +  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
> +  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
> +  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
> +  f_esize = 8 * f_ebytes;
> +  f_elem = 8 / f_ebytes;
> +
> +  if (!l_bit)
> +    {
> +      ULONGEST u_regval = 0;
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      address = u_regval;
> +
> +      if (!a_bit)
> +        {
> +          /* Handle VST1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            {
> +              if (b_bits == 0x07)
> +                bf_regs = 1;
> +              else if (b_bits == 0x0a)
> +                bf_regs = 2;
> +              else if (b_bits == 0x06)
> +                bf_regs = 3;
> +              else if (b_bits == 0x02)
> +                bf_regs = 4;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                {
> +                  for (index_e = 0; index_e < f_elem; index_e++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address;
> +                      address = address + f_ebytes;
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                }
> +            }
> +          /* Handle VST2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            {
> +              if (b_bits == 0x09 || b_bits == 0x08)
> +                bf_regs = 1;
> +              else if (b_bits == 0x03)
> +                bf_regs = 2;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                for (index_e = 0; index_e < f_elem; index_e++)
> +                  {
> +                    for (loop_t = 0; loop_t < 2; loop_t++)
> +                      {
> +                        record_buf_mem[index_m++] = f_ebytes;
> +                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                        thumb2_insn_r->mem_rec_count += 1;
> +                      }
> +                    address = address + (2 * f_ebytes);
> +                  }
> +            }
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 3; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (3 * f_ebytes);
> +                }
> +            }
> +          /* Handle VST4.  */
> +          else if (!(b_bits & 0x0e))
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 4; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (4 * f_ebytes);
> +                }
> +            }
> +        }
> +      else
> +        {
> +          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
> +
> +          if (bft_size == 0x00)
> +            f_ebytes = 1;
> +          else if (bft_size == 0x01)
> +            f_ebytes = 2;
> +          else if (bft_size == 0x02)
> +            f_ebytes = 4;
> +          else
> +            f_ebytes = 0;
> +
> +          /* Handle VST1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08)
> +            thumb2_insn_r->mem_rec_count = 1;
> +          /* Handle VST2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
> +            thumb2_insn_r->mem_rec_count = 2;
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
> +            thumb2_insn_r->mem_rec_count = 3;
> +          /* Handle VST4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
> +            thumb2_insn_r->mem_rec_count = 4;
> +
> +          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
> +            {
> +              record_buf_mem[index_m] = f_ebytes;
> +              record_buf_mem[index_m] = address + (index_m * f_ebytes);
> +            }
> +        }
> +    }
> +  else
> +    {
> +      if (!a_bit)
> +        {
> +          /* Handle VLD1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if (!(b_bits & 0x0e))
> +            thumb2_insn_r->reg_rec_count = 4;
> +        }
> +      else
> +        {
> +          /* Handle VLD1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
> +            thumb2_insn_r->reg_rec_count = 4;
> +
> +          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
> +            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
> +        }
> +    }
> +
> +  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
> +    {
> +      record_buf[index_r] = reg_rn;
> +      thumb2_insn_r->reg_rec_count += 1;
> +    }
> +
> +  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
> +            record_buf);
> +  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
> +            record_buf_mem);
> +  return 0;
> +}
> +
>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>
>  static unsigned int
> @@ -13140,7 +13330,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (!((op2 & 0x71) ^ 0x10))
>          {
>            /* Advanced SIMD or structure load/store instructions.  */
> -          return arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
>          }
>        else if (!((op2 & 0x67) ^ 0x01))
>          {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-08-28 12:56         ` Omair Javaid
@ 2014-09-02 14:59           ` Will Newton
  2014-09-10 11:29             ` Omair Javaid
  0 siblings, 1 reply; 37+ messages in thread
From: Will Newton @ 2014-09-02 14:59 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

On 28 August 2014 13:55, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_asimd_vfp_coproc): Replace stub handler with
>         arm_record_exreg_ld_st_insn.
>         (arm_record_exreg_ld_st_insn): Add record handler for ex-register
>         load/store insns.
>
> ---
>  gdb/arm-tdep.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 176 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 8d55105..df62069 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -12022,6 +12022,180 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Record handler for extension register load/store instructions.  */
> +
> +static int
> +arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t opcode, single_reg;
> +  uint8_t op_vldm_vstm;
> +  uint32_t record_buf[8], record_buf_mem[128];
> +  ULONGEST u_regval = 0;
> +
> +  struct regcache *reg_cache = arm_insn_r->regcache;
> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
> +
> +  opcode = bits (arm_insn_r->arm_insn, 20, 24);
> +  single_reg = bit (arm_insn_r->arm_insn, 8);
> +  op_vldm_vstm = opcode & 0x1b;
> +
> +  /* Handle VMOV instructions.  */
> +  if ((opcode & 0x1e) == 0x04)
> +    {
> +      if (bit (arm_insn_r->arm_insn, 4))
> +        {
> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
> +          arm_insn_r->reg_rec_count = 2;
> +        }
> +      else
> +        {
> +          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
> +                          | bit (arm_insn_r->arm_insn, 5);
> +
> +          if (!single_reg)
> +            {
> +              record_buf[0] = num_regs + reg_m;
> +              record_buf[1] = num_regs + reg_m + 1;
> +              arm_insn_r->reg_rec_count = 2;
> +            }
> +          else
> +            {
> +              record_buf[0] = reg_m + ARM_D0_REGNUM;
> +              arm_insn_r->reg_rec_count = 1;
> +            }
> +        }
> +    }
> +  /* Handle VSTM and VPUSH instructions.  */
> +  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
> +          || op_vldm_vstm == 0x12)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        {
> +          record_buf[0] = reg_rn;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +
> +      while (memory_count)

This should be "memory_count > 0" as per Pedro's review.

> +        {
> +          if (!single_reg)
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              start_address = start_address + 4;
> +              memory_index = memory_index + 2;
> +            }
> +          else
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              record_buf_mem[memory_index + 2] = start_address + 4;
> +              record_buf_mem[memory_index + 3] = 4;
> +              start_address = start_address + 8;
> +              memory_index = memory_index + 4;
> +            }
> +          memory_count--;
> +        }
> +      arm_insn_r->mem_rec_count = (memory_index >> 1);
> +    }
> +  /* Handle VLDM instructions.  */
> +  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
> +          || op_vldm_vstm == 0x13)
> +    {
> +      uint32_t reg_count, reg_vd;
> +      uint32_t reg_index = 0;
> +
> +      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
> +
> +      if (single_reg)
> +        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
> +      else
> +        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
> +
> +      while (reg_count)

And this should be "reg_count > 0".

> +        {
> +          if (single_reg)
> +              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
> +          else
> +              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
> +
> +          reg_count--;
> +        }
> +      arm_insn_r->reg_rec_count = reg_index;
> +    }
> +  /* VSTR Vector store register.  */
> +  else if ((opcode & 0x13) == 0x10)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval + imm_off32;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (single_reg)
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +          arm_insn_r->mem_rec_count = 1;
> +        }
> +      else
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +          record_buf_mem[memory_index + 2] = start_address + 4;
> +          record_buf_mem[memory_index + 3] = 4;
> +          arm_insn_r->mem_rec_count = 2;
> +        }
> +    }
> +  /* VLDR Vector load register.  */
> +  else if ((opcode & 0x13) == 0x11)
> +    {
> +      uint32_t reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +
> +      if (!single_reg)
> +        {
> +          reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
> +          record_buf[0] = ARM_D0_REGNUM + reg_vd;
> +        }
> +      else
> +        {
> +          reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
> +          record_buf[0] = num_regs + reg_vd;
> +        }
> +      arm_insn_r->reg_rec_count = 1;
> +    }
> +
> +  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);
> +  return 0;
> +}
> +
>  /* Record handler for arm/thumb mode VFP data processing instructions.  */
>
>  static int
> @@ -12248,11 +12422,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>      {
>        /* Handle extension register ld/st instructions.  */
>        if (!(op1 & 0x20))
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>
>        /* 64-bit transfers between arm core and extension registers.  */
>        if ((op1 & 0x3e) == 0x04)
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>      }
>    else
>      {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns
  2014-09-02 14:55           ` Will Newton
@ 2014-09-10 11:16             ` Omair Javaid
  2014-09-10 11:54               ` Will Newton
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-09-10 11:16 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (thumb2_record_asimd_struct_ld_st): Add record handler
	for advance SIMD struct ld/st insn.
	(thumb2_record_decode_insn_handler): Replace stub handler with
	thumb2_record_asimd_struct_ld_st.
---
 gdb/arm-tdep.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 190 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 21c0242..27136e3 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -13072,6 +13072,195 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
     return arm_record_asimd_vfp_coproc (thumb2_insn_r);
 }
 
+/* Record handler for advance SIMD structure load/store instructions.  */
+
+static int
+thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
+{
+  struct regcache *reg_cache = thumb2_insn_r->regcache;
+  uint32_t l_bit, a_bit, b_bits;
+  uint32_t record_buf[128], record_buf_mem[128];
+  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
+  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
+  uint8_t f_ebytes;
+
+  l_bit = bit (thumb2_insn_r->arm_insn, 21);
+  a_bit = bit (thumb2_insn_r->arm_insn, 23);
+  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
+  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
+  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
+  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
+  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
+  f_esize = 8 * f_ebytes;
+  f_elem = 8 / f_ebytes;
+
+  if (!l_bit)
+    {
+      ULONGEST u_regval = 0;
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      address = u_regval;
+
+      if (!a_bit)
+        {
+          /* Handle VST1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            {
+              if (b_bits == 0x07)
+                bf_regs = 1;
+              else if (b_bits == 0x0a)
+                bf_regs = 2;
+              else if (b_bits == 0x06)
+                bf_regs = 3;
+              else if (b_bits == 0x02)
+                bf_regs = 4;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                {
+                  for (index_e = 0; index_e < f_elem; index_e++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address;
+                      address = address + f_ebytes;
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                }
+            }
+          /* Handle VST2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            {
+              if (b_bits == 0x09 || b_bits == 0x08)
+                bf_regs = 1;
+              else if (b_bits == 0x03)
+                bf_regs = 2;
+              else
+                bf_regs = 0;
+
+              for (index_r = 0; index_r < bf_regs; index_r++)
+                for (index_e = 0; index_e < f_elem; index_e++)
+                  {
+                    for (loop_t = 0; loop_t < 2; loop_t++)
+                      {
+                        record_buf_mem[index_m++] = f_ebytes;
+                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                        thumb2_insn_r->mem_rec_count += 1;
+                      }
+                    address = address + (2 * f_ebytes);
+                  }
+            }
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 3; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (3 * f_ebytes);
+                }
+            }
+          /* Handle VST4.  */
+          else if (!(b_bits & 0x0e))
+            {
+              for (index_e = 0; index_e < f_elem; index_e++)
+                {
+                  for (loop_t = 0; loop_t < 4; loop_t++)
+                    {
+                      record_buf_mem[index_m++] = f_ebytes;
+                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
+                      thumb2_insn_r->mem_rec_count += 1;
+                    }
+                  address = address + (4 * f_ebytes);
+                }
+            }
+        }
+      else
+        {
+          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
+
+          if (bft_size == 0x00)
+            f_ebytes = 1;
+          else if (bft_size == 0x01)
+            f_ebytes = 2;
+          else if (bft_size == 0x02)
+            f_ebytes = 4;
+          else
+            f_ebytes = 0;
+
+          /* Handle VST1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08)
+            thumb2_insn_r->mem_rec_count = 1;
+          /* Handle VST2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
+            thumb2_insn_r->mem_rec_count = 2;
+          /* Handle VST3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
+            thumb2_insn_r->mem_rec_count = 3;
+          /* Handle VST4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
+            thumb2_insn_r->mem_rec_count = 4;
+
+          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
+            {
+              record_buf_mem[index_m] = f_ebytes;
+              record_buf_mem[index_m] = address + (index_m * f_ebytes);
+            }
+        }
+    }
+  else
+    {
+      if (!a_bit)
+        {
+          /* Handle VLD1.  */
+          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0e) == 0x04)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if (!(b_bits & 0x0e))
+            thumb2_insn_r->reg_rec_count = 4;
+        }
+      else
+        {
+          /* Handle VLD1.  */
+          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
+            thumb2_insn_r->reg_rec_count = 1;
+          /* Handle VLD2.  */
+          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
+            thumb2_insn_r->reg_rec_count = 2;
+          /* Handle VLD3.  */
+          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
+            thumb2_insn_r->reg_rec_count = 3;
+          /* Handle VLD4.  */
+          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
+            thumb2_insn_r->reg_rec_count = 4;
+
+          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
+            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
+        }
+    }
+
+  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
+    {
+      record_buf[index_r] = reg_rn;
+      thumb2_insn_r->reg_rec_count += 1;
+    }
+
+  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
+            record_buf);
+  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
+            record_buf_mem);
+  return 0;
+}
+
 /* Decodes thumb2 instruction type and invokes its record handler.  */
 
 static unsigned int
@@ -13134,7 +13323,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
       else if (!((op2 & 0x71) ^ 0x10))
         {
           /* Advanced SIMD or structure load/store instructions.  */
-          return arm_record_unsupported_insn (thumb2_insn_r);
+          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
         }
       else if (!((op2 & 0x67) ^ 0x01))
         {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-09-02 14:59           ` Will Newton
@ 2014-09-10 11:29             ` Omair Javaid
  2014-09-10 11:55               ` Will Newton
  0 siblings, 1 reply; 37+ messages in thread
From: Omair Javaid @ 2014-09-10 11:29 UTC (permalink / raw)
  To: gdb-patches

gdb:

2014-08-13  Omair Javaid  <omair.javaid@linaro.org>

	* arm-tdep.c (arm_record_asimd_vfp_coproc): Replace stub handler with
	arm_record_exreg_ld_st_insn.
	(arm_record_exreg_ld_st_insn): Add record handler for ex-register
	load/store insns.
---
 gdb/arm-tdep.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 176 insertions(+), 2 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 21c1209..a0b4848 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -12016,6 +12016,180 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
   return -1;
 }
 
+/* Record handler for extension register load/store instructions.  */
+
+static int
+arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
+{
+  uint32_t opcode, single_reg;
+  uint8_t op_vldm_vstm;
+  uint32_t record_buf[8], record_buf_mem[128];
+  ULONGEST u_regval = 0;
+
+  struct regcache *reg_cache = arm_insn_r->regcache;
+  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
+
+  opcode = bits (arm_insn_r->arm_insn, 20, 24);
+  single_reg = bit (arm_insn_r->arm_insn, 8);
+  op_vldm_vstm = opcode & 0x1b;
+
+  /* Handle VMOV instructions.  */
+  if ((opcode & 0x1e) == 0x04)
+    {
+      if (bit (arm_insn_r->arm_insn, 4))
+        {
+          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
+          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
+          arm_insn_r->reg_rec_count = 2;
+        }
+      else
+        {
+          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
+                          | bit (arm_insn_r->arm_insn, 5);
+
+          if (!single_reg)
+            {
+              record_buf[0] = num_regs + reg_m;
+              record_buf[1] = num_regs + reg_m + 1;
+              arm_insn_r->reg_rec_count = 2;
+            }
+          else
+            {
+              record_buf[0] = reg_m + ARM_D0_REGNUM;
+              arm_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+  /* Handle VSTM and VPUSH instructions.  */
+  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
+          || op_vldm_vstm == 0x12)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        {
+          record_buf[0] = reg_rn;
+          arm_insn_r->reg_rec_count = 1;
+        }
+
+      while (memory_count > 0)
+        {
+          if (!single_reg)
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              start_address = start_address + 4;
+              memory_index = memory_index + 2;
+            }
+          else
+            {
+              record_buf_mem[memory_index] = start_address;
+              record_buf_mem[memory_index + 1] = 4;
+              record_buf_mem[memory_index + 2] = start_address + 4;
+              record_buf_mem[memory_index + 3] = 4;
+              start_address = start_address + 8;
+              memory_index = memory_index + 4;
+            }
+          memory_count--;
+        }
+      arm_insn_r->mem_rec_count = (memory_index >> 1);
+    }
+  /* Handle VLDM instructions.  */
+  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
+          || op_vldm_vstm == 0x13)
+    {
+      uint32_t reg_count, reg_vd;
+      uint32_t reg_index = 0;
+
+      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
+
+      if (single_reg)
+        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
+      else
+        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
+
+      if (bit (arm_insn_r->arm_insn, 21))
+        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
+
+      while (reg_count > 0)
+        {
+          if (single_reg)
+              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
+          else
+              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
+
+          reg_count--;
+        }
+      arm_insn_r->reg_rec_count = reg_index;
+    }
+  /* VSTR Vector store register.  */
+  else if ((opcode & 0x13) == 0x10)
+    {
+      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
+      uint32_t memory_index = 0;
+
+      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
+      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
+      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
+      imm_off32 = imm_off8 << 24;
+      memory_count = imm_off8;
+
+      if (bit (arm_insn_r->arm_insn, 23))
+        start_address = u_regval + imm_off32;
+      else
+        start_address = u_regval - imm_off32;
+
+      if (single_reg)
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+          arm_insn_r->mem_rec_count = 1;
+        }
+      else
+        {
+          record_buf_mem[memory_index] = start_address;
+          record_buf_mem[memory_index + 1] = 4;
+          record_buf_mem[memory_index + 2] = start_address + 4;
+          record_buf_mem[memory_index + 3] = 4;
+          arm_insn_r->mem_rec_count = 2;
+        }
+    }
+  /* VLDR Vector load register.  */
+  else if ((opcode & 0x13) == 0x11)
+    {
+      uint32_t reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
+
+      if (!single_reg)
+        {
+          reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
+          record_buf[0] = ARM_D0_REGNUM + reg_vd;
+        }
+      else
+        {
+          reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
+          record_buf[0] = num_regs + reg_vd;
+        }
+      arm_insn_r->reg_rec_count = 1;
+    }
+
+  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);
+  return 0;
+}
+
 /* Record handler for arm/thumb mode VFP data processing instructions.  */
 
 static int
@@ -12242,11 +12416,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
     {
       /* Handle extension register ld/st instructions.  */
       if (!(op1 & 0x20))
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
 
       /* 64-bit transfers between arm core and extension registers.  */
       if ((op1 & 0x3e) == 0x04)
-        return arm_record_unsupported_insn (arm_insn_r);
+        return arm_record_exreg_ld_st_insn (arm_insn_r);
     }
   else
     {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns
  2014-09-10 11:16             ` Omair Javaid
@ 2014-09-10 11:54               ` Will Newton
  0 siblings, 0 replies; 37+ messages in thread
From: Will Newton @ 2014-09-10 11:54 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

On 10 September 2014 12:15, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (thumb2_record_asimd_struct_ld_st): Add record handler
>         for advance SIMD struct ld/st insn.
>         (thumb2_record_decode_insn_handler): Replace stub handler with
>         thumb2_record_asimd_struct_ld_st.
> ---
>  gdb/arm-tdep.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 190 insertions(+), 1 deletion(-)

This looks ok to me.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 21c0242..27136e3 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -13072,6 +13072,195 @@ thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
>      return arm_record_asimd_vfp_coproc (thumb2_insn_r);
>  }
>
> +/* Record handler for advance SIMD structure load/store instructions.  */
> +
> +static int
> +thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
> +{
> +  struct regcache *reg_cache = thumb2_insn_r->regcache;
> +  uint32_t l_bit, a_bit, b_bits;
> +  uint32_t record_buf[128], record_buf_mem[128];
> +  uint32_t reg_rn, reg_vd, address, f_esize, f_elem;
> +  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
> +  uint8_t f_ebytes;
> +
> +  l_bit = bit (thumb2_insn_r->arm_insn, 21);
> +  a_bit = bit (thumb2_insn_r->arm_insn, 23);
> +  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
> +  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
> +  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
> +  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
> +  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
> +  f_esize = 8 * f_ebytes;
> +  f_elem = 8 / f_ebytes;
> +
> +  if (!l_bit)
> +    {
> +      ULONGEST u_regval = 0;
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      address = u_regval;
> +
> +      if (!a_bit)
> +        {
> +          /* Handle VST1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            {
> +              if (b_bits == 0x07)
> +                bf_regs = 1;
> +              else if (b_bits == 0x0a)
> +                bf_regs = 2;
> +              else if (b_bits == 0x06)
> +                bf_regs = 3;
> +              else if (b_bits == 0x02)
> +                bf_regs = 4;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                {
> +                  for (index_e = 0; index_e < f_elem; index_e++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address;
> +                      address = address + f_ebytes;
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                }
> +            }
> +          /* Handle VST2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            {
> +              if (b_bits == 0x09 || b_bits == 0x08)
> +                bf_regs = 1;
> +              else if (b_bits == 0x03)
> +                bf_regs = 2;
> +              else
> +                bf_regs = 0;
> +
> +              for (index_r = 0; index_r < bf_regs; index_r++)
> +                for (index_e = 0; index_e < f_elem; index_e++)
> +                  {
> +                    for (loop_t = 0; loop_t < 2; loop_t++)
> +                      {
> +                        record_buf_mem[index_m++] = f_ebytes;
> +                        record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                        thumb2_insn_r->mem_rec_count += 1;
> +                      }
> +                    address = address + (2 * f_ebytes);
> +                  }
> +            }
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 3; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (3 * f_ebytes);
> +                }
> +            }
> +          /* Handle VST4.  */
> +          else if (!(b_bits & 0x0e))
> +            {
> +              for (index_e = 0; index_e < f_elem; index_e++)
> +                {
> +                  for (loop_t = 0; loop_t < 4; loop_t++)
> +                    {
> +                      record_buf_mem[index_m++] = f_ebytes;
> +                      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
> +                      thumb2_insn_r->mem_rec_count += 1;
> +                    }
> +                  address = address + (4 * f_ebytes);
> +                }
> +            }
> +        }
> +      else
> +        {
> +          uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);
> +
> +          if (bft_size == 0x00)
> +            f_ebytes = 1;
> +          else if (bft_size == 0x01)
> +            f_ebytes = 2;
> +          else if (bft_size == 0x02)
> +            f_ebytes = 4;
> +          else
> +            f_ebytes = 0;
> +
> +          /* Handle VST1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08)
> +            thumb2_insn_r->mem_rec_count = 1;
> +          /* Handle VST2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
> +            thumb2_insn_r->mem_rec_count = 2;
> +          /* Handle VST3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
> +            thumb2_insn_r->mem_rec_count = 3;
> +          /* Handle VST4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
> +            thumb2_insn_r->mem_rec_count = 4;
> +
> +          for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
> +            {
> +              record_buf_mem[index_m] = f_ebytes;
> +              record_buf_mem[index_m] = address + (index_m * f_ebytes);
> +            }
> +        }
> +    }
> +  else
> +    {
> +      if (!a_bit)
> +        {
> +          /* Handle VLD1.  */
> +          if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0e) == 0x04)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if (!(b_bits & 0x0e))
> +            thumb2_insn_r->reg_rec_count = 4;
> +        }
> +      else
> +        {
> +          /* Handle VLD1.  */
> +          if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
> +            thumb2_insn_r->reg_rec_count = 1;
> +          /* Handle VLD2.  */
> +          else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
> +            thumb2_insn_r->reg_rec_count = 2;
> +          /* Handle VLD3.  */
> +          else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
> +            thumb2_insn_r->reg_rec_count = 3;
> +          /* Handle VLD4.  */
> +          else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
> +            thumb2_insn_r->reg_rec_count = 4;
> +
> +          for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
> +            record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
> +        }
> +    }
> +
> +  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
> +    {
> +      record_buf[index_r] = reg_rn;
> +      thumb2_insn_r->reg_rec_count += 1;
> +    }
> +
> +  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
> +            record_buf);
> +  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
> +            record_buf_mem);
> +  return 0;
> +}
> +
>  /* Decodes thumb2 instruction type and invokes its record handler.  */
>
>  static unsigned int
> @@ -13134,7 +13323,7 @@ thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
>        else if (!((op2 & 0x71) ^ 0x10))
>          {
>            /* Advanced SIMD or structure load/store instructions.  */
> -          return arm_record_unsupported_insn (thumb2_insn_r);
> +          return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
>          }
>        else if (!((op2 & 0x67) ^ 0x01))
>          {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH v3 4/6] Implement support for recording extension register ld/st insn
  2014-09-10 11:29             ` Omair Javaid
@ 2014-09-10 11:55               ` Will Newton
  0 siblings, 0 replies; 37+ messages in thread
From: Will Newton @ 2014-09-10 11:55 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

On 10 September 2014 12:29, Omair Javaid <omair.javaid@linaro.org> wrote:
> gdb:
>
> 2014-08-13  Omair Javaid  <omair.javaid@linaro.org>
>
>         * arm-tdep.c (arm_record_asimd_vfp_coproc): Replace stub handler with
>         arm_record_exreg_ld_st_insn.
>         (arm_record_exreg_ld_st_insn): Add record handler for ex-register
>         load/store insns.
> ---
>  gdb/arm-tdep.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 176 insertions(+), 2 deletions(-)

This looks ok to me.

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 21c1209..a0b4848 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -12016,6 +12016,180 @@ arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
>    return -1;
>  }
>
> +/* Record handler for extension register load/store instructions.  */
> +
> +static int
> +arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
> +{
> +  uint32_t opcode, single_reg;
> +  uint8_t op_vldm_vstm;
> +  uint32_t record_buf[8], record_buf_mem[128];
> +  ULONGEST u_regval = 0;
> +
> +  struct regcache *reg_cache = arm_insn_r->regcache;
> +  const int num_regs = gdbarch_num_regs (arm_insn_r->gdbarch);
> +
> +  opcode = bits (arm_insn_r->arm_insn, 20, 24);
> +  single_reg = bit (arm_insn_r->arm_insn, 8);
> +  op_vldm_vstm = opcode & 0x1b;
> +
> +  /* Handle VMOV instructions.  */
> +  if ((opcode & 0x1e) == 0x04)
> +    {
> +      if (bit (arm_insn_r->arm_insn, 4))
> +        {
> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
> +          record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
> +          arm_insn_r->reg_rec_count = 2;
> +        }
> +      else
> +        {
> +          uint8_t reg_m = (bits (arm_insn_r->arm_insn, 0, 3) << 1)
> +                          | bit (arm_insn_r->arm_insn, 5);
> +
> +          if (!single_reg)
> +            {
> +              record_buf[0] = num_regs + reg_m;
> +              record_buf[1] = num_regs + reg_m + 1;
> +              arm_insn_r->reg_rec_count = 2;
> +            }
> +          else
> +            {
> +              record_buf[0] = reg_m + ARM_D0_REGNUM;
> +              arm_insn_r->reg_rec_count = 1;
> +            }
> +        }
> +    }
> +  /* Handle VSTM and VPUSH instructions.  */
> +  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
> +          || op_vldm_vstm == 0x12)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        {
> +          record_buf[0] = reg_rn;
> +          arm_insn_r->reg_rec_count = 1;
> +        }
> +
> +      while (memory_count > 0)
> +        {
> +          if (!single_reg)
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              start_address = start_address + 4;
> +              memory_index = memory_index + 2;
> +            }
> +          else
> +            {
> +              record_buf_mem[memory_index] = start_address;
> +              record_buf_mem[memory_index + 1] = 4;
> +              record_buf_mem[memory_index + 2] = start_address + 4;
> +              record_buf_mem[memory_index + 3] = 4;
> +              start_address = start_address + 8;
> +              memory_index = memory_index + 4;
> +            }
> +          memory_count--;
> +        }
> +      arm_insn_r->mem_rec_count = (memory_index >> 1);
> +    }
> +  /* Handle VLDM instructions.  */
> +  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
> +          || op_vldm_vstm == 0x13)
> +    {
> +      uint32_t reg_count, reg_vd;
> +      uint32_t reg_index = 0;
> +
> +      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +      reg_count = bits (arm_insn_r->arm_insn, 0, 7);
> +
> +      if (single_reg)
> +        reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
> +      else
> +        reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
> +
> +      if (bit (arm_insn_r->arm_insn, 21))
> +        record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);
> +
> +      while (reg_count > 0)
> +        {
> +          if (single_reg)
> +              record_buf[reg_index++] = num_regs + reg_vd + reg_count - 1;
> +          else
> +              record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
> +
> +          reg_count--;
> +        }
> +      arm_insn_r->reg_rec_count = reg_index;
> +    }
> +  /* VSTR Vector store register.  */
> +  else if ((opcode & 0x13) == 0x10)
> +    {
> +      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
> +      uint32_t memory_index = 0;
> +
> +      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
> +      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
> +      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
> +      imm_off32 = imm_off8 << 24;
> +      memory_count = imm_off8;
> +
> +      if (bit (arm_insn_r->arm_insn, 23))
> +        start_address = u_regval + imm_off32;
> +      else
> +        start_address = u_regval - imm_off32;
> +
> +      if (single_reg)
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +          arm_insn_r->mem_rec_count = 1;
> +        }
> +      else
> +        {
> +          record_buf_mem[memory_index] = start_address;
> +          record_buf_mem[memory_index + 1] = 4;
> +          record_buf_mem[memory_index + 2] = start_address + 4;
> +          record_buf_mem[memory_index + 3] = 4;
> +          arm_insn_r->mem_rec_count = 2;
> +        }
> +    }
> +  /* VLDR Vector load register.  */
> +  else if ((opcode & 0x13) == 0x11)
> +    {
> +      uint32_t reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
> +
> +      if (!single_reg)
> +        {
> +          reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
> +          record_buf[0] = ARM_D0_REGNUM + reg_vd;
> +        }
> +      else
> +        {
> +          reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
> +          record_buf[0] = num_regs + reg_vd;
> +        }
> +      arm_insn_r->reg_rec_count = 1;
> +    }
> +
> +  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);
> +  return 0;
> +}
> +
>  /* Record handler for arm/thumb mode VFP data processing instructions.  */
>
>  static int
> @@ -12242,11 +12416,11 @@ arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
>      {
>        /* Handle extension register ld/st instructions.  */
>        if (!(op1 & 0x20))
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>
>        /* 64-bit transfers between arm core and extension registers.  */
>        if ((op1 & 0x3e) == 0x04)
> -        return arm_record_unsupported_insn (arm_insn_r);
> +        return arm_record_exreg_ld_st_insn (arm_insn_r);
>      }
>    else
>      {
> --
> 1.9.1
>



-- 
Will Newton
Toolchain Working Group, Linaro

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2014-09-10 11:55 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-13 13:13 [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid
2014-08-13 13:13 ` [PATCH v3 4/6] Implement support for recording extension register ld/st insn Omair Javaid
2014-08-13 14:10   ` Will Newton
2014-08-27  9:21     ` Omair Javaid
2014-08-27 10:17       ` Pedro Alves
2014-08-28 12:56         ` Omair Javaid
2014-09-02 14:59           ` Will Newton
2014-09-10 11:29             ` Omair Javaid
2014-09-10 11:55               ` Will Newton
2014-08-13 13:13 ` [PATCH v3 5/6] Implement support for recording vector data transfer instructions Omair Javaid
2014-08-13 14:10   ` Will Newton
2014-08-27  9:09     ` Omair Javaid
2014-08-27 10:19     ` Pedro Alves
2014-08-28 13:07       ` Omair Javaid
2014-08-13 13:13 ` [PATCH v3 1/6] Implements support for recording arm/thumb mode coprocessor instructions Omair Javaid
2014-08-13 14:10   ` Will Newton
2014-08-27  9:07     ` Omair Javaid
2014-08-27 10:05       ` Pedro Alves
2014-08-28  9:50         ` [PATCH] Implement " Omair Javaid
2014-09-02 14:51           ` Will Newton
2014-08-13 13:13 ` [PATCH v3 3/6] Implement support for recording VFP data processing instructions Omair Javaid
2014-08-13 14:10   ` Will Newton
2014-08-27  9:10     ` Omair Javaid
2014-08-27 10:11       ` Pedro Alves
2014-08-28 11:06         ` Omair Javaid
2014-08-13 13:13 ` [PATCH v3 6/6] Fix reverse-step and reverse-next over undebuggable solib code Omair Javaid
2014-08-27  9:09   ` Omair Javaid
2014-08-27 10:34   ` Pedro Alves
2014-08-13 13:13 ` [PATCH v3 2/6] Implements support for recording thumb2 ASIMD struct ld/st insn Omair Javaid
2014-08-13 14:10   ` Will Newton
2014-08-27  9:08     ` Omair Javaid
2014-08-27 10:09       ` Pedro Alves
2014-08-28 10:56         ` [PATCH v3 2/6] Implement support for recording thumb2 ASIMD struct ld/st insns Omair Javaid
2014-09-02 14:55           ` Will Newton
2014-09-10 11:16             ` Omair Javaid
2014-09-10 11:54               ` Will Newton
2014-08-27  9:05 ` [PATCH v3 0/6] ARM process record/replay improvements Omair Javaid

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).