Add usage to printf command
[deliverable/binutils-gdb.git] / gdb / ppc-sysv-tdep.c
index 9cc9a43903f58d4d01dce2d5fb9063bbb04884a8..a6ba5d0ffd6d483eb71fa5614d32fa94ab766777 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for PowerPC systems using the SVR4 ABI
    for GDB, the GNU debugger.
 
-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "inferior.h"
 #include "regcache.h"
 #include "value.h"
-#include <string.h>
-#include "gdb_assert.h"
 #include "ppc-tdep.h"
 #include "target.h"
 #include "objfiles.h"
 #include "infcall.h"
 #include "dwarf2.h"
+#include "target-float.h"
+#include <algorithm>
 
 
 /* Check whether FTPYE is a (pointer to) function type that should use
@@ -135,10 +135,10 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                    {
                      /* Always store the floating point value using
                         the register's floating-point format.  */
-                     gdb_byte regval[MAX_REGISTER_SIZE];
+                     gdb_byte regval[PPC_MAX_REGISTER_SIZE];
                      struct type *regtype
                        = register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
-                     convert_typed_floating (val, type, regval, regtype);
+                     target_float_convert (val, type, regval, regtype);
                      regcache_cooked_write (regcache,
                                              tdep->ppc_fp0_regnum + freg,
                                             regval);
