summaryrefslogtreecommitdiff
path: root/gdb/sparc64-tdep.c
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2017-05-19 03:06:19 -0700
committerJose E. Marchesi <jose.marchesi@oracle.com>2017-05-19 03:06:19 -0700
commit1933fd8ee01ad2e74a9c6341bc40f54962a8f889 (patch)
tree4fa1d4f8a0b9c540d3efcc87c6fe499534ecdde3 /gdb/sparc64-tdep.c
parenteb026f09eb6fcb96a5de1e655cdde041ba44affb (diff)
downloadbinutils-gdb-1933fd8ee01ad2e74a9c6341bc40f54962a8f889.tar.gz
gdb: fix TYPE_CODE_ARRAY handling in sparc targets
gdb has a special type (TYPE_CODE_ARRAY) to support the gcc extension (https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html). TYPE_CODE_ARRAY is handled incorrectly for both (32- and 64-bit) modes on Sparc machines. Tested on sparc64-linux-gnu and sparc-solaris (32- and 64-bit mode). 6 tests ( from gdb/testsuite/gdb.base/gnu_vector.exp) failed on sparc64-Linux and on sparc-Solaris in 32- and 64-bit mode. Now all these tests passed. gdb/testsuite/gdb.base/gnu_vector.exp has 117 different cases for small (and not small) arrays and structures. No regressions. gdb/ChangeLog: 2017-05-19 Vladimir Mezentsev <vladimir.mezentsev@oracle.com> * sparc-tdep.c (sparc_structure_return_p) (sparc_arg_on_registers_p): New functions. (sparc32_store_arguments): Use them. * sparc64-tdep.c (sparc64_16_byte_align_p) (sparc64_store_floating_fields, sparc64_extract_floating_fields): Handle TYPE_CODE_ARRAY.
Diffstat (limited to 'gdb/sparc64-tdep.c')
-rw-r--r--gdb/sparc64-tdep.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 58f5bf08e4e..9e0e6b532cb 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -669,6 +669,13 @@ static const struct frame_base sparc64_frame_base =
static int
sparc64_16_byte_align_p (struct type *type)
{
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ struct type *t = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (sparc64_floating_p (t))
+ return 1;
+ }
if (sparc64_floating_p (type) && TYPE_LENGTH (type) == 16)
return 1;
@@ -703,7 +710,23 @@ sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
gdb_assert (element < 16);
- if (sparc64_floating_p (type)
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ gdb_byte buf[8];
+ int regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32;
+
+ valbuf += bitpos / 8;
+ if (len < 8)
+ {
+ memset (buf, 0, 8 - len);
+ memcpy (buf + 8 - len, valbuf, len);
+ valbuf = buf;
+ len = 8;
+ }
+ for (int n = 0; n < (len + 3) / 4; n++)
+ regcache_cooked_write (regcache, regnum + n, valbuf + n * 4);
+ }
+ else if (sparc64_floating_p (type)
|| (sparc64_complex_floating_p (type) && len <= 16))
{
int regnum;
@@ -776,7 +799,23 @@ sparc64_extract_floating_fields (struct regcache *regcache, struct type *type,
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (sparc64_floating_p (type))
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ int len = TYPE_LENGTH (type);
+ int regnum = SPARC_F0_REGNUM + bitpos / 32;
+
+ valbuf += bitpos / 8;
+ if (len < 4)
+ {
+ gdb_byte buf[4];
+ regcache_cooked_read (regcache, regnum, buf);
+ memcpy (valbuf, buf + 4 - len, len);
+ }
+ else
+ for (int i = 0; i < (len + 3) / 4; i++)
+ regcache_cooked_read (regcache, regnum + i, valbuf + i * 4);
+ }
+ else if (sparc64_floating_p (type))
{
int len = TYPE_LENGTH (type);
int regnum;