public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/24] MIPS: Add support for reconfigurable FPR size, MIPS MSA and MIPSR6
@ 2016-06-29 12:46 Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 17/24] Add msa support etc to gdbserver Bhushan Attarde
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Bhushan Attarde @ 2016-06-29 12:46 UTC (permalink / raw)
  To: gdb-patches
  Cc: Maciej.Rozycki, Matthew.Fortune, James.Hogan, Andrew.Bennett,
	Jaydeep.Patil, Bhushan Attarde


Hi All,

This patch series (total 24 patches) has following changes:

    1. Handles run-time reconfigurable FPR size. MIPS revision 2 onwards MIPS32
    and MIPS64 both can have either 32-bit or 64-bit FPRs. This is decided
    based on the values of CP1.FIR.F64, CP0.SR.FR and CP0.Config5.FRE bits.
    Patch 1 to patch 12 in the series handles this property. This work is based
    on the patch submitted earlier by Maciej W. Rozycki. Please refer to
    https://sourceware.org/ml/gdb-patches/2012-06/msg00201.html for details. So
    this series includes his patch (updated to GDB 7.11 release version) as the
    [patch 1] of the series.
    
    2. Adds support to MIPS SIMD Architecture (MSA). The patch 13 to 20
    includes changes related to MSA.
    
    3. Adds MIPS revision 6 (MIPSR6) support in GDB. The patch 21 to 24
    includes changes related to MIPSR6 support in GDB.

*** BLURB HERE ***
Bhushan Attarde (24):
  MIPS: Handle run-time reconfigurable FPR size
  Add MIPS32 FPU64 GDB target descriptions
  regcache: handle invalidated regcache
  Add MIPS Config5 register related support
  MIPS: Add config5 to MIPS GDB target descriptions
  mips-linux-nat: pick fp64 target description when appropriate
  MIPS: Make Linux restart register more dynamic
  MIPS: Convert FP mode to enum and put fp registers into fp reggroup
  MIPS: Enhance cooked FP format
  MIPS: override fscr/fir types and print control registers specially
  MIPS: Add support for hybrid fp32/fp64 mode
  o32 sigframe unwinding with FR1
  Add MIPS MSA GDB target descriptions
  Implement core MSA stuff
  MIPS: Define msascr/msair types
  Pick msa target when appropriate and put msa registers into vector    
        reggroups.
  Add msa support etc to gdbserver
  mips-linux-nat: get msa registers
  Add MIPS MSA vector branch instruction support
  Drop FP and MSA control registers from default info registers
  MIPSR6 support for GDB
  Support all new ABIs when detecting if an FPU is present
  MIPS R6 opcode table shuffle for LDC2/SDC2
  MIPS R6 forbidden slot support

 gdb/features/Makefile                   |   11 +-
 gdb/features/mips-cp0.xml               |    1 +
 gdb/features/mips-dsp-linux.c           |   85 +-
 gdb/features/mips-dsp.xml               |   14 +-
 gdb/features/mips-fpu.xml               |    2 +-
 gdb/features/mips-fpu128.xml            |   47 +
 gdb/features/mips-fpu64-dsp-linux.c     |  111 ++
 gdb/features/mips-fpu64-dsp-linux.xml   |   20 +
 gdb/features/mips-fpu64-linux.c         |  102 ++
 gdb/features/mips-fpu64-linux.xml       |   19 +
 gdb/features/mips-fpu64.xml             |   45 +
 gdb/features/mips-linux.c               |   71 +-
 gdb/features/mips-msa-linux.c           |  110 ++
 gdb/features/mips-msa-linux.xml         |   26 +
 gdb/features/mips-msa.xml               |   12 +
 gdb/features/mips64-cp0.xml             |    1 +
 gdb/features/mips64-dsp-linux.c         |   85 +-
 gdb/features/mips64-dsp.xml             |   14 +-
 gdb/features/mips64-fpu.xml             |    2 +-
 gdb/features/mips64-fpu128.xml          |   47 +
 gdb/features/mips64-linux.c             |   71 +-
 gdb/features/mips64-msa-linux.c         |  108 ++
 gdb/features/mips64-msa-linux.xml       |   24 +
 gdb/features/mips64-msa.xml             |   12 +
 gdb/gdbarch.c                           |   32 +
 gdb/gdbarch.h                           |   11 +
 gdb/gdbarch.sh                          |    5 +
 gdb/gdbserver/Makefile.in               |   13 +-
 gdb/gdbserver/configure.srv             |   13 +
 gdb/gdbserver/linux-mips-low.c          |  205 ++-
 gdb/mips-linux-nat.c                    |  468 ++++++-
 gdb/mips-linux-tdep.c                   |  117 +-
 gdb/mips-linux-tdep.h                   |   10 -
 gdb/mips-tdep.c                         | 2197 +++++++++++++++++++++++++++----
 gdb/mips-tdep.h                         |   43 +
 gdb/regcache.c                          |   28 +-
 gdb/regformats/mips-dsp-linux.dat       |    1 +
 gdb/regformats/mips-fpu64-dsp-linux.dat |   85 ++
 gdb/regformats/mips-fpu64-linux.dat     |   78 ++
 gdb/regformats/mips-linux.dat           |    1 +
 gdb/regformats/mips-msa-linux.dat       |   80 ++
 gdb/regformats/mips64-dsp-linux.dat     |    1 +
 gdb/regformats/mips64-linux.dat         |    1 +
 gdb/regformats/mips64-msa-linux.dat     |   80 ++
 include/elf/common.h                    |    1 +
 include/opcode/mips.h                   |   13 +
 opcodes/micromips-opc.c                 |    3 +
 opcodes/mips-dis.c                      |   33 +-
 opcodes/mips-opc.c                      |   14 +-
 49 files changed, 4061 insertions(+), 512 deletions(-)
 create mode 100644 gdb/features/mips-fpu128.xml
 create mode 100644 gdb/features/mips-fpu64-dsp-linux.c
 create mode 100644 gdb/features/mips-fpu64-dsp-linux.xml
 create mode 100644 gdb/features/mips-fpu64-linux.c
 create mode 100644 gdb/features/mips-fpu64-linux.xml
 create mode 100644 gdb/features/mips-fpu64.xml
 create mode 100644 gdb/features/mips-msa-linux.c
 create mode 100644 gdb/features/mips-msa-linux.xml
 create mode 100644 gdb/features/mips-msa.xml
 create mode 100644 gdb/features/mips64-fpu128.xml
 create mode 100644 gdb/features/mips64-msa-linux.c
 create mode 100644 gdb/features/mips64-msa-linux.xml
 create mode 100644 gdb/features/mips64-msa.xml
 create mode 100644 gdb/regformats/mips-fpu64-dsp-linux.dat
 create mode 100644 gdb/regformats/mips-fpu64-linux.dat
 create mode 100644 gdb/regformats/mips-msa-linux.dat
 create mode 100644 gdb/regformats/mips64-msa-linux.dat

