Format gdb-gdb.py.in with autopep8
[external/binutils.git] / gdb / aarch64-tdep.c
index 0172e4c..5120fff 100644 (file)
@@ -69,6 +69,7 @@
 #define AARCH64_S0_REGNUM (AARCH64_D0_REGNUM + 32)
 #define AARCH64_H0_REGNUM (AARCH64_S0_REGNUM + 32)
 #define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
+#define AARCH64_SVE_V0_REGNUM (AARCH64_B0_REGNUM + 32)
 
 /* All possible aarch64 target descriptors.  */
 struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1];
@@ -1766,6 +1767,30 @@ aarch64_vnb_type (struct gdbarch *gdbarch)
   return tdep->vnb_type;
 }
 
+/* Return the type for an AdvSISD V register.  */
+
+static struct type *
+aarch64_vnv_type (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->vnv_type == NULL)
+    {
+      struct type *t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnv",
+                                           TYPE_CODE_UNION);
+
+      append_composite_type_field (t, "d", aarch64_vnd_type (gdbarch));
+      append_composite_type_field (t, "s", aarch64_vns_type (gdbarch));
+      append_composite_type_field (t, "h", aarch64_vnh_type (gdbarch));
+      append_composite_type_field (t, "b", aarch64_vnb_type (gdbarch));
+      append_composite_type_field (t, "q", aarch64_vnq_type (gdbarch));
+
+      tdep->vnv_type = t;
+    }
+
+  return tdep->vnv_type;
+}
+
 /* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */
 
 static int
@@ -1780,9 +1805,20 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31)
     return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0;
 
+  if (reg == AARCH64_DWARF_SVE_VG)
+    return AARCH64_SVE_VG_REGNUM;
+
+  if (reg == AARCH64_DWARF_SVE_FFR)
+    return AARCH64_SVE_FFR_REGNUM;
+
+  if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15)
+    return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0;
+
+  if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
+    return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
+
   return -1;
 }
-\f
 
 /* Implement the "print_insn" gdbarch method.  */
 
@@ -2114,6 +2150,8 @@ aarch64_gen_return_address (struct gdbarch *gdbarch,
 static const char *
 aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   static const char *const q_name[] =
     {
       "q0", "q1", "q2", "q3",
@@ -2191,6 +2229,25 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return b_name[regnum - AARCH64_B0_REGNUM];
 
+  if (tdep->has_sve ())
+    {
+      static const char *const sve_v_name[] =
+       {
+         "v0", "v1", "v2", "v3",
+         "v4", "v5", "v6", "v7",
+         "v8", "v9", "v10", "v11",
+         "v12", "v13", "v14", "v15",
+         "v16", "v17", "v18", "v19",
+         "v20", "v21", "v22", "v23",
+         "v24", "v25", "v26", "v27",
+         "v28", "v29", "v30", "v31",
+       };
+
+      if (regnum >= AARCH64_SVE_V0_REGNUM
+         && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+       return sve_v_name[regnum - AARCH64_SVE_V0_REGNUM];
+    }
+
   internal_error (__FILE__, __LINE__,
                  _("aarch64_pseudo_register_name: bad register number %d"),
                  regnum);
@@ -2201,6 +2258,8 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 static struct type *
 aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
@@ -2218,6 +2277,10 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return aarch64_vnb_type (gdbarch);
 
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+    return aarch64_vnv_type (gdbarch);
+
   internal_error (__FILE__, __LINE__,
                  _("aarch64_pseudo_register_type: bad register number %d"),
                  regnum);
@@ -2229,6 +2292,8 @@ static int
 aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                                    struct reggroup *group)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
@@ -2243,175 +2308,144 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
     return group == all_reggroup || group == vector_reggroup;
   else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
     return group == all_reggroup || group == vector_reggroup;
+  else if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+          && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+    return group == all_reggroup || group == vector_reggroup;
 
   return group == all_reggroup;
 }
 
+/* Helper for aarch64_pseudo_read_value.  */
+
+static struct value *
+aarch64_pseudo_read_value_1 (struct gdbarch *gdbarch,
+                            readable_regcache *regcache, int regnum_offset,
+                            int regsize, struct value *result_value)
+{
+  unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset;
+
+  /* Enough space for a full vector register.  */
+  gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)];
+  gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
+
+  if (regcache->raw_read (v_regnum, reg_buf) != REG_VALID)
+    mark_value_bytes_unavailable (result_value, 0,
+                                 TYPE_LENGTH (value_type (result_value)));
+  else
+    memcpy (value_contents_raw (result_value), reg_buf, regsize);
+
+  return result_value;
+ }
+
 /* Implement the "pseudo_register_read_value" gdbarch method.  */
 
 static struct value *