@@ -279,7 +279,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                {
                  if (write_pass)
                    {
-                     gdb_byte regval[MAX_REGISTER_SIZE];
+                     gdb_byte regval[PPC_MAX_REGISTER_SIZE];
                      const gdb_byte *p;
 
                      /* 32-bit decimal floats are right aligned in the
@@ -365,11 +365,11 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                          if (write_pass)
                            {
                              int regnum = tdep->ppc_fp0_regnum + freg;
-                             gdb_byte regval[MAX_REGISTER_SIZE];
+                             gdb_byte regval[PPC_MAX_REGISTER_SIZE];
                              struct type *regtype
                                = register_type (gdbarch, regnum);
-                             convert_typed_floating (elval, eltype,
-                                                     regval, regtype);
+                             target_float_convert (elval, eltype,
+                                                   regval, regtype);
                              regcache_cooked_write (regcache, regnum, regval);
                            }
                          freg++;
@@ -412,7 +412,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                    }
                  else
                    {
-                     gdb_byte word[MAX_REGISTER_SIZE];
+                     gdb_byte word[PPC_MAX_REGISTER_SIZE];
                      store_unsigned_integer (word, tdep->wordsize, byte_order,
                                              unpack_long (eltype, elval));
 
@@ -517,8 +517,8 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
            {
              /* Reduce the parameter down to something that fits in a
                 "word".  */
-             gdb_byte word[MAX_REGISTER_SIZE];
-             memset (word, 0, MAX_REGISTER_SIZE);
+             gdb_byte word[PPC_MAX_REGISTER_SIZE];
+             memset (word, 0, PPC_MAX_REGISTER_SIZE);
              if (len > tdep->wordsize
                  || TYPE_CODE (type) == TYPE_CODE_STRUCT
                  || TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -610,7 +610,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 /* Handle the return-value conventions for Decimal Floating Point values.  */
-static int
+static enum return_value_convention
 get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
                                struct regcache *regcache, gdb_byte *readbuf,
                                const gdb_byte *writebuf)
@@ -624,7 +624,7 @@ get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
     {
       if (writebuf != NULL)
        {
-         gdb_byte regval[MAX_REGISTER_SIZE];
+         gdb_byte regval[PPC_MAX_REGISTER_SIZE];
          const gdb_byte *p;
 
          /* 32-bit decimal float is right aligned in the doubleword.  */
@@ -707,19 +707,19 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
        {
          /* Floats and doubles stored in "f1".  Convert the value to
             the required type.  */
-         gdb_byte regval[MAX_REGISTER_SIZE];
+         gdb_byte regval[PPC_MAX_REGISTER_SIZE];
          struct type *regtype = register_type (gdbarch,
                                                 tdep->ppc_fp0_regnum + 1);
          regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
-         convert_typed_floating (regval, regtype, readbuf, type);
+         target_float_convert (regval, regtype, readbuf, type);
        }
       if (writebuf)
        {
          /* Floats and doubles stored in "f1".  Convert the value to
             the register's "double" type.  */
-         gdb_byte regval[MAX_REGISTER_SIZE];
+         gdb_byte regval[PPC_MAX_REGISTER_SIZE];
          struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
-         convert_typed_floating (writebuf, type, regval, regtype);
+         target_float_convert (writebuf, type, regval, regtype);
          regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
@@ -807,7 +807,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
            || TYPE_CODE (type) == TYPE_CODE_CHAR
            || TYPE_CODE (type) == TYPE_CODE_BOOL
            || TYPE_CODE (type) == TYPE_CODE_PTR
-           || TYPE_CODE (type) == TYPE_CODE_REF
+           || TYPE_IS_REFERENCE (type)
            || TYPE_CODE (type) == TYPE_CODE_ENUM)
           && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -848,20 +848,20 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
          if (TYPE_CODE (eltype) == TYPE_CODE_FLT)
            {
              int regnum = tdep->ppc_fp0_regnum + 1 + i;
-             gdb_byte regval[MAX_REGISTER_SIZE];
+             gdb_byte regval[PPC_MAX_REGISTER_SIZE];
              struct type *regtype = register_type (gdbarch, regnum);
 
              if (writebuf != NULL)
                {
-                 convert_typed_floating (writebuf + offset, eltype,
-                                         regval, regtype);
+                 target_float_convert (writebuf + offset, eltype,
+                                       regval, regtype);
                  regcache_cooked_write (regcache, regnum, regval);
                }
              if (readbuf != NULL)
                {
                  regcache_cooked_read (regcache, regnum, regval);
-                 convert_typed_floating (regval, regtype,
-                                         readbuf + offset, eltype);
+                 target_float_convert (regval, regtype,
+                                       readbuf + offset, eltype);
                }
            }
          else
@@ -978,7 +978,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
       /* GCC screwed up for structures or unions whose size is less
         than or equal to 8 bytes..  Instead of left-aligning, it
         right-aligns the data into the buffer formed by r3, r4.  */
-      gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+      gdb_byte regvals[PPC_MAX_REGISTER_SIZE * 2];
       int len = TYPE_LENGTH (type);
       int offset = (2 * tdep->wordsize - len) % tdep->wordsize;
 
@@ -1011,7 +1011,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
          /* This matches SVr4 PPC, it does not match GCC.  */
          /* The value is right-padded to 8 bytes and then loaded, as
             two "words", into r3/r4.  */
-         gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+         gdb_byte regvals[PPC_MAX_REGISTER_SIZE * 2];
          regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
                                regvals + 0 * tdep->wordsize);
          if (TYPE_LENGTH (type) > tdep->wordsize)
@@ -1024,7 +1024,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
          /* This matches SVr4 PPC, it does not match GCC.  */
          /* The value is padded out to 8 bytes and then loaded, as
             two "words" into r3/r4.  */
-         gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+         gdb_byte regvals[PPC_MAX_REGISTER_SIZE * 2];
          memset (regvals, 0, sizeof regvals);
          memcpy (regvals, writebuf, TYPE_LENGTH (type));
          regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
@@ -1076,7 +1076,7 @@ convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr)
 {
   struct obj_section *dot_fn_section;
   struct bound_minimal_symbol dot_fn;
-  struct minimal_symbol *fn;
+  struct bound_minimal_symbol fn;
 
   /* Find the minimal symbol that corresponds to CODE_ADDR (should
      have a name of the form ".FN").  */
@@ -1094,10 +1094,10 @@ convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr)
      contain a minimal symbol with the same name.  */
   fn = lookup_minimal_symbol (MSYMBOL_LINKAGE_NAME (dot_fn.minsym) + 1, NULL,
                              dot_fn_section->objfile);
-  if (fn == NULL)
+  if (fn.minsym == NULL)
     return 0;
   /* Found a descriptor.  */
-  (*desc_addr) = MSYMBOL_VALUE_ADDRESS (fn);
+  (*desc_addr) = BMSYMBOL_VALUE_ADDRESS (fn);
   return 1;
 }
 
@@ -1191,7 +1191,7 @@ ppc64_aggregate_candidate (struct type *type,
              if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
                count += sub_count;
              else
-               count = max (count, sub_count);
+               count = std::max (count, sub_count);
            }
 
          /* There must be no padding.  */
@@ -1341,7 +1341,7 @@ ppc64_sysv_abi_push_integer (struct gdbarch *gdbarch, ULONGEST val,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[PPC_MAX_REGISTER_SIZE];
 
   if (argpos->regcache)
     store_unsigned_integer (buf, tdep->wordsize, byte_order, val);
@@ -1370,9 +1370,9 @@ ppc64_sysv_abi_push_freg (struct gdbarch *gdbarch,
        {
          int regnum = tdep->ppc_fp0_regnum + argpos->freg;
          struct type *regtype = register_type (gdbarch, regnum);
-         gdb_byte regval[MAX_REGISTER_SIZE];
+         gdb_byte regval[PPC_MAX_REGISTER_SIZE];
 
-         convert_typed_floating (val, type, regval, regtype);
+         target_float_convert (val, type, regval, regtype);
          regcache_cooked_write (argpos->regcache, regnum, regval);
        }
 
@@ -1495,7 +1495,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
            || TYPE_CODE (type) == TYPE_CODE_BOOL
            || TYPE_CODE (type) == TYPE_CODE_CHAR
            || TYPE_CODE (type) == TYPE_CODE_PTR
-           || TYPE_CODE (type) == TYPE_CODE_REF)
+           || TYPE_IS_REFERENCE (type))
           && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1815,17 +1815,17 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
     {
       int regnum = tdep->ppc_fp0_regnum + 1 + index;
       struct type *regtype = register_type (gdbarch, regnum);
-      gdb_byte regval[MAX_REGISTER_SIZE];
+      gdb_byte regval[PPC_MAX_REGISTER_SIZE];
 
       if (writebuf != NULL)
        {
-         convert_typed_floating (writebuf, valtype, regval, regtype);
+         target_float_convert (writebuf, valtype, regval, regtype);
          regcache_cooked_write (regcache, regnum, regval);
        }
       if (readbuf != NULL)
        {
          regcache_cooked_read (regcache, regnum, regval);
-         convert_typed_floating (regval, regtype, readbuf, valtype);
+         target_float_convert (regval, regtype, readbuf, valtype);
        }
       return 1;
     }
@@ -1894,7 +1894,8 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
     }
 
   /* AltiVec vectors are returned in VRs starting at v2.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype)
+  if (TYPE_LENGTH (valtype) == 16
+      && TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype)
       && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
     {
       int regnum = tdep->ppc_vr0_regnum + 2 + index;
@@ -1906,6 +1907,25 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
       return 1;
     }
 
+  /* Short vectors are returned in GPRs starting at r3.  */
+  if (TYPE_LENGTH (valtype) <= 8
+      && TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype))
+    {
+      int regnum = tdep->ppc_gp0_regnum + 3 + index;
+      int offset = 0;
+
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       offset = 8 - TYPE_LENGTH (valtype);
+
+      if (writebuf != NULL)
+       regcache_cooked_write_part (regcache, regnum,
+                                   offset, TYPE_LENGTH (valtype), writebuf);
+      if (readbuf != NULL)
+       regcache_cooked_read_part (regcache, regnum,
+                                  offset, TYPE_LENGTH (valtype), readbuf);
+      return 1;
+    }
+
   return 0;
 }
 