-- 
1.9-rc2

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

* [PATCH 15/24]     MIPS: Define msascr/msair types
  2016-06-29 12:46 [PATCH 00/24] MIPS: Add support for reconfigurable FPR size, MIPS MSA and MIPSR6 Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 17/24] Add msa support etc to gdbserver Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 16/24] Pick msa target when appropriate and put msa registers into vector reggroups Bhushan Attarde
@ 2016-06-29 12:46 ` Bhushan Attarde
  2 siblings, 0 replies; 4+ messages in thread
From: Bhushan Attarde @ 2016-06-29 12:46 UTC (permalink / raw)
  To: gdb-patches
  Cc: Maciej.Rozycki, Matthew.Fortune, James.Hogan, Andrew.Bennett,
	Jaydeep.Patil, Bhushan Attarde

    Define types for the MIPS SIMD Architecture (MSA) status and control
    register and implementation register, allowing the fields to be decoded.

    gdb/ChangeLog:

        * mips-tdep.c (mips_msair_type, mips_msacsr_type): New functions.
        (mips_fcsr_type): Return mips_msacsr_type and mips_msair_type
        for msascr and msair registers respecively.
        (mips_gdbarch_init): Initialize msa_csr_type and msa_ir_type
        fields.
        * mips-tdep.h (gdbarch_tdep): New msa_csr_type and msa_ir_type
        fields.
---
 gdb/mips-tdep.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/mips-tdep.h |   2 ++
 2 files changed, 112 insertions(+)

diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index f98c288..a11857a 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -1352,6 +1352,51 @@ mips_config5_type (struct gdbarch *gdbarch)
   return tdep->config5_type;
 }
 
+static struct type *
+mips_msair_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->msa_ir_type == NULL)
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      struct type *t, *flags;
+
+      /* top half has flags */
+      flags = arch_flags_type (gdbarch, "__gdb_builtin_type_msa_ir_flags", 2);
+      append_flags_type_flag (flags, 0, "WRP");
+
+      t = arch_composite_type (gdbarch, "__gdb_builtin_type_msa_ir",
+			       TYPE_CODE_STRUCT);
+
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+	{
+	  /* bottom half has revision & processor id */
+	  append_composite_type_field (t, "rev", bt->builtin_uint8);
+	  append_composite_type_field (t, "prid", bt->builtin_uint8);
+
+	  /* top half has flags */
+	  append_composite_type_field (t, "", flags);
+	}
+      else
+	{
+	  /* top half has flags */
+	  append_composite_type_field (t, "", flags);
+
+	  /* bottom half has revision & processor id */
+	  append_composite_type_field (t, "prid", bt->builtin_uint8);
+	  append_composite_type_field (t, "rev", bt->builtin_uint8);
+	}
+
+      TYPE_LENGTH (t) = 4;
+      TYPE_NAME (t) = "msa_ir";
+      tdep->msa_ir_type = t;
+    }
+
+  return tdep->msa_ir_type;
+}
+
+
 /* Get 32-bit only floating point type, which can be interpreted as either a
    single precision float or a 32-bit signed integer.
    This is used for odd fp registers when FR=0. In this case there are no odd
@@ -1607,6 +1652,59 @@ mips_fcflags_type (struct gdbarch *gdbarch)
 }
 
 static struct type *
+mips_msacsr_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->msa_csr_type == NULL)
+    {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+      struct type *t, *cflags, *flags;
+      struct field *f;
+
+      /* Flags, Enables, Cause have common set of condition flags */
+      cflags = mips_fcflags_type (gdbarch);
+
+      /* Various bits at top end */
+      flags = arch_flags_type (gdbarch, "__gdb_builtin_type_msa_csr_flags", 2);
+      append_flags_type_flag (flags, 0, "NX");
+      append_flags_type_flag (flags, 3, "IMPL0");
+      append_flags_type_flag (flags, 4, "IMPL1");
+      append_flags_type_flag (flags, 6, "FS");
+
+      t = arch_composite_type (gdbarch, "__gdb_builtin_type_msa_csr",
+			       TYPE_CODE_STRUCT);
+
+      /* Rounding mode */
+      f = append_composite_type_field_raw (t, "rm", mips_frm_type (gdbarch));
+      SET_FIELD_BITPOS (*f, 0);
+      FIELD_BITSIZE (*f) = 2;
+
+      f = append_composite_type_field_raw (t, "flags", cflags);
+      SET_FIELD_BITPOS (*f, 2);
+      FIELD_BITSIZE (*f) = 5;
+
+      f = append_composite_type_field_raw (t, "enables", cflags);
+      SET_FIELD_BITPOS (*f, 7);
+      FIELD_BITSIZE (*f) = 5;
+
+      f = append_composite_type_field_raw (t, "cause", cflags);
+      SET_FIELD_BITPOS (*f, 12);
+      FIELD_BITSIZE (*f) = 6;
+
+      f = append_composite_type_field_raw (t, "", flags);
+      SET_FIELD_BITPOS (*f, 18);
+      FIELD_BITSIZE (*f) = 14;
+
+      TYPE_LENGTH (t) = 4;
+      TYPE_NAME (t) = "msa_csr";
+      tdep->msa_csr_type = t;
+    }
+
+  return tdep->msa_csr_type;
+}
+
+static struct type *
 mips_fcsr_type (struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -1832,6 +1930,10 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
 	return mips_fir_type (gdbarch);
       else if (rawnum == mips_regnum (gdbarch)->config5)
 	return mips_config5_type (gdbarch);
+      else if (rawnum == mips_regnum (gdbarch)->msa_csr)
+	return mips_msacsr_type (gdbarch);
+      else if (rawnum == mips_regnum (gdbarch)->msa_ir)
+	return mips_msair_type (gdbarch);
       else if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
 	       && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
 	       && rawnum >= MIPS_FIRST_EMBED_REGNUM
@@ -1918,6 +2020,12 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   if (rawnum == mips_regnum (gdbarch)->config5)
     return mips_config5_type (gdbarch);
 
+  if (rawnum == mips_regnum (gdbarch)->msa_csr)
+    return mips_msacsr_type (gdbarch);
+
+  if (rawnum == mips_regnum (gdbarch)->msa_ir)
+    return mips_msair_type (gdbarch);
+
   if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
       && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
       && rawnum >= MIPS_EMBED_FP0_REGNUM + 32
@@ -9583,6 +9691,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->fp64_type = NULL;
   tdep->fp96_type = NULL;
   tdep->msa_128b_type = NULL;
+  tdep->msa_csr_type = NULL;
+  tdep->msa_ir_type = NULL;
 
   if (info.target_desc)
     {
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index b5f00fc..4e77cc2 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -143,6 +143,8 @@ struct gdbarch_tdep
   struct type *fp64_type;
   struct type *fp96_type;
   struct type *msa_128b_type;
+  struct type *msa_csr_type;
+  struct type *msa_ir_type;
 
   /* Return the expected next PC if FRAME is stopped at a syscall
      instruction.  */
-- 
1.9-rc2

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

* [PATCH 16/24]     Pick msa target when appropriate and put msa registers into vector     reggroups.
  2016-06-29 12:46 [PATCH 00/24] MIPS: Add support for reconfigurable FPR size, MIPS MSA and MIPSR6 Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 17/24] Add msa support etc to gdbserver Bhushan Attarde
@ 2016-06-29 12:46 ` Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 15/24] MIPS: Define msascr/msair types Bhushan Attarde
  2 siblings, 0 replies; 4+ messages in thread
