From fe10a582b69fc09ce4775071aa619b0a6fc5dd1a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Sep 2011 17:59:42 +0000 Subject: [PATCH] Fix complex floats on sparc. * sparc-tdep.h (SPARC_F2_REGNUM, SPARC_F3_REGNUM, SPARC_F4_REGNUM, SPARC_F5_REGNUM, SPARC_F6_REGNUM, SPARC_F7_REGNUM): New enums. * sparc-tdep.c (sparc_complex_floating_p): New function. (sparc32_store_arguments): Handle complex floats. (sparc32_extract_return_value): Likewise. (sparc32_store_return_value): Likewise. (sparc32_stabs_argument_has_addr): Likewise. * sparc64-tdep.c (sparc64_complex_floating_p): New function. (sparc64_store_floating_fields): Handle complex floats. (sparc64_store_arguments): Likewise. (sparc64_store_return_value): Likewise. --- gdb/ChangeLog | 14 ++++++++++++ gdb/sparc-tdep.c | 55 +++++++++++++++++++++++++++++++++++++++++----- gdb/sparc-tdep.h | 6 +++++ gdb/sparc64-tdep.c | 32 ++++++++++++++++++++++----- 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index faf28a7a81f..cd3036201a9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2011-09-28 David S. Miller + + * sparc-tdep.h (SPARC_F2_REGNUM, SPARC_F3_REGNUM, SPARC_F4_REGNUM, + SPARC_F5_REGNUM, SPARC_F6_REGNUM, SPARC_F7_REGNUM): New enums. + * sparc-tdep.c (sparc_complex_floating_p): New function. + (sparc32_store_arguments): Handle complex floats. + (sparc32_extract_return_value): Likewise. + (sparc32_store_return_value): Likewise. + (sparc32_stabs_argument_has_addr): Likewise. + * sparc64-tdep.c (sparc64_complex_floating_p): New function. + (sparc64_store_floating_fields): Handle complex floats. + (sparc64_store_arguments): Likewise. + (sparc64_store_return_value): Likewise. + 2011-09-28 Eli Zaretskii * windows-nat.c (env_sort) [!__CYGWIN__]: Function restored from diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index faa7b3a4adc..c98de3a9433 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -221,6 +221,25 @@ sparc_floating_p (const struct type *type) return 0; } +/* Check whether TYPE is "Complex Floating". */ + +static int +sparc_complex_floating_p (const struct type *type) +{ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_COMPLEX: + { + int len = TYPE_LENGTH (type); + return (len == 8 || len == 16 || len == 32); + } + default: + break; + } + + return 0; +} + /* Check whether TYPE is "Structure or Union". In terms of Ada subprogram calls, arrays are treated the same as @@ -454,7 +473,8 @@ sparc32_store_arguments (struct regcache *regcache, int nargs, int len = TYPE_LENGTH (type); if (sparc_structure_or_union_p (type) - || (sparc_floating_p (type) && len == 16)) + || (sparc_floating_p (type) && len == 16) + || sparc_complex_floating_p (type)) { /* Structure, Union and Quad-Precision Arguments. */ sp -= len; @@ -1233,17 +1253,29 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache, gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - gdb_byte buf[8]; + gdb_byte buf[32]; gdb_assert (!sparc_structure_or_union_p (type)); gdb_assert (!(sparc_floating_p (type) && len == 16)); - if (sparc_floating_p (type)) + if (sparc_floating_p (type) || sparc_complex_floating_p (type)) { /* Floating return values. */ regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf); if (len > 4) regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4); + if (len > 8) + { + regcache_cooked_read (regcache, SPARC_F2_REGNUM, buf + 8); + regcache_cooked_read (regcache, SPARC_F3_REGNUM, buf + 12); + } + if (len > 16) + { + regcache_cooked_read (regcache, SPARC_F4_REGNUM, buf + 16); + regcache_cooked_read (regcache, SPARC_F5_REGNUM, buf + 20); + regcache_cooked_read (regcache, SPARC_F6_REGNUM, buf + 24); + regcache_cooked_read (regcache, SPARC_F7_REGNUM, buf + 28); + } memcpy (valbuf, buf, len); } else @@ -1281,13 +1313,25 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache, gdb_assert (!(sparc_floating_p (type) && len == 16)); gdb_assert (len <= 8); - if (sparc_floating_p (type)) + if (sparc_floating_p (type) || sparc_complex_floating_p (type)) { /* Floating return values. */ memcpy (buf, valbuf, len); regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf); if (len > 4) regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4); + if (len > 8) + { + regcache_cooked_write (regcache, SPARC_F2_REGNUM, buf + 8); + regcache_cooked_write (regcache, SPARC_F3_REGNUM, buf + 12); + } + if (len > 16) + { + regcache_cooked_write (regcache, SPARC_F4_REGNUM, buf + 16); + regcache_cooked_write (regcache, SPARC_F5_REGNUM, buf + 20); + regcache_cooked_write (regcache, SPARC_F6_REGNUM, buf + 24); + regcache_cooked_write (regcache, SPARC_F7_REGNUM, buf + 28); + } } else { @@ -1351,7 +1395,8 @@ static int sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) { return (sparc_structure_or_union_p (type) - || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)); + || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16) + || sparc_complex_floating_p (type)); } static int diff --git a/gdb/sparc-tdep.h b/gdb/sparc-tdep.h index d4e8b067c61..92b4705fad4 100644 --- a/gdb/sparc-tdep.h +++ b/gdb/sparc-tdep.h @@ -114,6 +114,12 @@ enum sparc_regnum SPARC_I7_REGNUM, /* %i7 */ SPARC_F0_REGNUM, /* %f0 */ SPARC_F1_REGNUM, + SPARC_F2_REGNUM, + SPARC_F3_REGNUM, + SPARC_F4_REGNUM, + SPARC_F5_REGNUM, + SPARC_F6_REGNUM, + SPARC_F7_REGNUM, SPARC_F31_REGNUM /* %f31 */ = SPARC_F0_REGNUM + 31 }; diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index 0430ecf22ac..31ee6130545 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -103,6 +103,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 @@ -622,11 +642,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) @@ -886,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) @@ -901,7 +923,7 @@ 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 @@ -1067,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); -- 2.30.2