-aarch64_pseudo_read_value (struct gdbarch *gdbarch,
-                          readable_regcache *regcache,
+aarch64_pseudo_read_value (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int regnum)
 {
-  gdb_byte reg_buf[V_REGISTER_SIZE];
-  struct value *result_value;
-  gdb_byte *buf;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct value *result_value = allocate_value (register_type (gdbarch, regnum));
 
-  result_value = allocate_value (register_type (gdbarch, regnum));
   VALUE_LVAL (result_value) = lval_register;
   VALUE_REGNUM (result_value) = regnum;
-  buf = value_contents_raw (result_value);
 
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
-    {
-      enum register_status status;
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
-      status = regcache->raw_read (v_regnum, reg_buf);
-      if (status != REG_VALID)
-       mark_value_bytes_unavailable (result_value, 0,
-                                     TYPE_LENGTH (value_type (result_value)));
-      else
-       memcpy (buf, reg_buf, Q_REGISTER_SIZE);
-      return result_value;
-    }
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_Q0_REGNUM,
+                                       Q_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
-    {
-      enum register_status status;
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
-      status = regcache->raw_read (v_regnum, reg_buf);
-      if (status != REG_VALID)
-       mark_value_bytes_unavailable (result_value, 0,
-                                     TYPE_LENGTH (value_type (result_value)));
-      else
-       memcpy (buf, reg_buf, D_REGISTER_SIZE);
-      return result_value;
-    }
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_D0_REGNUM,
+                                       D_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
-    {
-      enum register_status status;
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
-      status = regcache->raw_read (v_regnum, reg_buf);
-      if (status != REG_VALID)
-       mark_value_bytes_unavailable (result_value, 0,
-                                     TYPE_LENGTH (value_type (result_value)));
-      else
-       memcpy (buf, reg_buf, S_REGISTER_SIZE);
-      return result_value;
-    }
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_S0_REGNUM,
+                                       S_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
-    {
-      enum register_status status;
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
-      status = regcache->raw_read (v_regnum, reg_buf);
-      if (status != REG_VALID)
-       mark_value_bytes_unavailable (result_value, 0,
-                                     TYPE_LENGTH (value_type (result_value)));
-      else
-       memcpy (buf, reg_buf, H_REGISTER_SIZE);
-      return result_value;
-    }
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_H0_REGNUM,
+                                       H_REGISTER_SIZE, result_value);
 
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
-    {
-      enum register_status status;
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
-      status = regcache->raw_read (v_regnum, reg_buf);
-      if (status != REG_VALID)
-       mark_value_bytes_unavailable (result_value, 0,
-                                     TYPE_LENGTH (value_type (result_value)));
-      else
-       memcpy (buf, reg_buf, B_REGISTER_SIZE);
-      return result_value;
-    }
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_B0_REGNUM,
+                                       B_REGISTER_SIZE, result_value);
+
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return aarch64_pseudo_read_value_1 (gdbarch, regcache,
+                                       regnum - AARCH64_SVE_V0_REGNUM,
+                                       V_REGISTER_SIZE, result_value);
 
   gdb_assert_not_reached ("regnum out of bound");
 }
 
-/* Implement the "pseudo_register_write" gdbarch method.  */
+/* Helper for aarch64_pseudo_write.  */
 
 static void
-aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                     int regnum, const gdb_byte *buf)
+aarch64_pseudo_write_1 (struct gdbarch *gdbarch, struct regcache *regcache,
+                       int regnum_offset, int regsize, const gdb_byte *buf)
 {
-  gdb_byte reg_buf[V_REGISTER_SIZE];
+  unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset;
+
+  /* Enough space for a full vector register.  */
+  gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)];
+  gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
 
   /* Ensure the register buffer is zero, we want gdb writes of the
      various 'scalar' pseudo registers to behavior like architectural
      writes, register width bytes are written the remainder are set to
      zero.  */
-  memset (reg_buf, 0, sizeof (reg_buf));
+  memset (reg_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM));
+
+  memcpy (reg_buf, buf, regsize);
+  regcache->raw_write (v_regnum, reg_buf);
+}
+
+/* Implement the "pseudo_register_write" gdbarch method.  */
 
+static void
+aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                     int regnum, const gdb_byte *buf)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   regnum -= gdbarch_num_regs (gdbarch);
 
   if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
-    {
-      /* pseudo Q registers */
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
-      memcpy (reg_buf, buf, Q_REGISTER_SIZE);
-      regcache->raw_write (v_regnum, reg_buf);
-      return;
-    }
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_Q0_REGNUM, Q_REGISTER_SIZE,
+                                  buf);
 
   if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
-    {
-      /* pseudo D registers */
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
-      memcpy (reg_buf, buf, D_REGISTER_SIZE);
-      regcache->raw_write (v_regnum, reg_buf);
-      return;
-    }
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_D0_REGNUM, D_REGISTER_SIZE,
+                                  buf);
 
   if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
-    {
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
-      memcpy (reg_buf, buf, S_REGISTER_SIZE);
-      regcache->raw_write (v_regnum, reg_buf);
-      return;
-    }
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_S0_REGNUM, S_REGISTER_SIZE,
+                                  buf);
 
   if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
-    {
-      /* pseudo H registers */
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
-      memcpy (reg_buf, buf, H_REGISTER_SIZE);
-      regcache->raw_write (v_regnum, reg_buf);
-      return;
-    }
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_H0_REGNUM, H_REGISTER_SIZE,
+                                  buf);
 
   if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
-    {
-      /* pseudo B registers */
-      unsigned v_regnum;
-
-      v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
-      memcpy (reg_buf, buf, B_REGISTER_SIZE);
-      regcache->raw_write (v_regnum, reg_buf);
-      return;
-    }
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_B0_REGNUM, B_REGISTER_SIZE,
+                                  buf);
+
+  if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
+      && regnum < AARCH64_SVE_V0_REGNUM + 32)
+    return aarch64_pseudo_write_1 (gdbarch, regcache,
+                                  regnum - AARCH64_SVE_V0_REGNUM,
+                                  V_REGISTER_SIZE, buf);
 
   gdb_assert_not_reached ("regnum out of bound");
 }