From: Bhushan Attarde @ 2016-06-29 12:46 UTC (permalink / raw)
  To: gdb-patches
  Cc: Maciej.Rozycki, Matthew.Fortune, James.Hogan, Andrew.Bennett,
	Jaydeep.Patil, Bhushan Attarde

    gdb/ChangeLog:
        * mips-linux-nat.c: Include "features/mips-msa-linux.c" and
        "features/mips64-msa-linux.c".
        (mips_linux_read_description): New "have_msa" variable which is
        set using ptrace result and return appropriate target based on
        "have_msa".
        (initialize_tdesc_mips_msa_linux,
        initialize_tdesc_mips64_msa_linux): Initilizer functions for MSA
        targets.
        *mips-tdep.c (mips_register_reggroup_p): Put msa registers into
        vector reggroup.
---
 gdb/mips-linux-nat.c | 35 +++++++++++++++++++++++++++++++++--
 gdb/mips-tdep.c      |  4 +++-
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index fd1837f..20e3d17 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -42,8 +42,10 @@
 #include "features/mips-dsp-linux.c"
 #include "features/mips-fpu64-linux.c"
 #include "features/mips-fpu64-dsp-linux.c"
+#include "features/mips-msa-linux.c"
 #include "features/mips64-linux.c"
 #include "features/mips64-dsp-linux.c"