@@ -1981,8 +2001,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
@@ -1995,6 +2014,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
 
   /* Small character arrays are returned, right justified, in r3.  */
   if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+      && !TYPE_VECTOR (valtype)
       && TYPE_LENGTH (valtype) <= 8
       && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT
       && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
@@ -2014,7 +2034,13 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
   /* In the ELFv2 ABI, homogeneous floating-point or vector
      aggregates are returned in registers.  */
   if (tdep->elf_abi == POWERPC_ELF_V2
-      && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &eltype, &nelt))
+      && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &eltype, &nelt)
+      && (TYPE_CODE (eltype) == TYPE_CODE_FLT
+         || TYPE_CODE (eltype) == TYPE_CODE_DECFLOAT
+         || (TYPE_CODE (eltype) == TYPE_CODE_ARRAY
+             && TYPE_VECTOR (eltype)
+             && tdep->vector_abi == POWERPC_VEC_ALTIVEC
+             && TYPE_LENGTH (eltype) == 16)))
     {
       for (i = 0; i < nelt; i++)
        {
@@ -2046,7 +2072,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
 
       for (i = 0; i < n_regs; i++)
        {
-         gdb_byte regval[MAX_REGISTER_SIZE];
+         gdb_byte regval[PPC_MAX_REGISTER_SIZE];
          int regnum = tdep->ppc_gp0_regnum + 3 + i;
          int offset = i * tdep->wordsize;
          int len = TYPE_LENGTH (valtype) - offset;
This page took 0.028961 seconds and 4 git commands to generate.