* completer.c (location_completer): Fix typo in comment.
[deliverable/binutils-gdb.git] / gdb / sparc64-tdep.c
index 6efa2202a50fd836c50149d0bdf90a29f2be8432..f01848ea1eaff292fabf8550a88cd2720bf3c5e7 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for UltraSPARC.
 
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -103,6 +102,26 @@ sparc64_floating_p (const struct type *type)
   return 0;
 }
 
+/* Check whether TYPE is "Complex Floating".  */
+
+static int
+sparc64_complex_floating_p (const struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_COMPLEX:
+      {
+       int len = TYPE_LENGTH (type);
+       gdb_assert (len == 8 || len == 16 || len == 32);
+      }
+      return 1;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
 /* Check whether TYPE is "Structure or Union".
 
    In terms of Ada subprogram calls, arrays are treated the same as
@@ -520,7 +539,8 @@ sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     {
       CORE_ADDR pc = (regnum == SPARC64_NPC_REGNUM) ? 4 : 0;
 
-      regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
+      regnum =
+       (cache->copied_regs_mask & 0x80) ? SPARC_I7_REGNUM : SPARC_O7_REGNUM;
       pc += get_frame_register_unsigned (this_frame, regnum) + 8;
       return frame_unwind_got_constant (this_frame, regnum, pc);
     }
@@ -540,20 +560,20 @@ sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
       }
   }
 
-  /* The previous frame's `local' and `in' registers have been saved
+  /* The previous frame's `local' and `in' registers may have been saved
      in the register save area.  */
-  if (!cache->frameless_p
-      && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)
+  if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM
+      && (cache->saved_regs_mask & (1 << (regnum - SPARC_L0_REGNUM))))
     {
       CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 8;
 
       return frame_unwind_got_memory (this_frame, regnum, addr);
     }
 