+#include "features/mips64-msa-linux.c"
 
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
@@ -611,6 +613,7 @@ mips_linux_read_description (struct target_ops *ops)
 
   static int have_dsp = -1;
   static int have_fpu64 = -1;
+  static int have_msa = -1;
 
   if (have_fpu64 < 0)
     {
@@ -631,12 +634,36 @@ mips_linux_read_description (struct target_ops *ops)
 	  break;
 	case EIO:
 	  have_fpu64 = 0;
+	  have_msa = 0;
 	  break;
 	default:
 	  perror_with_name ("ptrace");
 	  break;
 	}
     }
+
+  /* Check for MSA, which requires FR=1 */
+  if (have_msa < 0)
+    {
+      int tid;
+      int res;
+      uint32_t regs[32*4 + 8];
+      struct iovec iov;
+
+      tid = ptid_get_lwp (inferior_ptid);
+      if (tid == 0)
+	tid = ptid_get_pid (inferior_ptid);
+
+      /* this'd probably be better */
+      //have_msa = (getauxval(AT_HWCAP) & 0x2) != 0;
+
+      /* Test MSAIR */
+      iov.iov_base = regs;
+      iov.iov_len = sizeof(regs);
+      res = ptrace (PTRACE_GETREGSET, tid, NT_MIPS_MSA, &iov);
+      have_msa = (res >= 0) && regs[32*4 + 0];
+    }
+
   if (have_dsp < 0)
     {
       int tid;
@@ -664,9 +691,11 @@ mips_linux_read_description (struct target_ops *ops)
   /* Report that target registers are a size we know for sure
      that we can get from ptrace.  */
   if (_MIPS_SIM == _ABIO32)
-    return tdescs[have_dsp][have_fpu64];
+    return have_msa ? tdesc_mips_msa_linux
+		    : tdescs[have_dsp][have_fpu64];
   else
-    return have_dsp ? tdesc_mips64_dsp_linux : tdesc_mips64_linux;
+    return have_msa ? tdesc_mips64_msa_linux :
+	   have_dsp ? tdesc_mips64_dsp_linux : tdesc_mips64_linux;
 }
 
 /* -1 if the kernel and/or CPU do not support watch registers.
@@ -1023,6 +1052,8 @@ triggers a breakpoint or watchpoint."),
   initialize_tdesc_mips_dsp_linux ();
   initialize_tdesc_mips_fpu64_linux ();
   initialize_tdesc_mips_fpu64_dsp_linux ();
+  initialize_tdesc_mips_msa_linux ();
   initialize_tdesc_mips64_linux ();
   initialize_tdesc_mips64_dsp_linux ();
+  initialize_tdesc_mips64_msa_linux ();
 }
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index a11857a..63291db 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -776,7 +776,9 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   int pseudo = regnum / gdbarch_num_regs (gdbarch);
   if (reggroup == all_reggroup)
     return pseudo;
-  vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
+  vector_p = (TYPE_VECTOR (register_type (gdbarch, regnum)) ||
+	      rawnum == mips_regnum (gdbarch)->msa_csr ||
+	      rawnum == mips_regnum (gdbarch)->msa_ir);
   float_p = (mips_float_register_p (gdbarch, rawnum) ||
 	     rawnum == mips_regnum (gdbarch)->fp_control_status ||
 	     rawnum == mips_regnum (gdbarch)->fp_implementation_revision);
-- 
1.9-rc2

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

* [PATCH 17/24]     Add msa support etc to gdbserver
  2016-06-29 12:46 [PATCH 00/24] MIPS: Add support for reconfigurable FPR size, MIPS MSA and MIPSR6 Bhushan Attarde
@ 2016-06-29 12:46 ` Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 16/24] Pick msa target when appropriate and put msa registers into vector reggroups Bhushan Attarde
  2016-06-29 12:46 ` [PATCH 15/24] MIPS: Define msascr/msair types Bhushan Attarde
  2 siblings, 0 replies; 4+ messages in thread
From: Bhushan Attarde @ 2016-06-29 12:46 UTC (permalink / raw)
  To: gdb-patches
  Cc: Maciej.Rozycki, Matthew.Fortune, James.Hogan, Andrew.Bennett,
	Jaydeep.Patil, Bhushan Attarde

    gdb/gdbserver/ChangeLog:
        * linux-mips-low.c: Include "elf/common.h" and "sys/uio.h".
        (init_registers_mips_fpu64_linux): New declaration.
        (init_registers_mips_fpu64_dsp_linux,
        init_registers_mips_msa_linux,
        init_registers_mips64_msa_linux): Likewise.
        (tdesc_mips_fpu64_linux): New variable.
        (tdesc_mips_fpu64_dsp_linux, tdesc_mips_msa_linux,
        tdesc_mips64_msa_linux): Likewise.
        (PTRACE_GETREGSET, PTRACE_SETREGSET): New fallback definitions.
        (have_fpu64, have_msa): New variables.
        (mips_read_description): Set have_fpu64, have_msa appropriately
        and return target decription based on that.
        (mips_fill_fpregset, mips_store_fpregset): New fp_use_64bit
        variable.
        (mips_fill_msa_regset): New function.
        (mips_store_msa_regset): Likewise.
        (mips_regsets): Add MSA registers.
        (initialize_low_arch): Add initilizer functions for fpu64
        and MSA.
---
 gdb/gdbserver/linux-mips-low.c | 199 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 191 insertions(+), 8 deletions(-)

diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index e9f0b06..f170144 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -18,8 +18,10 @@
 
 #include "server.h"
 #include "linux-low.h"
+#include "elf/common.h"
 
 #include "nat/gdb_ptrace.h"
+#include <sys/uio.h>
 #include <endian.h>
 
 #include "nat/mips-linux-watch.h"
@@ -33,6 +35,18 @@ extern const struct target_desc *tdesc_mips_linux;
 void init_registers_mips_dsp_linux (void);
 extern const struct target_desc *tdesc_mips_dsp_linux;
 
+/* Defined in auto-generated file mips-fpu64-linux.c.  */
+void init_registers_mips_fpu64_linux (void);
+extern const struct target_desc *tdesc_mips_fpu64_linux;
+
+/* Defined in auto-generated file mips-fpu64-dsp-linux.c.  */
+void init_registers_mips_fpu64_dsp_linux (void);
+extern const struct target_desc *tdesc_mips_fpu64_dsp_linux;
+
+/* Defined in auto-generated file mips-msa-linux.c.  */
+void init_registers_mips_msa_linux (void);
+extern const struct target_desc *tdesc_mips_msa_linux;
+
 /* Defined in auto-generated file mips64-linux.c.  */
 void init_registers_mips64_linux (void);
 extern const struct target_desc *tdesc_mips64_linux;
@@ -41,15 +55,30 @@ extern const struct target_desc *tdesc_mips64_linux;
 void init_registers_mips64_dsp_linux (void);
 extern const struct target_desc *tdesc_mips64_dsp_linux;
 
+/* Defined in auto-generated file mips64-msa-linux.c.  */
+void init_registers_mips64_msa_linux (void);
+extern const struct target_desc *tdesc_mips64_msa_linux;
+
 #ifdef __mips64
 #define tdesc_mips_linux tdesc_mips64_linux
 #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux
+#define tdesc_mips_fpu64_linux tdesc_mips64_linux
+#define tdesc_mips_fpu64_dsp_linux tdesc_mips64_dsp_linux
+#define tdesc_mips_msa_linux tdesc_mips64_msa_linux
 #endif
 
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
 #endif
 
+#ifndef PTRACE_GETREGSET
+#define PTRACE_GETREGSET	0x4204
+#endif
+
+#ifndef PTRACE_SETREGSET
+#define PTRACE_SETREGSET	0x4205
+#endif
+
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
 #endif
@@ -64,6 +93,9 @@ extern const struct target_desc *tdesc_mips64_dsp_linux;
 #define DSP_CONTROL 77
 #endif
 
+#define ST0_FR	  (1 << 26)
+#define FIR_F64	  (1 << 22)
+
 union mips_register
 {
   unsigned char buf[8];
@@ -117,17 +149,68 @@ static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = {
 };
 
 static int have_dsp = -1;
+static int have_fpu64 = -1;
+static int have_msa = -1;
 
-/* Try peeking at an arbitrarily chosen DSP register and pick the available
-   user register set accordingly.  */
+/* Try peeking at registers and pick the available user register set
+   accordingly.  */
 
 static const struct target_desc *
 mips_read_description (void)
 {
+  const struct target_desc *tdescs[2][2] =
+    {
+	/* have_fpu64 = 0	have_fpu64 = 1 */
+	{ tdesc_mips_linux,	tdesc_mips_fpu64_linux },     /* have_dsp = 0 */
+	{ tdesc_mips_dsp_linux,	tdesc_mips_fpu64_dsp_linux }, /* have_dsp = 1 */
+    };
+
+  if (have_fpu64 < 0)
+    {
+      int pid = lwpid_of (current_thread);
+      long fir;
+
+      /* Try peeking at FIR.F64 bit */
+      errno = 0;
+      fir = ptrace (PTRACE_PEEKUSER, pid, FPC_EIR, 0);
+      switch (errno)
+	{
+	case 0:
+	  have_fpu64 = !!(fir & FIR_F64);
+	  break;
+	case EIO:
+	  have_fpu64 = 0;
+	  have_msa = 0;
+	  break;
+	default:
+	  perror_with_name ("ptrace");
+	  break;
+	}
+    }
+
+  /* Check for MSA, which requires FR=1 */
+  if (have_msa < 0)
+    {
+      int pid = lwpid_of (current_thread);
+      int res;
+      uint32_t regs[32*4 + 8];
+      struct iovec iov;
+
+      /* this'd probably be better */
+      //have_msa = (getauxval(AT_HWCAP) & 0x2) != 0;
+
+      /* Test MSAIR */
+      iov.iov_base = regs;
+      iov.iov_len = sizeof(regs);
+      res = ptrace (PTRACE_GETREGSET, pid, NT_MIPS_MSA, &iov);
+      have_msa = (res >= 0) && regs[32*4 + 0];
+    }
+
   if (have_dsp < 0)
     {
       int pid = lwpid_of (current_thread);
 
+      /* Try peeking at an arbitrarily chosen DSP register */
       errno = 0;
       ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
       switch (errno)
@@ -144,7 +227,8 @@ mips_read_description (void)
 	}
     }
 
-  return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
+  return have_msa ? tdesc_mips_msa_linux
+		  : tdescs[have_dsp][have_fpu64];
 }
 
 static void