-  /* The previous frame's `out' registers are accessable as the
-     current frame's `in' registers.  */
-  if (!cache->frameless_p
-      && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
+  /* The previous frame's `out' registers may be accessible as the current
+     frame's `in' registers.  */
+  if (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM
+      && (cache->copied_regs_mask & (1 << (regnum - SPARC_O0_REGNUM))))
     regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
 
   return frame_unwind_got_register (this_frame, regnum, regnum);
@@ -621,11 +641,13 @@ static void
 sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
                               const gdb_byte *valbuf, int element, int bitpos)
 {
+  int len = TYPE_LENGTH (type);
+
   gdb_assert (element < 16);
 
-  if (sparc64_floating_p (type))
+  if (sparc64_floating_p (type)
+      || (sparc64_complex_floating_p (type) && len <= 16))
     {
-      int len = TYPE_LENGTH (type);
       int regnum;
 
       if (len == 16)
@@ -763,7 +785,8 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
       struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
 
-      if (sparc64_structure_or_union_p (type))
+      if (sparc64_structure_or_union_p (type)
+         || (sparc64_complex_floating_p (type) && len == 32))
        {
          /* Structure or Union arguments.  */
          if (len <= 16)
@@ -794,10 +817,9 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
              num_elements++;
            }
        }
-      else if (sparc64_floating_p (type))
+      else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
        {
          /* Floating arguments.  */
-
          if (len == 16)
            {
              /* The psABI says that "Each quad-precision parameter
@@ -865,7 +887,8 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
       int regnum = -1;
       gdb_byte buf[16];
 
-      if (sparc64_structure_or_union_p (type))
+      if (sparc64_structure_or_union_p (type)
+         || (sparc64_complex_floating_p (type) && len == 32))
        {
          /* Structure or Union arguments.  */
          gdb_assert (len <= 16);
@@ -885,7 +908,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
          if (element < 16)
            sparc64_store_floating_fields (regcache, type, valbuf, element, 0);
        }
-      else if (sparc64_floating_p (type))
+      else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
        {
          /* Floating arguments.  */
          if (len == 16)
@@ -900,12 +923,12 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
              if (element < 16)
                regnum = SPARC64_D0_REGNUM + element;
            }
-         else
+         else if (len == 4)
            {
              /* The psABI says "Each single-precision parameter value
                  will be assigned to one extended word in the
                  parameter array, and right-justified within that
-                 word; the left half (even floatregister) is
+                 word; the left half (even float register) is
                  undefined."  Even though the psABI says that "the
                  left half is undefined", set it to zero here.  */
              memset (buf, 0, 4);
@@ -938,7 +961,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
            }
          else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
            {
-             gdb_assert (element < 6);
+             gdb_assert (element < 5);
              regnum = SPARC_O0_REGNUM + element;
              regcache_cooked_write (regcache, regnum, valbuf);
              regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
@@ -1012,7 +1035,7 @@ sparc64_extract_return_value (struct type *type, struct regcache *regcache,
        sparc64_extract_floating_fields (regcache, type, buf, 0);
       memcpy (valbuf, buf, len);
     }
-  else if (sparc64_floating_p (type))
+  else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
     {
       /* Floating return values.  */
       for (i = 0; i < len / 4; i++)
@@ -1066,7 +1089,7 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
       if (TYPE_CODE (type) != TYPE_CODE_UNION)
        sparc64_store_floating_fields (regcache, type, buf, 0, 0);
     }
-  else if (sparc64_floating_p (type))
+  else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
     {
       /* Floating return values.  */
       memcpy (buf, valbuf, len);
@@ -1096,7 +1119,7 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
 }
 
 static enum return_value_convention
-sparc64_return_value (struct gdbarch *gdbarch, struct type *func_type,
+sparc64_return_value (struct gdbarch *gdbarch, struct value *function,
                      struct type *type, struct regcache *regcache,
                      gdb_byte *readbuf, const gdb_byte *writebuf)
 {
@@ -1425,7 +1448,8 @@ sparc64_collect_gregset (const struct sparc_gregset *gregset,
 }
 
 void
-sparc64_supply_fpregset (struct regcache *regcache,
+sparc64_supply_fpregset (const struct sparc_fpregset *fpregset,
+                        struct regcache *regcache,
                         int regnum, const void *fpregs)
 {
   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
@@ -1435,14 +1459,15 @@ sparc64_supply_fpregset (struct regcache *regcache,
   for (i = 0; i < 32; i++)
     {
       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
-       regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
+       regcache_raw_supply (regcache, SPARC_F0_REGNUM + i,
+                            regs + fpregset->r_f0_offset + (i * 4));
     }
 
   if (sparc32)
     {
       if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
        regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
-                            regs + (32 * 4) + (16 * 8) + 4);
+                            regs + fpregset->r_fsr_offset);
     }
   else
     {
@@ -1450,17 +1475,19 @@ sparc64_supply_fpregset (struct regcache *regcache,
        {
          if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
            regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i,
-                                regs + (32 * 4) + (i * 8));
+                                (regs + fpregset->r_f0_offset
+                                 + (32 * 4) + (i * 8)));
        }
 
       if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
        regcache_raw_supply (regcache, SPARC64_FSR_REGNUM,
-                            regs + (32 * 4) + (16 * 8));
+                            regs + fpregset->r_fsr_offset);
     }
 }
 
 void
-sparc64_collect_fpregset (const struct regcache *regcache,
+sparc64_collect_fpregset (const struct sparc_fpregset *fpregset,
+                         const struct regcache *regcache,
                          int regnum, void *fpregs)
 {
   int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
@@ -1470,14 +1497,15 @@ sparc64_collect_fpregset (const struct regcache *regcache,
   for (i = 0; i < 32; i++)
     {
       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
-       regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
+       regcache_raw_collect (regcache, SPARC_F0_REGNUM + i,
+                             regs + fpregset->r_f0_offset + (i * 4));
     }
 
   if (sparc32)
     {
       if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
        regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
-                             regs + (32 * 4) + (16 * 8) + 4);
+                             regs + fpregset->r_fsr_offset);
     }
   else
     {
@@ -1485,12 +1513,18 @@ sparc64_collect_fpregset (const struct regcache *regcache,
        {
          if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
            regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i,
-                                 regs + (32 * 4) + (i * 8));
+                                 (regs + fpregset->r_f0_offset
+                                  + (32 * 4) + (i * 8)));
        }
 
       if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
        regcache_raw_collect (regcache, SPARC64_FSR_REGNUM,
-                             regs + (32 * 4) + (16 * 8));
+                             regs + fpregset->r_fsr_offset);
     }
 }
 
+const struct sparc_fpregset sparc64_bsd_fpregset =
+{
+  0 * 8,                       /* %f0 */
+  32 * 8,                      /* %fsr */
+};
This page took 0.029365 seconds and 4 git commands to generate.