@@ -770,22 +854,24 @@ static void
 mips_fill_fpregset (struct regcache *regcache, void *buf)
 {
   union mips_register *regset = (union mips_register *) buf;
-  int i, use_64bit, first_fp, big_endian;
+  int i, use_64bit, fp_use_64bit, first_fp, big_endian;
 
   use_64bit = (register_size (regcache->tdesc, 0) == 8);
   first_fp = find_regno (regcache->tdesc, "f0");
+  fp_use_64bit = (register_size (regcache->tdesc, first_fp) >= 8);
   big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
 
   /* See GDB for a discussion of this peculiar layout.  */
   for (i = 0; i < 32; i++)
-    if (use_64bit)
+    if (fp_use_64bit)
       collect_register (regcache, first_fp + i, regset[i].buf);
     else
       collect_register (regcache, first_fp + i,
 			regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
 
   mips_collect_register_32bit (regcache, use_64bit,
-			       find_regno (regcache->tdesc, "fcsr"), regset[32].buf);
+			       find_regno (regcache->tdesc, "fcsr"),
+			       regset[32].buf);
   mips_collect_register_32bit (regcache, use_64bit,
 			       find_regno (regcache->tdesc, "fir"),
 			       regset[32].buf + 4);
@@ -795,15 +881,16 @@ static void
 mips_store_fpregset (struct regcache *regcache, const void *buf)
 {
   const union mips_register *regset = (const union mips_register *) buf;
-  int i, use_64bit, first_fp, big_endian;
+  int i, use_64bit, fp_use_64bit, first_fp, big_endian;
 
   use_64bit = (register_size (regcache->tdesc, 0) == 8);
   first_fp = find_regno (regcache->tdesc, "f0");
+  fp_use_64bit = (register_size (regcache->tdesc, first_fp) >= 8);
   big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
 
   /* See GDB for a discussion of this peculiar layout.  */
   for (i = 0; i < 32; i++)
-    if (use_64bit)
+    if (fp_use_64bit)
       supply_register (regcache, first_fp + i, regset[i].buf);
     else
       supply_register (regcache, first_fp + i,
@@ -818,12 +905,104 @@ mips_store_fpregset (struct regcache *regcache, const void *buf)
 }
 #endif /* HAVE_PTRACE_GETREGS */
 
+static void
+mips_fill_msa_regset (struct regcache *regcache, void *buf)
+{
+  unsigned char *bufp = buf;
+  int i, first_fp, fir, fcsr, msair, msacsr, config5;
+  unsigned char tmp[16];
+
+  if (!have_msa)
+    return;
+
+  first_fp = find_regno (regcache->tdesc, "f0");
+  fir = find_regno (regcache->tdesc, "fir");
+  fcsr = find_regno (regcache->tdesc, "fcsr");
+  msair = find_regno (regcache->tdesc, "msair");
+  msacsr = find_regno (regcache->tdesc, "msacsr");
+  config5 = find_regno (regcache->tdesc, "config5");
+
+  /* full vector including float */
+  if (__BYTE_ORDER == __BIG_ENDIAN)
+    for (i = 0; i < 32; i++)
+      {
+	collect_register (regcache, first_fp + i, tmp);
+	/* swap 64-bit halves, so it's a single word */
+	memcpy(bufp, tmp + 8, 8);
+	memcpy(bufp + 8, tmp, 8);
+	bufp += 16;
+      }
+  else
+    for (i = 0; i < 32; i++)
+      {
+	collect_register (regcache, first_fp + i, bufp);
+	bufp += 16;
+      }
+
+  collect_register (regcache, fir, bufp);
+  bufp += 4;
+  collect_register (regcache, fcsr, bufp);
+  bufp += 4;
+  collect_register (regcache, msair, bufp);
+  bufp += 4;
+  collect_register (regcache, msacsr, bufp);
+  bufp += 4;
+  collect_register (regcache, config5, bufp);
+}
+
+static void
+mips_store_msa_regset (struct regcache *regcache, const void *buf)
+{
+  const unsigned char *bufp = buf;
+  int i, first_fp, fir, fcsr, msair, msacsr, config5;
+  unsigned char tmp[16];
+
+  if (!have_msa)
+    return;
+
+  first_fp = find_regno (regcache->tdesc, "f0");
+  fir = find_regno (regcache->tdesc, "fir");
+  fcsr = find_regno (regcache->tdesc, "fcsr");
+  msair = find_regno (regcache->tdesc, "msair");
+  msacsr = find_regno (regcache->tdesc, "msacsr");
+  config5 = find_regno (regcache->tdesc, "config5");
+
+  /* full vector including float */
+  if (__BYTE_ORDER == __BIG_ENDIAN)
+    for (i = 0; i < 32; i++)
+      {
+	/* swap 64-bit halves, as it's a single word */
+	memcpy(tmp, bufp + 8, 8);
+	memcpy(tmp + 8, bufp, 8);
+	supply_register (regcache, first_fp + i, tmp);
+	bufp += 16;
+      }
+  else
+    for (i = 0; i < 32; i++)
+      {
+	supply_register (regcache, first_fp + i, bufp);
+	bufp += 16;
+      }
+
+  supply_register (regcache, fir, bufp);
+  bufp += 4;
+  supply_register (regcache, fcsr, bufp);
+  bufp += 4;
+  supply_register (regcache, msair, bufp);
+  bufp += 4;
+  supply_register (regcache, msacsr, bufp);
+  bufp += 4;
+  supply_register (regcache, config5, bufp);
+}
+
 static struct regset_info mips_regsets[] = {
 #ifdef HAVE_PTRACE_GETREGS
   { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
     mips_fill_gregset, mips_store_gregset },
   { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
     mips_fill_fpregset, mips_store_fpregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_MIPS_MSA, 34*16, EXTENDED_REGS,
+    mips_fill_msa_regset, mips_store_msa_regset },
 #endif /* HAVE_PTRACE_GETREGS */
   NULL_REGSET
 };
@@ -903,8 +1082,12 @@ initialize_low_arch (void)
   /* Initialize the Linux target descriptions.  */
   init_registers_mips_linux ();
   init_registers_mips_dsp_linux ();
+  init_registers_mips_fpu64_linux ();
+  init_registers_mips_fpu64_dsp_linux ();
+  init_registers_mips_msa_linux ();
   init_registers_mips64_linux ();
   init_registers_mips64_dsp_linux ();
+  init_registers_mips64_msa_linux ();
 
   initialize_regsets_info (&mips_regsets_info);
 }
-- 
1.9-rc2

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

end of thread, other threads:[~2016-06-29 12:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-29 12:46 [PATCH 00/24] MIPS: Add support for reconfigurable FPR size, MIPS MSA and MIPSR6 Bhushan Attarde
2016-06-29 12:46 ` [PATCH 17/24] Add msa support etc to gdbserver Bhushan Attarde
2016-06-29 12:46 ` [PATCH 16/24] Pick msa target when appropriate and put msa registers into vector reggroups Bhushan Attarde
2016-06-29 12:46 ` [PATCH 15/24] MIPS: Define msascr/msair types Bhushan Attarde

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).